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

Debugging2 #149

Merged
merged 5 commits into from
Apr 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 32 additions & 5 deletions src/acom_music_box/music_box.py
Original file line number Diff line number Diff line change
Expand Up @@ -118,11 +118,11 @@ def generateConfig(self, directory):
"evolving_conditions.csv": {},
}

data["initial conditions"] = {}
data["initial conditions"] = {
"initial_conditions.csv": {}
}

for reaction_rate in self.initial_conditions.reaction_rates:
name = "PHOT." + reaction_rate.reaction.name + ".s-1"
data["initial conditions"][name] = reaction_rate.rate


data["model components"] = [
{
Expand All @@ -141,6 +141,7 @@ def generateConfig(self, directory):

config_file.write(json.dumps(data, indent=4))


# Make evolving conditions config
with open(output_path + "/evolving_conditions.csv", 'w', newline='') as evolving_conditions_file:
writer = csv.writer(evolving_conditions_file)
Expand Down Expand Up @@ -171,6 +172,29 @@ def generateConfig(self, directory):

writer.writerow(row)



reaction_names = []
reaction_rates = []

for reaction_rate in self.initial_conditions.reaction_rates:
if reaction_rate.reaction.reaction_type == "PHOTOLYSIS":
name = "PHOT." + reaction_rate.reaction.name + ".s-1"
elif reaction_rate.reaction.reaction_type == "LOSS":
name = "LOSS." + reaction_rate.reaction.name + ".s-1"
elif reaction_rate.reaction.reaction_type == "EMISSION":
name = "EMISSION." + reaction_rate.reaction.name + ".s-1"

reaction_names.append(name)
reaction_rates.append(reaction_rate.rate)
#writes reaction rates inital conditions to file
with open(output_path + "/initial_conditions.csv", 'w', newline='') as initial_conditions_file:
writer = csv.writer(initial_conditions_file)
writer.writerow(reaction_names)
writer.writerow(reaction_rates)



def generateSpeciesConfig(self):
"""
Generate a JSON configuration for the species in the box model.
Expand Down Expand Up @@ -358,6 +382,9 @@ def generateReactionConfig(self):
if(reaction.name != None):
reac["MUSICA name"] = reaction.name

if(reaction.scaling_factor != None):
reac["scaling factor"] = reaction.scaling_factor

reactionsArray.append(reac)

reacList["reactions"] = reactionsArray
Expand Down Expand Up @@ -552,7 +579,7 @@ def readConditionsFromJson(self, path_to_json):
self.reaction_list = ReactionList.from_config_JSON(path_to_json, data, self.species_list)

# Set initial conditions
self.initial_conditions = Conditions.from_config_JSON(data, self.species_list, self.reaction_list)
self.initial_conditions = Conditions.from_config_JSON(path_to_json, data, self.species_list, self.reaction_list)

# Set initial conditions
self.evolving_conditions = EvolvingConditions.from_config_JSON(path_to_json, data, self.species_list, self.reaction_list)
Expand Down
45 changes: 39 additions & 6 deletions src/acom_music_box/music_box_conditions.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import csv
import os
from typing import List
from .music_box_reaction_rate import ReactionRate
from .music_box_species import Species
Expand Down Expand Up @@ -76,20 +78,23 @@ def from_UI_JSON(cls, UI_JSON, species_list, reaction_list):
return cls(pressure, temperature, species_concentrations, reaction_rates)

@classmethod
def from_config_JSON(cls, config_JSON, species_list, reaction_list):
def from_config_JSON(cls, path_to_json, config_JSON, species_list, reaction_list):
pressure = convert_pressure(config_JSON['environmental conditions']['pressure'], 'initial value')

temperature = convert_temperature(config_JSON['environmental conditions']['temperature'], 'initial value')


# Set initial species concentrations
species_concentrations = []
reaction_rates = []

#reads initial conditions from csv if it is given
if 'initial conditions' in config_JSON:
initial_conditions_csv = config_JSON['initial conditions']
#read_initial_conditions_from_csv(initial_conditions_csv)
if 'initial conditions' in config_JSON and len(list(config_JSON['initial conditions'].keys())) > 0:

initial_conditions_path = os.path.dirname(path_to_json) + "/" + list(config_JSON['initial conditions'].keys())[0]
reaction_rates = Conditions.read_initial_rates_from_file(initial_conditions_path, reaction_list)


#reads from config file directly if present
if 'chemical species' in config_JSON:
for chem_spec in config_JSON['chemical species']:
Expand All @@ -105,16 +110,44 @@ def from_config_JSON(cls, config_JSON, species_list, reaction_list):

#TODO: may or may not be necessary
# Set initial reaction rates
reaction_rates = []

for reaction in reaction_list.reactions:
if reaction.name != None and not any(reac.reaction.name == reaction.name for reac in reaction_rates):
reaction_rates.append(ReactionRate(reaction, 0))


return cls(pressure, temperature, species_concentrations, reaction_rates)


@classmethod
def read_initial_rates_from_file(cls, file_path, reaction_list):

reaction_rates = []

with open(file_path, 'r') as csv_file:
initial_conditions = list(csv.reader(csv_file))

if(len(initial_conditions) > 1):
# The first row of the CSV contains headers
headers = initial_conditions[0]

# The second row of the CSV contains rates
rates = initial_conditions[1]


for i in range(0, len(headers)):


reaction_rate = headers[i]

match = filter(lambda x: x.name == reaction_rate.split('.')[1], reaction_list.reactions)

reaction = next(match, None)
rate = rates[i]

reaction_rates.append(ReactionRate(reaction, rate))
return reaction_rates


def add_species_concentration(self, species_concentration):
"""
Expand Down
103 changes: 52 additions & 51 deletions src/acom_music_box/music_box_evolving_conditions.py
Original file line number Diff line number Diff line change
Expand Up @@ -125,58 +125,59 @@ def read_conditions_from_file(cls, file_path, species_list, reaction_list):

# Open the evolving conditions file and read it as a CSV
with open(file_path, 'r') as csv_file:
evolving_conditions = list(csv.reader(csv_file))

# The first row of the CSV contains headers
headers = evolving_conditions[0]
evolving_conditions = list(csv.reader(csv_file))

# Iterate over the remaining rows of the CSV
for i in range(1, len(evolving_conditions)):
# The first column of each row is a time value
times.append(float(evolving_conditions[i][0]))

# Initialize pressure and temperature as None
pressure = None
temperature = None

# If pressure and temperature headers are present in the CSV, extract their values
if 'ENV.pressure.Pa' in headers:
pressure = float(evolving_conditions[i][headers.index('ENV.pressure.Pa')])
if 'ENV.temperature.K' in headers:
temperature = float(evolving_conditions[i][headers.index('ENV.temperature.K')])

# Initialize concentrations list and extract concentration headers
concentrations = []
concentration_headers = list(filter(lambda x: 'CONC' in x, headers))

# For each concentration header, find the matching species and append its concentration to the list
for j in range(len(concentration_headers)):
match = filter(lambda x: x.name == concentration_headers[j].split('.')[1], species_list.species)
species = next(match, None)
concentration = float(evolving_conditions[i][headers.index(concentration_headers[j])])

concentrations.append(SpeciesConcentration(species, concentration))


# Initialize rates list and extract rate headers
rates = []
rate_headers = list(filter(lambda x: 's-1' in x, headers))

# For each rate header, find the matching reaction and append its rate to the list
for k in range(len(rate_headers)):
name_to_match = rate_headers[k].split('.')

if name_to_match[0] == 'LOSS' or name_to_match[0] == 'EMIS':
name_to_match = name_to_match[0] + '_' + name_to_match[1]
else:
name_to_match = name_to_match[1]
match = filter(lambda x: x.name == name_to_match, reaction_list.reactions)
reaction = next(match, None)
rate = float(evolving_conditions[i][headers.index(rate_headers[k])])
rates.append(ReactionRate(reaction, rate))

# Append the conditions for this time point to the conditions list
conditions.append(Conditions(pressure, temperature, concentrations, rates))
if(len(evolving_conditions) > 1):
# The first row of the CSV contains headers
headers = evolving_conditions[0]

# Iterate over the remaining rows of the CSV
for i in range(1, len(evolving_conditions)):
# The first column of each row is a time value
times.append(float(evolving_conditions[i][0]))

# Initialize pressure and temperature as None
pressure = None
temperature = None

# If pressure and temperature headers are present in the CSV, extract their values
if 'ENV.pressure.Pa' in headers:
pressure = float(evolving_conditions[i][headers.index('ENV.pressure.Pa')])
if 'ENV.temperature.K' in headers:
temperature = float(evolving_conditions[i][headers.index('ENV.temperature.K')])

# Initialize concentrations list and extract concentration headers
concentrations = []
concentration_headers = list(filter(lambda x: 'CONC' in x, headers))

# For each concentration header, find the matching species and append its concentration to the list
for j in range(len(concentration_headers)):
match = filter(lambda x: x.name == concentration_headers[j].split('.')[1], species_list.species)
species = next(match, None)
concentration = float(evolving_conditions[i][headers.index(concentration_headers[j])])

concentrations.append(SpeciesConcentration(species, concentration))


# Initialize rates list and extract rate headers
rates = []
rate_headers = list(filter(lambda x: 's-1' in x, headers))

# For each rate header, find the matching reaction and append its rate to the list
for k in range(len(rate_headers)):
name_to_match = rate_headers[k].split('.')

if name_to_match[0] == 'LOSS' or name_to_match[0] == 'EMIS':
name_to_match = name_to_match[0] + '_' + name_to_match[1]
else:
name_to_match = name_to_match[1]
match = filter(lambda x: x.name == name_to_match, reaction_list.reactions)
reaction = next(match, None)
rate = float(evolving_conditions[i][headers.index(rate_headers[k])])
rates.append(ReactionRate(reaction, rate))

# Append the conditions for this time point to the conditions list
conditions.append(Conditions(pressure, temperature, concentrations, rates))

# Return a new instance of the class with the times and conditions

Expand Down
3 changes: 2 additions & 1 deletion src/acom_music_box/music_box_reaction.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ class Reaction:
products (List[Product]): A list of Product instances representing the products. Default is an empty list.
"""

def __init__(self, name=None, reaction_type=None, reactants=None, products=None):
def __init__(self, name=None, reaction_type=None, reactants=None, products=None, scaling_factor=None):
"""
Initializes a new instance of the Reaction class.

Expand All @@ -25,6 +25,7 @@ def __init__(self, name=None, reaction_type=None, reactants=None, products=None)
self.reaction_type = reaction_type
self.reactants = reactants if reactants is not None else []
self.products = products if products is not None else []
self.scaling_factor = scaling_factor

def add_reactant(self, reactant):
"""
Expand Down
3 changes: 2 additions & 1 deletion src/acom_music_box/music_box_reaction_list.py
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ def get_products_from_JSON(self, reaction, species_list):
def get_reactions_from_JSON(self, reaction, species_list):

name = reaction['MUSICA name'] if 'MUSICA name' in reaction else None
scaling_factor = reaction['scaling factor'] if 'scaling factor' in reaction else None
reaction_type = reaction['type']

reactants = ReactionList.get_reactants_from_JSON(reaction, species_list)
Expand Down Expand Up @@ -163,4 +164,4 @@ def get_reactions_from_JSON(self, reaction, species_list):
N = reaction.get('N')
return Troe_Ternary(name, reaction_type, reactants, products, k0_A, k0_B, k0_C, kinf_A, kinf_B, kinf_C, Fc, N)
else:
return Reaction(name, reaction_type, reactants, products)
return Reaction(name, reaction_type, reactants, products, scaling_factor)
Loading
Loading