Skip to content

Commit f36c214

Browse files
Implement comprehensive JLD2 type compatibility solution
- Added ScalesType002 and PhysicalUnitsType002 with enhanced field support - Updated all type references from 001 to 002 versions throughout codebase - Enables loading of legacy JLD2 files with automatic type migration - Preserves actual scale values and handles missing fields gracefully - Tested successfully with real problematic JLD2 files
1 parent 4ca3fda commit f36c214

File tree

5 files changed

+528
-26
lines changed

5 files changed

+528
-26
lines changed

src/functions/data/data_info.jl

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -136,9 +136,24 @@ function infodata(output::Int;
136136
end
137137
if verbose println("Use datatype: ", dtype) end
138138
inflink = string(dtype) * "/info"
139-
dataobject = JLD2.load(fpath, inflink,
140-
typemap=Dict("Mera.PhysicalUnitsType" => JLD2.Upgrade(PhysicalUnitsType001),
141-
"Mera.ScalesType" => JLD2.Upgrade(ScalesType001)))
139+
140+
# Create comprehensive typemap matching the one in loaddata()
141+
typemap = Dict(
142+
# Map old PhysicalUnitsType versions to current one
143+
"Mera.PhysicalUnitsType" => JLD2.Upgrade(PhysicalUnitsType001),
144+
"Mera.PhysicalUnitsType001" => PhysicalUnitsType001,
145+
146+
# Map old ScalesType versions to current one using Upgrade for field conversion
147+
"Mera.ScalesType" => JLD2.Upgrade(ScalesType002),
148+
"Mera.ScalesType001" => JLD2.Upgrade(ScalesType002),
149+
"Mera.ScalesType002" => ScalesType002,
150+
151+
# Map old InfoType versions (if they exist)
152+
"Mera.InfoType" => InfoType,
153+
"Mera.InfoType001" => InfoType,
154+
)
155+
156+
dataobject = JLD2.load(fpath, inflink, typemap=typemap)
142157

143158
# update constants and scales
144159
dataobject.constants = Mera.createconstants()

src/functions/data/data_load.jl

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -160,9 +160,24 @@ function loaddata(output::Int; path::String="./",
160160

161161
# todo: check if request exists
162162
dlink = string(datatype) * "/data"
163-
dataobject = JLD2.load(fpath, dlink,
164-
typemap=Dict("Mera.PhysicalUnitsType" => JLD2.Upgrade(PhysicalUnitsType001),
165-
"Mera.ScalesType" => JLD2.Upgrade(ScalesType001)))
163+
164+
# Create comprehensive typemap following JLD2 best practices for backward compatibility
165+
typemap = Dict(
166+
# Map old PhysicalUnitsType versions to current one
167+
"Mera.PhysicalUnitsType" => JLD2.Upgrade(PhysicalUnitsType001),
168+
"Mera.PhysicalUnitsType001" => PhysicalUnitsType001,
169+
170+
# Map old ScalesType versions to current one using Upgrade for field conversion
171+
"Mera.ScalesType" => JLD2.Upgrade(ScalesType002),
172+
"Mera.ScalesType001" => JLD2.Upgrade(ScalesType002),
173+
"Mera.ScalesType002" => ScalesType002,
174+
175+
# Map old InfoType versions (if they exist)
176+
"Mera.InfoType" => InfoType,
177+
"Mera.InfoType001" => InfoType,
178+
)
179+
180+
dataobject = JLD2.load(fpath, dlink, typemap=typemap)
166181

167182
# update constants and scales
168183
dataobject.info.constants = Mera.createconstants()

src/functions/miscellaneous.jl

Lines changed: 192 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ function createconstants()
2424
# http://www.astro.wisc.edu/~dolan/constants.html
2525
# IAU
2626
# RAMSES
27-
constants = PhysicalUnitsType001() #zeros(Float64, 17)...)
27+
constants = PhysicalUnitsType002() #zeros(Float64, 17)...)
2828
constants.Au = 149597870700e-13 # [cm] Astronomical unit -> from IAU
2929
constants.pc = 3.08567758128e18 # [cm] Parsec -> from IAU
3030
constants.kpc = constants.pc * 1e3
@@ -85,7 +85,7 @@ end
8585
```julia
8686
function createscales!(dataobject::InfoType)
8787
88-
return ScalesType001
88+
return ScalesType002
8989
```
9090
"""
9191
function createscales!(dataobject::InfoType)
@@ -105,7 +105,7 @@ end
105105

106106
function createscales(unit_l::Float64, unit_d::Float64, unit_t::Float64, unit_m::Float64, constants::PhysicalUnitsType001)
107107
#Initialize scale-object
108-
scale = ScalesType001() #zeros(Float64, 32)...)
108+
scale = ScalesType002() #zeros(Float64, 32)...)
109109

110110
# Conversion factors from user units to astronomical units
111111
mH = constants.mH # [g] H-Atom mass -> from RAMSES
@@ -308,6 +308,193 @@ function createscales(unit_l::Float64, unit_d::Float64, unit_t::Float64, unit_m:
308308
return scale
309309
end
310310

311+
# Overload for PhysicalUnitsType002 (same implementation, just different type signature)
312+
function createscales(unit_l::Float64, unit_d::Float64, unit_t::Float64, unit_m::Float64, constants::PhysicalUnitsType002)
313+
#Initialize scale-object
314+
scale = ScalesType002() #zeros(Float64, 32)...)
315+
316+
# Conversion factors from user units to astronomical units
317+
mH = constants.mH # [g] H-Atom mass -> from RAMSES
318+
kB = constants.kB # [cm2 g s-2 K-1] = [erg K-1] Boltzmann constant -> cooling_module.f90 RAMSES
319+
#Mpc = constants.pc /1e6 # [cm] MegaParsec -> from IAU
320+
#kpc = constants.pc /1e3 # [cm] KiloParsec -> from IAU
321+
pc = constants.pc # [cm] Parsec -> from IAU
322+
#mpc = constants.pc *1e3 # [cm] MilliParsec -> from IAU
323+
Au = constants.Au # [cm] Astronomical unit -> from IAU
324+
ly = constants.ly # [cm] Light year -> from IAU
325+
Msol = constants.Msol # [g] Solar mass -> from IAU
326+
Mearth = constants.Mearth # [g] Earth mass -> from IAU
327+
Mjupiter= constants.Mjupiter # [g] Jupiter -> from IAU
328+
#Gyr = constants.yr /1e9 # [s] GigaYear -> from IAU
329+
#Myr = constants.yr /1e6 # [s] MegaYear -> from IAU
330+
yr = constants.yr # [s] Year -> from IAU
331+
X_frac = 0.76 # Hydrogen fraction by mass -> cooling_module.f90 RAMSES
332+
μ = 1/X_frac # mean molecular weight
333+
334+
scale.Mpc = unit_l / pc / 1e6
335+
scale.kpc = unit_l / pc / 1e3
336+
scale.pc = unit_l / pc
337+
scale.mpc = unit_l / pc * 1e3
338+
scale.ly = unit_l / ly
339+
scale.Au = unit_l / Au
340+
scale.km = unit_l / 1.0e5
341+
scale.m = unit_l / 1.0e2
342+
scale.cm = unit_l
343+
scale.mm = unit_l * 10.
344+
scale.μm = unit_l * 1e4
345+
346+
scale.Mpc3 = scale.Mpc^3
347+
scale.kpc3 = scale.kpc^3
348+
scale.pc3 = scale.pc^3
349+
scale.mpc3 = scale.mpc^3
350+
scale.ly3 = scale.ly^3
351+
scale.Au3 = scale.Au^3
352+
scale.km3 = scale.km^3
353+
scale.m3 = scale.m^3
354+
scale.cm3 = scale.cm^3
355+
scale.mm3 = scale.mm^3
356+
scale.μm3 = scale.μm^3
357+
358+
scale.Msol_pc3 = unit_d * pc^3 / Msol
359+
scale.Msun_pc3 = scale.Msol_pc3
360+
scale.g_cm3 = unit_d
361+
362+
scale.Msol_pc2 = unit_d * unit_l * pc^2 / Msol
363+
scale.Msun_pc2 = scale.Msol_pc2
364+
365+
scale.Gyr = unit_t / yr / 1e9
366+
scale.Myr = unit_t / yr / 1e6
367+
scale.yr = unit_t / yr
368+
scale.s = unit_t
369+
scale.ms = unit_t * 1e3
370+
371+
scale.Msol = unit_d * unit_l^3 / Msol
372+
scale.Msun = scale.Msol
373+
scale.Mearth = unit_d * unit_l^3 / Mearth
374+
scale.Mjupiter = unit_d * unit_l^3 / Mjupiter
375+
scale.g = unit_d * unit_l^3
376+
scale.km_s = unit_l / unit_t / 1e5
377+
scale.m_s = unit_l / unit_t / 1e2
378+
scale.cm_s = unit_l / unit_t
379+
380+
scale.nH = X_frac / mH * unit_d # Hydrogen number density in [H/cc]
381+
scale.erg = unit_m * (unit_l / unit_t)^2 # [g (cm/s)^2]
382+
scale.g_cms2 = unit_m / (unit_l * unit_t^2)
383+
384+
scale.T_mu = mH / kB * (unit_l / unit_t)^2 # T/mu [Kelvin]
385+
scale.K_mu = scale.T_mu
386+
scale.T = scale.T_mu * μ # T [Kelvin]
387+
scale.K = scale.T
388+
scale.Ba = unit_m / unit_l / unit_t^2 # Barye (pressure) [cm-1 g s-2]
389+
scale.g_cm_s2 = scale.Ba
390+
scale.p_kB = scale.g_cm_s2 / kB # [K cm-3]
391+
scale.K_cm3 = scale.p_kB # p/kB
392+
393+
# Entropy-specific units for astrophysical applications
394+
scale.erg_g_K = (unit_m * (unit_l / unit_t)^2) / (unit_d * unit_l^3) / kB # [erg/(g·K)] specific entropy
395+
scale.keV_cm2 = scale.erg_g_K * unit_d * unit_l^2 / constants.eV * 1000.0 # [keV·cm²] entropy per particle (X-ray astro)
396+
397+
# Additional entropy unit scales
398+
scale.erg_K = scale.erg_g_K * unit_d * unit_l^3 # [erg/K] total entropy
399+
scale.J_K = scale.erg_K / 1e7 # [J/K] SI total entropy
400+
scale.erg_cm3_K = scale.erg_g_K * unit_d # [erg/(cm³·K)] entropy density
401+
scale.J_m3_K = scale.erg_cm3_K * 1e1 # [J/(m³·K)] SI entropy density
402+
scale.kB_per_particle = constants.k_B # [erg/K per particle] Boltzmann constant
403+
404+
# Angular momentum units
405+
scale.J_s = unit_m * (unit_l^2 / unit_t) # [J·s] Angular momentum (SI)
406+
scale.g_cm2_s = unit_m * (unit_l^2 / unit_t) # [g·cm²/s] Angular momentum (cgs)
407+
scale.kg_m2_s = scale.g_cm2_s * 1e-3 * 1e4 # [kg·m²/s] Angular momentum (SI)
408+
409+
# Magnetic field units (corrected formulas)
410+
scale.Gauss = sqrt(4π * unit_m / (unit_l * unit_t^2)) # [G] Magnetic field strength
411+
scale.muG = scale.Gauss * 1e6 # [μG] Micro-Gauss
412+
scale.microG = scale.muG # Alternative notation
413+
scale.Tesla = scale.Gauss * 1e-4 # [T] Tesla (SI)
414+
415+
# Energy and luminosity scales (corrected)
416+
scale.eV = (unit_m * (unit_l / unit_t)^2) / constants.eV # [eV] Electron volt
417+
scale.keV = scale.eV / 1e3 # [keV] Kilo electron volt
418+
scale.MeV = scale.eV / 1e6 # [MeV] Mega electron volt
419+
scale.erg_s = unit_m * (unit_l / unit_t)^2 / unit_t # [erg/s] Luminosity
420+
scale.Lsol = scale.erg_s / constants.Lsol # [L☉] Solar luminosity
421+
scale.Lsun = scale.Lsol # Alternative notation
422+
423+
# Particle number densities (corrected)
424+
scale.cm_3 = 1. / (unit_l^3) # [cm⁻³] Number density
425+
scale.pc_3 = scale.cm_3 / (pc^3) # [pc⁻³] Number density
426+
scale.n_e = scale.nH # [e⁻/cm³] Electron density (assuming full ionization)
427+
428+
# Cooling and heating rates
429+
scale.erg_g_s = (unit_m * (unit_l / unit_t)^2) / (unit_d * unit_l^3) / unit_t # [erg/(g·s)] Specific cooling rate
430+
scale.erg_cm3_s = unit_m / (unit_l * unit_t^3) # [erg/(cm³·s)] Volumetric cooling rate
431+
432+
# Flux and surface brightness (corrected)
433+
scale.erg_cm2_s = unit_m / (unit_l * unit_t^3) # [erg/(cm²·s)] Energy flux
434+
scale.Jy = scale.erg_cm2_s / 1e-23 # [Jy] Jansky (radio astronomy)
435+
scale.mJy = scale.Jy * 1e3 # [mJy] Milli-Jansky
436+
scale.microJy = scale.Jy * 1e6 # [μJy] Micro-Jansky
437+
438+
# Column density (corrected)
439+
scale.atoms_cm2 = unit_d * unit_l / mH # [atoms/cm²] Column density
440+
scale.NH_cm2 = scale.atoms_cm2 # [H/cm²] Hydrogen column density
441+
scale.g_cm2 = unit_d * unit_l # [g/cm²] Surface density
442+
443+
# Gravitational and acceleration unit scales
444+
scale.cm_s2 = unit_l / unit_t^2 # [cm/s²] Acceleration
445+
scale.m_s2 = scale.cm_s2 / 100.0 # [m/s²] SI acceleration
446+
scale.km_s2 = scale.cm_s2 / 1e5 # [km/s²] Acceleration
447+
scale.pc_Myr2 = scale.cm_s2 * (scale.Myr^2 / scale.pc) # [pc/Myr²] Astronomical acceleration
448+
449+
# Gravitational potential and energy unit scales
450+
scale.erg_g = (unit_l / unit_t)^2 # [erg/g] Specific energy/potential
451+
scale.J_kg = scale.erg_g / 1e7 # [J/kg] SI specific energy
452+
scale.km2_s2 = scale.erg_g / 1e10 # [km²/s²] Velocity squared units
453+
454+
# Gravitational energy analysis unit scales
455+
scale.u_grav = unit_d * scale.erg_g # [erg/cm³] Gravitational energy density
456+
scale.erg_cell = unit_d * scale.erg_g * unit_l^3 # [erg] Total energy per cell
457+
scale.dyne = unit_d * scale.cm_s2 # [dyne] Force
458+
scale.s_2 = scale.cm_s2 / unit_l # [s⁻²] Acceleration per length
459+
scale.lambda_J = unit_l # [cm] Jeans length scale
460+
scale.M_J = unit_d * unit_l^3 # [g] Jeans mass scale
461+
scale.t_ff = unit_t # [s] Free-fall time scale
462+
scale.alpha_vir = 1.0 # Dimensionless virial parameter
463+
464+
# Dimensionless and angular units (no scaling)
465+
scale.dimensionless = 1.0 # Dimensionless quantities
466+
scale.rad = 1.0 # [rad] Radians (dimensionless)
467+
scale.deg = 180.0 / π # [deg] Degrees
468+
469+
# Complete set of specialized astrophysical unit scales for comprehensive gravitational analysis
470+
scale.gravitational_energy_density = scale.u_grav # [erg/cm³] Gravitational energy density → same as u_grav
471+
scale.gravitational_binding_energy = scale.u_grav # [erg/cm³] Binding energy density → same as u_grav
472+
scale.total_binding_energy = scale.erg_cell # [erg] Total energy per cell → same as erg_cell
473+
scale.specific_gravitational_energy = scale.erg_g # [erg/g] Specific energy → same as erg_g
474+
scale.gravitational_work = scale.erg # [erg] Work/energy → energy unit
475+
scale.jeans_length_gravity = scale.lambda_J # [cm] Jeans length → length unit
476+
scale.jeans_mass_gravity = scale.M_J # [g] Jeans mass → mass unit
477+
scale.jeansmass = scale.g # [g] Jeans mass (hydro) → mass unit
478+
scale.freefall_time_gravity = scale.s # [s] Free-fall time → time unit
479+
scale.ekin = scale.erg # [erg] Kinetic energy → energy unit
480+
scale.etherm = scale.erg # [erg] Thermal energy per cell → energy unit
481+
scale.virial_parameter_local = scale.dimensionless # Dimensionless virial param → dimensionless
482+
scale.Fg = scale.dyne # [dyne] Force → force unit
483+
scale.poisson_source = scale.s_2 # [s⁻²] Poisson source term → acceleration/length unit
484+
485+
# Coordinate system components (map to proper units)
486+
scale.ar_cylinder = scale.cm_s2 # [cm/s²] Cylindrical radial acceleration → acceleration unit
487+
scale.aϕ_cylinder = scale.cm_s2 # [cm/s²] Cylindrical azimuthal acceleration → acceleration unit
488+
scale.ar_sphere = scale.cm_s2 # [cm/s²] Spherical radial acceleration → acceleration unit
489+
scale.aθ_sphere = scale.cm_s2 # [cm/s²] Spherical polar acceleration → acceleration unit
490+
scale.aϕ_sphere = scale.cm_s2 # [cm/s²] Spherical azimuthal acceleration → acceleration unit
491+
scale.r_cylinder = scale.cm # [cm] Cylindrical radius → length unit
492+
scale.r_sphere = scale.cm # [cm] Spherical radius → length unit
493+
scale.ϕ = scale.rad # [rad] Azimuthal angle → angle unit
494+
495+
return scale
496+
end
497+
311498
"""
312499
### Get a list of all exported Mera types and functions:
313500
```julia
@@ -329,12 +516,12 @@ end
329516
### Convert a value to human-readable astrophysical units and round to ndigits
330517
(pass the value in code units and the quantity specification (length, time) )
331518
```julia
332-
function humanize(value::Float64, scale::ScalesType001, ndigits::Int, quantity::String)
519+
function humanize(value::Float64, scale::ScalesType002, ndigits::Int, quantity::String)
333520
334521
return value, value_unit
335522
```
336523
"""
337-
function humanize(value::Float64, scale::ScalesType001, ndigits::Int, quantity::String)
524+
function humanize(value::Float64, scale::ScalesType002, ndigits::Int, quantity::String)
338525

339526
if quantity == ""
340527
round(value, digits=ndigits)

src/functions/viewfields.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ function viewfields(object::ArgumentsType)
7171
end
7272

7373

74-
function viewfields(object::ScalesType001)
74+
function viewfields(object::ScalesType002)
7575

7676
list_field = propertynames(object)
7777

@@ -195,7 +195,7 @@ end
195195

196196

197197

198-
function viewfields(object::PhysicalUnitsType001)
198+
function viewfields(object::PhysicalUnitsType002)
199199

200200
list_field = propertynames(object)
201201

0 commit comments

Comments
 (0)