def main(): # Reading from User leaving = Substance.from_formula('H2O') # Reading of conjungates CSV data = pd.read_csv('conjugates_input.csv', index_col=0, skipinitialspace=True) formula = data["formula"] conjugate = data["conjugate"] # Creating od necessary variables formula_list = [] conjugate_list = [] # Creating of two lists for position in formula: conjungate1 = Substance.from_formula(position) for x in formula: conjungate2 = Substance.from_formula(x) dict_formula = dict( Counter(conjungate1.composition) + Counter(conjungate2.composition) - Counter(leaving.composition)) formula_list.append(dict_to_formula(dict_formula)) for cona in conjugate: firstcon = cona for conb in conjugate: secondcon = conb conjugate_list.append(firstcon + '-' + secondcon) results_to_csv(conjugate_list, formula_list)
def equation(cmpin, cmpout): Set_in = set(cmpin) Set_out = set(cmpout) reac, prod = balance_stoichiometry(Set_in, Set_out) for i in range(len(cmpin)): if reac[cmpin[i]] != 1: print(reac[cmpin[i]], end='') out = Substance.from_formula(cmpin[i]) print(out.unicode_name, end='') if i != len(cmpin) - 1: print(' + ', end=''), print(' ----> ', end='') for i in range(len(cmpout)): if prod[cmpout[i]] != 1: print(prod[cmpout[i]], end='') out = Substance.from_formula(cmpout[i]) print(out.unicode_name, end='') if i != len(cmpout) - 1: print(' + ', end=''),
def test_get_odesys__with_units(): a = Substance('A') b = Substance('B') molar = u.molar second = u.second r = Reaction({'A': 2}, {'B': 1}, param=1e-3/molar/second) rsys = ReactionSystem([r], [a, b]) odesys = get_odesys(rsys, include_params=True, unit_registry=SI_base_registry)[0] c0 = { 'A': 13*u.mol / u.metre**3, 'B': .2 * u.molar } conc_unit = get_derived_unit(SI_base_registry, 'concentration') t = np.linspace(0, 10)*u.hour xout, yout, info = odesys.integrate( t, rsys.as_per_substance_array(c0, unit=conc_unit), atol=1e-10, rtol=1e-12) t_unitless = to_unitless(xout, u.second) Aref = dimerization_irrev(t_unitless, 1e-6, 13.0) # Aref = 1/(1/13 + 2*1e-6*t_unitless) yref = np.zeros((xout.size, 2)) yref[:, 0] = Aref yref[:, 1] = 200 + (13-Aref)/2 assert allclose(yout, yref*conc_unit)
def _get_cv(kelvin=1, gram=1, mol=1): Al = Substance.from_formula('Al', data={'DebyeT': 428*kelvin}) Be = Substance.from_formula('Be', data={'DebyeT': 1440*kelvin}) def einT(s): return 0.806*s.data['DebyeT'] return {s.name: EinsteinSolid([einT(s), s.mass * gram/mol], substance=s) for s in (Al, Be)}
def el(reac, prod): elr = [] elp = [] for i in reac: elr.append(Substance.from_formula(i).html_name) for i in prod: elp.append(Substance.from_formula(i).html_name) return elr, elp
def __init__(self, Acc_Forg: float = 0.2, Acc_N2: float = 134): Aitken = { "palmitic": 0.2, "(NH4)2SO4": 0.8, "NaCl": 0, } Accumulation = { "palmitic": Acc_Forg, "(NH4)2SO4": 0, "NaCl": (1 - Acc_Forg), } super().__init__( ionic_dissociation_phi={ "palmitic": 1, "(NH4)2SO4": 3, "NaCl": 2, }, is_soluble={ "palmitic": False, "(NH4)2SO4": True, "NaCl": True, }, densities={ "palmitic": 0.852 * si.g / si.cm**3, "(NH4)2SO4": 1.77 * si.g / si.cm**3, "NaCl": 2.16 * si.g / si.cm**3, }, compounds=("palmitic", "(NH4)2SO4", "NaCl"), molar_masses={ "palmitic": 256.4 * si.g / si.mole, "(NH4)2SO4": Substance.from_formula("(NH4)2SO4").mass * si.gram / si.mole, "NaCl": Substance.from_formula("NaCl").mass * si.gram / si.mole, }, ) self.modes = ( { "f_org": 1 - self.f_soluble_volume(Aitken), "kappa": self.kappa(Aitken), "nu_org": self.nu_org(Aitken), "spectrum": spectra.Lognormal( norm_factor=226 / si.cm**3, m_mode=19.6 * si.nm, s_geom=1.71 ), }, { "f_org": 1 - self.f_soluble_volume(Accumulation), "kappa": self.kappa(Accumulation), "nu_org": self.nu_org(Accumulation), "spectrum": spectra.Lognormal( norm_factor=Acc_N2 / si.cm**3, m_mode=69.5 * si.nm, s_geom=1.7 ), }, )
def __init__(self, constants): self._values = { compound: Substance.from_formula(compound).mass * si.gram / si.mole / constants.Md for compound in GASEOUS_COMPOUNDS.values() } for compounds in AQUEOUS_COMPOUNDS.values(): for compound in compounds: self._values[compound] = \ Substance.from_formula(compound).mass * si.gram / si.mole / constants.Md
def _get_cv(kelvin=1, gram=1, mol=1): Al = Substance.from_formula('Al', data={'DebyeT': 428 * kelvin}) Be = Substance.from_formula('Be', data={'DebyeT': 1440 * kelvin}) def einT(s): return 0.806 * s.data['DebyeT'] return { s.name: EinsteinSolid([einT(s), s.mass * gram / mol], substance=s) for s in (Al, Be) }
def _get_cv(kelvin=1, gram=1, mol=1): Al = Substance.from_formula("Al", data={"DebyeT": 428 * kelvin}) Be = Substance.from_formula("Be", data={"DebyeT": 1440 * kelvin}) def einT(s): return 0.806 * s.data["DebyeT"] return { s.name: EinsteinSolid([einT(s), s.mass * gram / mol]) for s in (Al, Be) }
def test_at_t_0(): # Arrange settings = Settings(n_sd=100, dt=1 * si.s, n_substep=5) settings.t_max = 0 simulation = Simulation(settings) specific_gravities = SpecificGravities( simulation.particulator.formulae.constants) # Act output = simulation.run() # Assert np.testing.assert_allclose(output['RH'][0], 95) np.testing.assert_allclose(output['gas_S_IV_ppb'][0], 0.2) np.testing.assert_allclose(output['gas_N_mIII_ppb'][0], 0.1) np.testing.assert_allclose(output['gas_H2O2_ppb'], 0.5) np.testing.assert_allclose(output['gas_N_V_ppb'], 0.1) np.testing.assert_allclose(output['gas_O3_ppb'], 50) np.testing.assert_allclose(output['gas_C_IV_ppb'], 360 * 1000) rtol = 0.15 mass_conc_SO4mm = 2 mass_conc_NH4p = 0.375 num_conc_SO4mm = mass_conc_SO4mm / Substance.from_formula( "SO4").mass * si.gram / si.mole num_conc_NH4p = mass_conc_NH4p / Substance.from_formula( "NH4").mass * si.gram / si.mole np.testing.assert_allclose(num_conc_NH4p, num_conc_SO4mm, rtol=.005) mass_conc_H = num_conc_NH4p * Substance.from_formula( "H").mass * si.gram / si.mole np.testing.assert_allclose( actual=np.asarray(output['q_dry']) * np.asarray(output['rhod']), desired=mass_conc_NH4p + mass_conc_SO4mm + mass_conc_H, rtol=rtol) expected = {k: 0 for k in AQUEOUS_COMPOUNDS} expected['S_VI'] = mass_conc_SO4mm * si.ug / si.m**3 expected['N_mIII'] = mass_conc_NH4p * si.ug / si.m**3 for key in expected: mole_fraction = np.asarray(output[f"aq_{key}_ppb"]) convert_to(mole_fraction, 1 / PPB) compound = AQUEOUS_COMPOUNDS[key][0] # sic! np.testing.assert_allclose( actual=(settings.formulae.trivia.mole_fraction_2_mixing_ratio( mole_fraction, specific_gravity=specific_gravities[compound]) * np.asarray(output['rhod'])), desired=expected[key], rtol=rtol)
def nice_to_learn(): print("--- using chempy ---") from chempy import Substance from chempy import balance_stoichiometry from pprint import pprint # substances = {s.name: s for s in [ # Substance('pancake', composition={'eggs': 1, 'spoons_of_flour': 2, 'cups_of_milk': 1}), # Substance('eggs_6pack', composition={'eggs': 6}), # Substance('milk_carton', composition={'cups_of_milk': 4}), # Substance('flour_bag', composition={'spoons_of_flour': 60}) # ]} # for x in balance_stoichiometry({'eggs_6pack', 'milk_carton', 'flour_bag'}, # {'pancake'}, substances=substances): # pprint(dict(x)) substances = {s.name: s for s in [ Substance('ORE', composition={} ), Substance('AIR', composition={} ), Substance('A', composition={'ORE': 1, 'AIR': 1} ), Substance('B', composition={'ORE': 1, 'AIR': 1} ), Substance('C', composition={'A': 7, 'B': 1}), Substance('D', composition={'A': 7, 'C': 1}), Substance('E', composition={'A': 7, 'D': 1}), Substance('FUEL', composition={'A': 7, 'E': 1}) ]} for x in balance_stoichiometry({'ORE', 'A', 'B', 'C', 'D', 'E'}, {'FUEL': 1}, substances=substances, underdetermined=None): pprint(dict(x))
def test_as_per_substance_html_table(): substances = OrderedDict([(k, Substance.from_formula(k)) for k in "H OH".split()]) assert html(as_per_substance_html_table([2, 3], substances)).count("<tr>") == 3 assert ( html(as_per_substance_html_table({"H": 2, "OH": 3}, substances)).count("<tr>") == 3 )
def search(self,my_list): '''On cherche dans notre base Chem.json si toutes les espèces de my_list sont connues; sinon, on ajoute les espèces inconnues.''' #Extrait les formules de la liste en argument local_list=[x for (x,y,z) in my_list] #liste identique mais au format chempy temp=[Substance.from_formula(x).unicode_name for x in local_list] #Génère un dictionnaire au format chempy{Formule:coeff stoechio} #La fonction zip permet d'extraire depuis deux listes local_dict={v : y for v ,(x,y,z) in zip(temp, my_list)} #Ouvre le fichier en lecture with open("chem.json") as my_file: #chargement des données du fichier au format json (dictionnaire) data=json.load(my_file) #Récupère les formules du fichier formules=[ v for k,v in data.items()] #Ferme le fichier my_file.close() #Récupère l'intersection avec la liste entrée self.connus=list(set(formules).intersection(local_list)) #Appelle la fonction ajout self.ajout(local_list) #Renvoie le dictionnaire pour l'équation return local_dict
def test_get_odesys__rate_exprs_cb(): k = .2 a = Substance('A') b = Substance('B') r = Reaction({'A': 1}, {'B': 1}, param=k) rsys = ReactionSystem([r], [a, b]) assert sorted(rsys.substances.keys()) == ['A', 'B'] odesys, extra = get_odesys(rsys) c0 = {'A': 1.0, 'B': 3.0} t = np.linspace(0.0, 10.0) res = odesys.integrate(t, c0) yref = np.zeros((t.size, 2)) yref[:, 0] = np.exp(-k*t) yref[:, 1] = 4 - np.exp(-k*t) assert np.allclose(res.yout, yref) rate = extra['rate_exprs_cb'](res.xout, res.yout, res.params) assert np.allclose(rate[:, 0], k*yref[:, 0])
def test_molar_masses_of_the_elements_gh172(): from chempy import Substance previous_mass = 0 for symbol in symbols: this_mass = Substance.from_formula(symbol).mass # Note that any average atomic masses of naturally occurring isotopes loose their # meaning for trans-uranium elements. The numbers are almost to be considered arbitrary # and the user needs to know what isotope they have at hand (and use isotopic mass). if symbol in ('K', 'Ni', 'I', 'Pa', 'Np', 'Am'): assert this_mass < previous_mass elif symbol in ('Bk', 'Og'): assert this_mass == previous_mass else: assert this_mass > previous_mass previous_mass = this_mass assert Substance.from_formula('Hs').mass == 271
def test_as_per_substance_html_table(): substances = OrderedDict([(k, Substance.from_formula(k)) for k in 'H OH'.split()]) assert html(as_per_substance_html_table([2, 3], substances)).count('<tr>') == 3 assert html(as_per_substance_html_table({ 'H': 2, 'OH': 3 }, substances)).count('<tr>') == 3
def test_get_odesys_1(): k = .2 a = Substance('A') b = Substance('B') r = Reaction({'A': 1}, {'B': 1}, param=k) rsys = ReactionSystem([r], [a, b]) assert sorted(rsys.substances.keys()) == ['A', 'B'] odesys = get_odesys(rsys, include_params=True)[0] c0 = { 'A': 1.0, 'B': 3.0, } t = np.linspace(0.0, 10.0) xout, yout, info = odesys.integrate(t, c0) yref = np.zeros((t.size, 2)) yref[:, 0] = np.exp(-k*t) yref[:, 1] = 4 - np.exp(-k*t) assert np.allclose(yout, yref)
def solveEq(userString): try: outputString = '' bothSides = userString.split(' = ') reactants = set(bothSides[0].split(' + ')) products = set(bothSides[1].split(' + ')) reac, prod = balance_stoichiometry(reactants, products) count = 0 for i in dict(reac): count += 1 outputString += str(reac[i]) if (count == len(dict(reac))): addedStr = str(Substance.from_formula(i).unicode_name) outputString += addedStr continue else: addedStr = str(Substance.from_formula(i).unicode_name) outputString += addedStr + ' + ' outputString += ' → ' count = 0 for i in dict(prod): count += 1 outputString += str(prod[i]) if (count == len(dict(prod))): addedStr = str(Substance.from_formula(i).unicode_name) outputString += addedStr continue else: addedStr = str(Substance.from_formula(i).unicode_name) outputString += addedStr + ' + ' return outputString except: return ('Error: Unsolveable or Bad Formatting')
def __init__(self, key, dry_radius_bins_edges): super().__init__(name=f'dm_{key}/dlog_10(dry diameter)', unit='µg / m3 / (unit dD/D)', description=f'... {key} ...') self.key = key self.moment_0 = None self.moments = None self.molar_mass = Substance.from_formula( AQUEOUS_COMPOUNDS[key][0]).mass * si.gram / si.mole self.dry_radius_bins_edges = dry_radius_bins_edges
def __init__(self, key, dry_radius_bins_edges, specific=False): super().__init__( name=f'dm_{key}/dlog_10(dry diameter){"_spec" if specific else ""}', unit=f'µg / {"kg" if specific else "m3"} / (unit dD/D)', description=f'... {key} ...') self.key = key self.dry_radius_bins_edges = dry_radius_bins_edges self.molar_mass = Substance.from_formula( AQUEOUS_COMPOUNDS[key][0]).mass * si.gram / si.mole self.specific = specific
def test_get_odesys_2(): g = Radiolytic([3.14]) a = Substance('A') b = Substance('B') r = Reaction({'A': 1}, {'B': 1}, param=g) rsys = ReactionSystem([r], [a, b]) odesys = get_odesys(rsys, include_params=True)[0] c0 = { 'A': 1.0, 'B': 3.0, } t = np.linspace(0.0, .1) xout, yout, info = odesys.integrate(t, rsys.as_per_substance_array(c0), {'doserate': 2.72, 'density': .998}) yref = np.zeros((t.size, 2)) k = 3.14*2.72*.998 yref[:, 0] = 1 - k*t yref[:, 1] = 3 + k*t assert np.allclose(yout, yref)
def __init__(self, Acc_Forg: float = 0.3, Acc_N2: float = 30): Ultrafine = { "SOA1": 0.52, "SOA2": 0, "(NH4)2SO4": 0.48, } Accumulation = { "SOA1": 0, "SOA2": Acc_Forg, "(NH4)2SO4": (1 - Acc_Forg), } super().__init__( ionic_dissociation_phi={ "SOA1": 1, "SOA2": 1, "(NH4)2SO4": 3, }, molar_masses={ "SOA1": 190 * si.g / si.mole, "SOA2": 368.4 * si.g / si.mole, "(NH4)2SO4": Substance.from_formula("(NH4)2SO4").mass * si.gram / si.mole, }, densities={ "SOA1": 1.24 * si.g / si.cm**3, "SOA2": 1.2 * si.g / si.cm**3, "(NH4)2SO4": 1.77 * si.g / si.cm**3, }, compounds=("SOA1", "SOA2", "(NH4)2SO4"), is_soluble={ "SOA1": False, "SOA2": False, "(NH4)2SO4": True, }, ) self.modes = ( { "f_org": 1 - self.f_soluble_volume(Ultrafine), "kappa": self.kappa(Ultrafine), "nu_org": self.nu_org(Ultrafine), "spectrum": spectra.Lognormal( norm_factor=2000 / si.cm**3, m_mode=11.5 * si.nm, s_geom=1.71 ), }, { "f_org": 1 - self.f_soluble_volume(Accumulation), "kappa": self.kappa(Accumulation), "nu_org": self.nu_org(Accumulation), "spectrum": spectra.Lognormal( norm_factor=Acc_N2 / si.cm**3, m_mode=100 * si.nm, s_geom=1.70 ), }, )
def test_get_odesys__ScaledSys(): from pyodesys.symbolic import ScaledSys k = 0.2 a = Substance("A") b = Substance("B") r = Reaction({"A": 1}, {"B": 1}, param=k) rsys = ReactionSystem([r], [a, b]) assert sorted(rsys.substances.keys()) == ["A", "B"] odesys = get_odesys(rsys, include_params=True, SymbolicSys=ScaledSys)[0] c0 = { "A": 1.0, "B": 3.0, } t = np.linspace(0.0, 10.0) xout, yout, info = odesys.integrate(t, c0) yref = np.zeros((t.size, 2)) yref[:, 0] = np.exp(-k * t) yref[:, 1] = 4 - np.exp(-k * t) assert np.allclose(yout, yref)
def test_get_odesys_2(): g = Radiolytic([3.14]) a = Substance("A") b = Substance("B") r = Reaction({"A": 1}, {"B": 1}, param=g) rsys = ReactionSystem([r], [a, b]) odesys = get_odesys(rsys, include_params=True)[0] c0 = { "A": 1.0, "B": 3.0, } t = np.linspace(0.0, 0.1) xout, yout, info = odesys.integrate( t, rsys.as_per_substance_array(c0), {"doserate": 2.72, "density": 0.998} ) yref = np.zeros((t.size, 2)) k = 3.14 * 2.72 * 0.998 yref[:, 0] = 1 - k * t yref[:, 1] = 3 + k * t assert np.allclose(yout, yref)
def __init__(self, key, dry_radius_bins_edges, specific=False, name=None, unit='kg/m^3'): super().__init__(name=name, unit=unit, attr_unit='m') self.key = key self.dry_radius_bins_edges = dry_radius_bins_edges self.molar_mass = Substance.from_formula( AQUEOUS_COMPOUNDS[key][0]).mass * si.g / si.mole self.specific = specific
def analyze(equation): # Parsing substance from formula try: substance = Substance.from_formula(equation) except: return [["Error: Check Formatting"]] try: # Gets elemental symbol for given atomic number def getSymbol(atomicNum): intElement = int(atomicNum) myElement = e(intElement) return (str(myElement.symbol)) # Initializing empty list inputList = [] # Adding tuples to inputList # No charge stat, ie element if 0 not in substance.composition.keys(): for element in substance.composition.keys(): inputList.append( (getSymbol(element), substance.composition[element])) else: for element in substance.composition.keys(): if element != 0: inputList.append( (getSymbol(element), substance.composition[element])) # Casting to OrderedDict inputList = collections.OrderedDict(inputList) # Actually getting mass percents massPercents = mass_fractions(inputList) # Result mpStr = str() # Build result string for element in massPercents.keys(): valueDecimal = round(massPercents[element], 3) valuePercent = round(valueDecimal * 100, 3) mpStr += element + ': (' + str(valuePercent) + '%) ' outputList = [['Molar Mass: ' + str(substance.molar_mass(u))], ['Mass %\'s: ' + str(mpStr)], ['Charge: ' + str(substance.charge)]] return outputList except: return [["Error: Something went wrong"]]
def formulas(self, output): labels = [] number_of_species = len(self.alpha) for i in range(1, number_of_species + 1): idx = number_of_species - i charge = number_of_species - (number_of_species + i - 1) if charge == 0: charge = '' elif charge == -1: charge = '-' else: pass if idx == 0: labels.append(f'B{charge}') elif idx == 1: labels.append(f'HB{charge}') else: labels.append(f'H{idx}B{charge}') if output == 'raw': return [formula.replace('B', 'A') for formula in labels] elif output == 'latex': temp = [ Substance.from_formula(formula).latex_name for formula in labels ] return [formula.replace('B', 'A') for formula in temp] elif output == 'html': temp = [ Substance.from_formula(formula).html_name for formula in labels ] return [formula.replace('B', 'A') for formula in temp] else: raise ValueError
def molar_mass_solute(idx_formula): """Calculates the molar mass for a chemical formula in a dataframe. Parameters ---------- idx_formula : int Integer representing an index in a dataframe Returns ------- float Molar mass for a chemical formula in a dataframe """ return Substance.from_formula(DF.iloc[idx_formula, 0]).mass
def atom_count_in_formula(formula, atom): """ Return the number of specified atom in the compound. Returns None if atom is not a recognized symbol Returns 0 if the atom is recognized, but not found in the compound """ substance = Substance.from_formula(formula) try: count = substance.composition.get(atomic_number(atom)) except (ValueError, AttributeError): warnings.warn(f"{atom} not found in list of elements") count = None else: if count is None: # Valid atom, but not in formula count = 0 return count
def __init__(self): nuclei = {"(NH4)2SO4": 1.0} accum = {"(NH4)2SO4": 1.0} coarse = {"(NH4)2SO4": 1.0} super().__init__( ionic_dissociation_phi={"(NH4)2SO4": 3}, molar_masses={ "(NH4)2SO4": Substance.from_formula("(NH4)2SO4").mass * si.gram / si.mole }, densities={"(NH4)2SO4": 1.77 * si.g / si.cm**3}, compounds=("(NH4)2SO4", ), is_soluble={"(NH4)2SO4": True}, ) self.modes = ( { "kappa": self.kappa(nuclei), "spectrum": spectra.Lognormal(norm_factor=1000.0 / si.cm**3, m_mode=0.008 * si.um, s_geom=1.6), }, { "kappa": self.kappa(accum), "spectrum": spectra.Lognormal(norm_factor=800 / si.cm**3, m_mode=0.034 * si.um, s_geom=2.1), }, { "kappa": self.kappa(coarse), "spectrum": spectra.Lognormal(norm_factor=0.72 / si.cm**3, m_mode=0.46 * si.um, s_geom=2.2), }, )
def __init__(self, Forg: float = 0.8, N: float = 400): mode = { "(NH4)2SO4": (1 - Forg), "apinene_dark": Forg, } super().__init__( compounds=("(NH4)2SO4", "apinene_dark"), molar_masses={ "(NH4)2SO4": Substance.from_formula("(NH4)2SO4").mass * si.gram / si.mole, "apinene_dark": 209 * si.gram / si.mole, }, densities={ "(NH4)2SO4": 1.77 * si.g / si.cm**3, "apinene_dark": 1.27 * si.g / si.cm**3, }, is_soluble={ "(NH4)2SO4": False, "apinene_dark": True, }, ionic_dissociation_phi={ "(NH4)2SO4": 3, "apinene_dark": 1, }, ) self.modes = ({ "f_org": 1 - self.f_soluble_volume(mode), "kappa": self.kappa(mode), "nu_org": self.nu_org(mode), "spectrum": spectra.Lognormal(norm_factor=N / si.cm**3, m_mode=50.0 * si.nm, s_geom=1.75), }, )
def test_as_per_substance_html_table(): substances = OrderedDict([(k, Substance.from_formula(k)) for k in 'H OH'.split()]) assert html(as_per_substance_html_table([2, 3], substances)).count('<tr>') == 3 assert html(as_per_substance_html_table({'H': 2, 'OH': 3}, substances)).count('<tr>') == 3
def Mass(name= 'O'): #Mole Mass Calculated by chempy return Substance.from_formula(name).mass
def test_Radioyltic__Reaction_html(): rate = Radiolytic([2.1*u.per100eV]) rxn = Reaction({}, {'H': 1}, rate) H = Substance.from_formula('H') html = rxn.html({'H': H}, with_param=True) assert html == ' → H; %s' % str(rate)