yt-project / yt

Main yt repository
http://yt-project.org
Other
469 stars 281 forks source link

No "code_length" when loading ART Datasets #5024

Open AsierLambarri opened 1 month ago

AsierLambarri commented 1 month ago

When loading ART Datasets it seems that no ´code_length´ attribute is loaded into the dataset. Instead, the attribute ´length_unit´ is loaded. This collides with some functionalities where the former is required to do unit conversion behind the curtains.

An Example: Im loading an snapshot from Agora-ART v18 dataset and plotting the dark matter alongside with the halos, using ´annotate_sphere´ with the keyword coord_system="data" to do so:

ds = yt.load(fn) 
ds.code_length = ds.length_unit
ad = ds.all_data()

max_dens, center = search_max_in_field(ds, 'stars', 'particle_mass')

print(f'The center will be located at {center.in_units("Mpc")} with density {max_dens}')

# DM
p = yt.ParticleProjectionPlot(ds,'z',('darkmatter','particle_mass'), center=center, width=width, density=True)
p.set_unit(("darkmatter", "particle_mass"), "Msun/kpc**2")
p.set_font(
     {  
        "size": 20,
    }

)
p.set_axes_unit('kpccm')
p.annotate_timestamp(redshift=True, text_args={"color":"black"})
p.set_xlabel('x [comoving kpc]')
p.set_ylabel('')

for i in tqdm(range(0, len(filtered_halos))):
    sub_tree_id = filtered_halos['Sub_tree_id'].iloc[i]
    position_x = filtered_halos['position_x'].iloc[i]
    position_y = filtered_halos['position_y'].iloc[i]
    position_z = filtered_halos['position_z'].iloc[i]
    virial_radius = filtered_halos['virial_radius'].iloc[i]

    if sub_tree_id == 1:
        p.annotate_sphere(unyt_array([position_x, position_y, position_z], 'kpccm'), radius=(1*virial_radius, 'kpccm'),coord_system='data',
                    circle_args={"color": "green", "linestyle": "dashed", "linewidth": 2})
    else:    
        p.annotate_sphere(unyt_array([position_x,position_y,position_z], 'kpccm'),
                        radius=(0.5*virial_radius, 'kpccm'),
                         coord_system='data', circle_args={"color": "white", "linewidth": 2})

p.show()

YT throws the following error:

UnitParseError: Could not find unit symbol 'code_length' in the provided symbols.

The above exception was the direct cause of the following exception:
(...)
YTPlotCallbackError: annotate_sphere callback failed

Im guessing ART doesn't store the code units as such but as "unit_{length, mass, etc}". There are workarounds to this, i.e. using axis or plot relative coordinates for the example above. There may be other cases where there is no workaround tho.

Im using python3.10 and yt 4.3.1.

welcome[bot] commented 1 month ago

Hi, and welcome to yt! Thanks for opening your first issue. We have an issue template that helps us to gather relevant information to help diagnosing and fixing the issue.

neutrinoceros commented 1 month ago

HI @AsierLambarri, Thanks for reporting ! Are you able to share the dataset used in your example with us ? alternatively, can you point to a publicly available dataset that shows the same defect ?

AsierLambarri commented 1 month ago

Yes of course!

The ART dataset is the new Agora-ART I CosmoRun Cosmo_v18. It is available on FlatHub under the ART-I section.

Each snapshot has four files associated:

You need all of them to load a single snapshot.

The Consistent Tree I use for halofinding are also available in those links but i don't think it is necessary to reproduce the error.

Cheers

neutrinoceros commented 1 month ago

thank you ! I'll try to give this a go in time for our next scheduled release