Skip to content

Commit

Permalink
changed initial conditions to be read and stored in a separate file
Browse files Browse the repository at this point in the history
  • Loading branch information
alexjamesgarza committed Apr 17, 2024
1 parent 0a12bc4 commit 696f7f4
Show file tree
Hide file tree
Showing 10 changed files with 181 additions and 114 deletions.
43 changes: 30 additions & 13 deletions src/acom_music_box/music_box.py
Original file line number Diff line number Diff line change
Expand Up @@ -118,18 +118,11 @@ def generateConfig(self, directory):
"evolving_conditions.csv": {},
}

data["initial conditions"] = {}

for reaction_rate in self.initial_conditions.reaction_rates:
if(reaction_rate.reaction.reaction_type == "PHOTOLYSIS"):
name = "PHOT." + reaction_rate.reaction.name + ".s-1"
data["initial conditions"][name] = reaction_rate.rate
elif(reaction_rate.reaction.reaction_type == "LOSS"):
name = "LOSS." + reaction_rate.reaction.name + ".s-1"
data["initial conditions"][name] = reaction_rate.rate
elif (reaction_rate.reaction.reaction_type =="EMISSION"):
name = "EMISSION." + reaction_rate.reaction.name + ".s-1"
data["initial conditions"][name] = reaction_rate.rate
data["initial conditions"] = {
"initial_conditions.csv": {}
}



data["model components"] = [
{
Expand All @@ -148,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 @@ -178,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 @@ -562,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
49 changes: 36 additions & 13 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,7 +78,7 @@ 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')
Expand All @@ -87,20 +89,12 @@ def from_config_JSON(cls, config_JSON, species_list, reaction_list):
reaction_rates = []

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

#read_initial_conditions_from_csv(initial_conditions_csv)
for reaction_rate in config_JSON['initial conditions']:

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

reaction = next(match, None)

rate = config_JSON['initial conditions'][reaction_rate]

reaction_rates.append(ReactionRate(reaction, rate))
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 @@ -125,6 +119,35 @@ def from_config_JSON(cls, config_JSON, species_list, reaction_list):
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
7 changes: 6 additions & 1 deletion tests/configs/wall_loss_config/camp_data/config.json
Original file line number Diff line number Diff line change
@@ -1 +1,6 @@
{"camp-files": ["species.json", "reactions.json"]}
{
"camp-files": [
"species.json",
"reactions.json"
]
}
38 changes: 18 additions & 20 deletions tests/configs/wall_loss_config/camp_data/reactions.json
Original file line number Diff line number Diff line change
@@ -1,44 +1,37 @@
{
"camp-data": [
{
"type": "MECHANISM",
"name": "music box interactive configuration",
"type": "MECHANISM",
"reactions": [
{
"type": "PHOTOLYSIS",

"scaling factor": 1,
"MUSICA name": "LOSS_SOA1 wall loss",
"reactants": {
"SOA1": {}
"SOA2": {}
},
"products": {
"irr__b27a3f9c-d866-409c-ba72-dd9b12620387": {
"irr__3fddcf85-062e-4a73-be2c-8f3bbe3af3da": {
"yield": 1
}
}
},
"MUSICA name": "LOSS_SOA2 wall loss",
"scaling factor": 1
},
{
"type": "PHOTOLYSIS",

"scaling factor": 1,
"MUSICA name": "LOSS_SOA2 wall loss",
"reactants": {
"SOA2": {}
"SOA1": {}
},
"products": {
"irr__da4d4fe9-644a-4824-9394-e79d2fbd460f": {
"irr__49b12001-dc96-4a05-9715-e3cd05cb37d5": {
"yield": 1
}
}
},
"MUSICA name": "LOSS_SOA1 wall loss",
"scaling factor": 1
},
{
"type": "ARRHENIUS",
"A": 8.8e-17,
"Ea": 0,
"B": 0,
"D": 300,
"E": 0,
"reactants": {
"O3": {
"qty": 1
Expand All @@ -54,10 +47,15 @@
"SOA2": {
"yield": 0.09
},
"irr__f290a9b8-ac95-47cf-958b-f73a1e7fcd48": {
"irr__d726e081-c0f1-4649-8947-4919aefd6ac8": {
"yield": 1
}
}
},
"A": 8.8e-17,
"B": 0,
"D": 300,
"E": 0,
"Ea": 0
}
]
}
Expand Down
15 changes: 7 additions & 8 deletions tests/configs/wall_loss_config/camp_data/species.json
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
{
"camp-data": [

{"type" : "RELATIVE_TOLERANCE",
"value" : 1e-4
{
"type": "RELATIVE_TOLERANCE",
"value": 0.0001
},
{
"name": "M",
"type": "CHEM_SPEC",
"tracer type": "CONSTANT"
"type": "CHEM_SPEC"
},
{
"name": "a-pinene",
Expand All @@ -26,15 +25,15 @@
"type": "CHEM_SPEC"
},
{
"name": "irr__b27a3f9c-d866-409c-ba72-dd9b12620387",
"name": "irr__3fddcf85-062e-4a73-be2c-8f3bbe3af3da",
"type": "CHEM_SPEC"
},
{
"name": "irr__da4d4fe9-644a-4824-9394-e79d2fbd460f",
"name": "irr__49b12001-dc96-4a05-9715-e3cd05cb37d5",
"type": "CHEM_SPEC"
},
{
"name": "irr__f290a9b8-ac95-47cf-958b-f73a1e7fcd48",
"name": "irr__d726e081-c0f1-4649-8947-4919aefd6ac8",
"type": "CHEM_SPEC"
}
]
Expand Down
1 change: 1 addition & 0 deletions tests/configs/wall_loss_config/evolving_conditions.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@

2 changes: 2 additions & 0 deletions tests/configs/wall_loss_config/initial_conditions.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
PHOT.LOSS_SOA1 wall loss.s-1,PHOT.LOSS_SOA2 wall loss.s-1
0.01,0.05
Loading

0 comments on commit 696f7f4

Please sign in to comment.