yt-project / yt

Main yt repository
http://yt-project.org
Other
463 stars 276 forks source link

LightRay masking out all zero-valued density fields in constructor #1262

Closed yt-fido closed 7 years ago

yt-fido commented 8 years ago

Originally reported by: chummels (Bitbucket: chummels, GitHub: chummels)


Recently, there was a problem with LightRay objects attempting to be created from zero density trajectories, which led to problems when attempting to use the AbsorptionSpectrum functionality because it expects non-zero density fields in order to work correctly (Issue #1232).

This issue was addressed by PR #2300, which searched for any fields present in the fields kwarg of the make_light_ray() function, identified which of these fields had units of 'K', 'g/cm**3', or 'cm**-3', and applied a mask so only non-zero values of those fields were included in the resulting LightRay.

The problem I've encountered is when you have several ion number density fields in a dataset and you want to include them in the LightRay object, you end up masking out all array elements that have zero values for any of the ion fields. So for example, if my simulation keeps track of Oxygen VI number density and H I number density (i.e. O_p5_number_density and H_p0_number_density), and my LightRay passes through a region with zero metallicity (and thus, zero Oxygen VI, but non-zero H I), all of the cells with zero oxygen VI will get masked out of the LightRay, even though they contain valid densities and H I densities. I've created an example script below:

#!python

import yt
from yt.analysis_modules.cosmological_observation.api import LightRay
ds = yt.load('IsolatedGalaxy/galaxy0030/galaxy0030')

# Add a field that is zero everywhere
def _zeros(field, data):
    return data["density"] * 0.0
ds.add_field("zeros", function=_zeros, units="g/cm**3")

# Create a LightRay object and include the zeros field
lr = LightRay(ds)
ray_start = [0,0,0]
ray_end = [1,1,1]
lr.make_light_ray(start_position=ray_start, end_position=ray_end,
             fields=['temperature', 'density', 'H_number_density', 'zeros'],
             data_filename='lightray.h5')

make_light_ray fails because it is trying to mask all cells that the ray hits that have zero values in any probed field. Here is the STDERR/STDOUT:

#!python

[cambot:~/scratch] chummels% python test_zero_dens.py
yt : [INFO     ] 2016-08-16 13:30:58,968 Parameters: current_time              = 0.00600002000283
yt : [INFO     ] 2016-08-16 13:30:58,969 Parameters: domain_dimensions         = [32 32 32]
yt : [INFO     ] 2016-08-16 13:30:58,969 Parameters: domain_left_edge          = [ 0.  0.  0.]
yt : [INFO     ] 2016-08-16 13:30:58,969 Parameters: domain_right_edge         = [ 1.  1.  1.]
yt : [INFO     ] 2016-08-16 13:30:58,970 Parameters: cosmological_simulation   = 0.0
Parsing Hierarchy : 100%|█████████████████████████████████████████████████████████| 173/173 [00:00<00:00, 35560.63it/s]
yt : [INFO     ] 2016-08-16 13:30:58,983 Gathering a field list (this may take a moment.)
yt : [INFO     ] 2016-08-16 13:31:00,080 Getting segment at z = 0.0: [ 0.  0.  0.] unitary to [ 0.  0.  1.] unitary.
/Users/chummels/src/yt/yt/units/yt_array.py:973: RuntimeWarning: invalid value encountered in divide
  return super(YTArray, self).__div__(ro)
yt : [INFO     ] 2016-08-16 13:31:00,082 Getting subsegment: [0.0, 0.0, 0.0] to [0.0, 0.0, 1.0].
Traceback (most recent call last):
  File "test_zero_dens.py", line 17, in <module>
    data_filename='lightray.h5')
  File "/Users/chummels/src/yt/yt/analysis_modules/cosmological_observation/light_ray/light_ray.py", line 575, in make_light_ray
    self._write_light_ray(data_filename, all_data)
  File "/Users/chummels/src/yt/yt/utilities/parallel_tools/parallel_analysis_interface.py", line 320, in root_only
    return func(*args, **kwargs)
  File "/Users/chummels/src/yt/yt/analysis_modules/cosmological_observation/light_ray/light_ray.py", line 617, in _write_light_ray
    "Please modify your light ray trajectory." % (f,))
RuntimeError: No zones along light ray with nonzero zeros. Please modify your light ray trajectory.

I'm not sure the ideal solution. One might be to require users to include the density field when they make a LightRay, and then just use that field for masking out the zero-value density cells. Alternatively, we could accept zero-valued cells and then make AbsorptionSpectrum smarter about what it tries to do with these data. Ideas?


yt-fido commented 8 years ago

Original comment by chummels (Bitbucket: chummels, GitHub: chummels):


Fixed by PR #2344.

yt-fido commented 8 years ago

Original comment by chummels (Bitbucket: chummels, GitHub: chummels):


Right now density is not a required field for generating the AbsorptionSpectrum object, which is why I was potentially proposing making it required. The example script in Issue 1232 actually didn't have 'density', which is why the change in your PR was required. I'm actually looking at just allowing all zero-value fields (including density) and no mask whatsoever in the LightRay construction, and then have the mask/zero-value check occur at the AbsorptionSpectrum level when the spectra are actually made. Unless people think that this is a bad idea.

yt-fido commented 8 years ago

Original comment by Nathan Goldbaum (Bitbucket: ngoldbaum, GitHub: ngoldbaum):


Maybe try checking only if density and temperature are zero, but not the ion species fields?