Skip to content

Commit 354587e

Browse files
ehhartmannEric Hartmann
and
Eric Hartmann
authored
calculate sampling time for averaging and improve logging (#524)
* calculate sampling time for averaging and improve logging * adjust tests to changes from sum to mean --------- Co-authored-by: Eric Hartmann <hartmaec@rh05659.villa-bosch.de>
1 parent fcde68d commit 354587e

File tree

2 files changed

+58
-16
lines changed

2 files changed

+58
-16
lines changed

src/kimmdy/kmc.py

+54-12
Original file line numberDiff line numberDiff line change
@@ -133,23 +133,36 @@ def rf_kmc(
133133
reaction_probability = []
134134

135135
# 1. Calculate the probability for each reaction
136+
# get overall sampling time
137+
# TODO: Can be replaced if we parse mdps for the simulation time
138+
t_min = recipe_collection.recipes[0].timespans[0][0]
139+
t_max = recipe_collection.recipes[0].timespans[0][1]
140+
for recipe in recipe_collection.recipes:
141+
for ts in recipe.timespans:
142+
t1 = ts[0]
143+
t2 = ts[1]
144+
t_min = t1 if t1 < t_min else t_min
145+
t_max = t2 if t2 > t_max else t_max
146+
sampling_time = t_max - t_min
147+
logger.debug(f"Sampling time: {sampling_time}ps")
148+
136149
for recipe in recipe_collection.recipes:
137150
dt = [x[1] - x[0] for x in recipe.timespans]
138-
reaction_probability.append(sum(np.multiply(dt, recipe.rates)))
151+
reaction_probability.append(sum(np.multiply(dt, recipe.rates)) / sampling_time)
139152

140153
# 2. Set the total rate to the sum of individual rates
141-
probability_cumulative = np.cumsum(reaction_probability)
142-
probability_sum = probability_cumulative[-1]
154+
rate_cumulative = np.cumsum(reaction_probability)
155+
total_rate = rate_cumulative[-1]
143156

144157
# 3. Generate two independent uniform (0,1) random numbers u1,u2
145158
u = rng.random(2)
146159
logger.debug(
147-
f"\tRandom values u: {u}, number cumulative probabilities "
148-
f"{len(probability_cumulative)}, probability sum {probability_sum}"
160+
f"\tRandom values u: {u}, number cumulative rates "
161+
f"{len(rate_cumulative)}, total rate {total_rate}"
149162
)
150163

151164
# 4. Find the even to carry out, mu, using binary search (np.searchsorted)
152-
pos = np.searchsorted(probability_cumulative, u[0] * probability_sum)
165+
pos = np.searchsorted(rate_cumulative, u[0] * total_rate)
153166
recipe: Recipe = recipe_collection.recipes[pos]
154167
time_index = np.argmax(recipe.rates)
155168
reaction_time = recipe.timespans[time_index][1]
@@ -158,10 +171,8 @@ def rf_kmc(
158171
)
159172

160173
# 5. Calculate the time step associated with uu
161-
time_delta = np.log(1 / u[1]) / probability_sum
162-
logger.info(
163-
f"Time delta: {time_delta} ps with cumulative probability: {probability_sum}"
164-
)
174+
time_delta = np.log(1 / u[1]) / total_rate
175+
logger.info(f"Time delta: {time_delta} ps with total rate: {total_rate}")
165176

166177
return KMCAccept(
167178
recipe=recipe,
@@ -213,11 +224,27 @@ def frm(
213224
# 1. Generate M independent uniform (0,1) random numbers
214225
u = rng.random(len(recipe_collection.recipes))
215226
# 2. Calculate the cumulative probabilities for each event
227+
# get overall sampling time
228+
# TODO: Can be replaced if we parse mdps for the simulation time
229+
t_min = recipe_collection.recipes[0].timespans[0][0]
230+
t_max = recipe_collection.recipes[0].timespans[0][1]
231+
for recipe in recipe_collection.recipes:
232+
for ts in recipe.timespans:
233+
t1 = ts[0]
234+
t2 = ts[1]
235+
t_min = t1 if t1 < t_min else t_min
236+
t_max = t2 if t2 > t_max else t_max
237+
sampling_time = t_max - t_min
238+
logger.debug(f"Sampling time: {sampling_time}ps")
239+
216240
for i, recipe in enumerate(recipe_collection.recipes):
217241
dt = [x[1] - x[0] for x in recipe.timespans]
218242
cumulative_probability = np.cumsum(
219243
list(map(lambda x, y: x * y, dt, recipe.rates))
220244
)
245+
cumulative_probability = (
246+
cumulative_probability / sampling_time
247+
) # calculate mean instead of sum
221248
reaction_probability.append(cumulative_probability[-1])
222249
# 3. For each event k, find the time until the this reaction takes place tau_k,
223250
# if it is during the time when the propensities are defined (simulation time)
@@ -534,9 +561,24 @@ def multi_rfkmc(
534561
reaction_probability = []
535562

536563
# 1. Calculate the probability for each reaction
537-
for recipe in recipes:
564+
# get overall sampling time
565+
# TODO: Can be replaced if we parse mdps for the simulation time
566+
t_min = recipe_collection.recipes[0].timespans[0][0]
567+
t_max = recipe_collection.recipes[0].timespans[0][1]
568+
for recipe in recipe_collection.recipes:
569+
for ts in recipe.timespans:
570+
t1 = ts[0]
571+
t2 = ts[1]
572+
t_min = t1 if t1 < t_min else t_min
573+
t_max = t2 if t2 > t_max else t_max
574+
sampling_time = t_max - t_min
575+
logger.debug(f"Sampling time: {sampling_time}ps")
576+
577+
for recipe in recipe_collection.recipes:
538578
dt = [x[1] - x[0] for x in recipe.timespans]
539-
reaction_probability.append(sum(np.multiply(dt, recipe.rates)))
579+
reaction_probability.append(
580+
sum(np.multiply(dt, recipe.rates)) / sampling_time
581+
)
540582

541583
# 2. Set the total rate to the sum of individual rates
542584
probability_cumulative = np.cumsum(reaction_probability)

tests/test_kmc.py

+4-4
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,8 @@ def reference_KMC() -> KMCAccept:
3636
recipe=Recipe(
3737
[Bind(2, 3)], rates=[0.12, 0.0], timespans=[(0.0, 6.0), (6.0, 10.0)]
3838
),
39-
time_delta=0.04032167624965666,
40-
reaction_probability=[0.0, 0.72, 0.54, 0.0],
39+
time_delta=0.4032167624965666,
40+
reaction_probability=[0.0, 0.072, 0.054, 0.0],
4141
time_start=0,
4242
time_start_index=0,
4343
)
@@ -51,8 +51,8 @@ def reference_multi2_KMC() -> KMCAccept:
5151
rates=[0.12, 0.0, 0.15, 0.06],
5252
timespans=[(0.0, 6.0), (6.0, 10.0), (2.0, 4.0), (4.0, 8.0)],
5353
),
54-
time_delta=0.09762211196506274,
55-
reaction_probability=[0.0, 0.72, 0.54, 0.0],
54+
time_delta=0.7809768957205019,
55+
reaction_probability=[0.0, 0.072, 0.054, 0.0],
5656
time_start=6.0,
5757
time_start_index=0,
5858
)

0 commit comments

Comments
 (0)