I am converting a large Python code into Julia. In my Python code, I have the ndarray datatype objects that
allow me to add fieldnames to each value of an array (as in the name of a chemical species and its concentration) as well as specify its format (which is all Float64, so it does not really matter as they are all the same type), and
these fieldnames are like keys and can be used to retrieve the values they are associated with. So if I want H2O, it retrieves a particular species’ (H2O) concentration.
allows me to initialize a complex object (i.e., 2D arrays of these objects that have 20 species each with their chemical name) like with the zeros and empty functions in python.
In python, I would do this:
dtype1=dict(names=listofnames,formats=[np.float64*len(listofnames)]
N = np.zeros((10,10),dtype=dtype1)
What would be the exact replacement type object for this in Julia?
Are there any modules that I should be aware of that help me create and manipulate such objects?
So far, I have created a mutable struct - say, Species, created a constructor for default values, an ArrayofStructs as ArrayofSpecies, and used this object to fill a 2D array.
mutable struct Species
name::String
value::Float64
end
Species(x::String)=Species(x,0.0)
ArrayofSpeciesObject = [Species(x) for x in arrayofstrings]
A=fill(arrayofSpeciesObject,10,10)
But I am missing the ease of retrieving values for each chemical species with their fieldnames in python as you would for dictionaries, i.e., A[i,j]["H2O"]
If I understand you correctly, you just want to define a struct datatype defining the elements of your array, giving its fields and types:
struct ChemicalSpecies
name::String
H2O::Float64
end
Then you can allocate an uninitialized 20×30 array of these values with:
a = Array{ChemicalSpecies}(undef, 20, 30)
You can also use zeros(ChemicalSpecies, 20, 30) to allocate an array initialized to zero values, as long as you define Base.zero(::Type{ChemicalSpecies}) = ChemicalSpecies(...something...), though it’s not clear to me what a “zero” would mean for a String field. You could also use a comprehension:
a = [ChemicalSpecies("", 0.0) for i = 1:20, j = 1:30]
Then you can access data with a[i,j].H2O, for example.
I hope I am not missing something, but how would I adapt such a mutable struct for species with different names, say I have H2O, CO2, NH3.
a[i,j].H2O, a[I,j].CO2 etc. require the fieldname for each species to be its particular name.
I require like 100+ different species to be in an array object, which is in turn an array element in a 2D array.
and then create an array of such composition objects.
These composition objects are static vectors (which are quite fast to operate on). They also have a whole set of operations defined in compositional space so you don’t mess up with ratios of the parts.
The only missing feature is the access with c.CO₂ syntax that could be easily added in case this is useful to you.
In case you want to experiment with the code, I’ve just added c.CO2 syntax support in the master branch. The release should be available in a few minutes in the package manager.
I am dealing with code designed to calculate chemistry in astrophysical objects. So essentially it has a large chemical reaction network that is solved across a 2D spatial grid. I think ultimately structs or named tuples would be helpful for my purposes!
Thanks juliohm! Not exactly compositions, I am actually calculating abundances of different chemical species across an astronomical object. But CoDa.jl seems very useful - I will make a note of it! Thanks for adding field access to it!
For me it looks like a (n+1)D array, where n is the space dimensionality, and in the last dimension you have the abundancies of the species. These species have all their names, reactivities etc., but these could be saved separately in a 1D array of structs.
P.S. With AxisArray you can have indexing by substance (Symbol or String) along the corresponding axis
Can you please elaborate on the concept of abundances @onafinedayforscience? Compositions don’t need to be percentages or add up to 1. If these abundances are some sort of fraction or proportion of chemicals from a bulk of material, this is a composition.
What I am really dealing with is number densities (1/cm^3) and mass densities (g/cm^3). By abundances, I mean like chemical species “x” with respect to the most abundant gas which is H2 - so x/H2. There are about a 100 different chemical species, most of them have negligible concentrations, some with moderate concentrations and few form the bulk of the composition of the cloud at each spatial grid point (i,j).
Yes, I am not 100% sure, but it seems like a good combination of GeoStats.jl + CoDa.jl both of which I am involved. Not so much the latter, but the former is taking a lot of my research time