Skip to content

Commit 63a221c

Browse files
authored
fix the error in the jumps calculation with minimal_residence (#369)
* there was an error in the jumps calculation and minimal_residence was not taken into account, now it is * fix the jumps test to reflect the fixed function * fix jumps plot, and add error when there are zero jumps * fix jumps_test
1 parent 2a1ce72 commit 63a221c

File tree

2 files changed

+55
-55
lines changed

2 files changed

+55
-55
lines changed

src/gemdat/jumps.py

Lines changed: 51 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -38,60 +38,52 @@ def _generic_transitions_to_jumps(
3838
events = events.rename(columns={'time': 'start time'})
3939

4040
jumps = []
41-
fromevent = None
42-
candidate_jump = None
43-
44-
for _, event in events.iterrows():
45-
# If we are jumping, but we go to the next atom index, reset
46-
if fromevent is not None:
47-
if fromevent['atom index'] != event['atom index']:
48-
fromevent = None
49-
50-
# If we have a candidate jump, we must make sure it remains on the site
51-
# for minimal_residence timesteps, this is that check, add it to the jumps
52-
# if it passes
53-
if candidate_jump is not None:
54-
if candidate_jump['atom index'] != event['atom index']:
55-
jumps.append(candidate_jump)
56-
candidate_jump = None
57-
elif event['start time'] - candidate_jump['stop time'] >= minimal_residence:
58-
jumps.append(candidate_jump)
59-
candidate_jump = None
60-
fromevent = None
61-
elif candidate_jump['destination site'] != event['destination site']:
62-
candidate_jump = None
63-
64-
# Specify the start of a jump if we encounter one
65-
if event['start site'] != -1:
66-
if event['start site'] != event['destination site']:
67-
fromevent = event
68-
69-
if fromevent is not None:
70-
# if we jump back, remove fromevent
71-
if fromevent['start site'] == event['destination site']:
72-
fromevent = None
73-
candidate_jump = None
74-
continue
75-
76-
# Check if jump to the inner site, add it to the jumps immediately
77-
if event['destination inner site'] != -1:
78-
event['start site'] = fromevent['start site']
79-
event['start time'] = fromevent['start time']
80-
fromevent = None
81-
candidate_jump = None
82-
jumps.append(event)
83-
continue
84-
85-
# If we enter another site, create a candidate jump
86-
if candidate_jump is None:
87-
if event['destination site'] != -1:
41+
42+
atom_events = [atomevents for i, atomevents in events.groupby('atom index')]
43+
44+
for events in atom_events:
45+
fromevent = None
46+
candidate_jump = None
47+
48+
for _, event in events.iterrows():
49+
# We have a previous jump, but must still determine
50+
# if it stays on the site long enough
51+
if candidate_jump is not None:
52+
if event['start time'] - candidate_jump['start time'] >= minimal_residence:
53+
jumps.append(candidate_jump)
54+
candidate_jump = None
55+
# it moves to early! dont add the jump
56+
elif candidate_jump['destination site'] != event['destination site']:
57+
candidate_jump = None
58+
59+
# Identify a transition away from a site, name it fromevent
60+
if event['start site'] != -1:
61+
if event['start site'] != event['destination site']:
62+
fromevent = event
63+
64+
if fromevent is not None:
65+
# jump to same site is no jump
66+
if event['destination site'] == fromevent['start site']:
67+
fromevent = None
68+
candidate_jump = None
69+
70+
# jump to another inner site is definitely jump
71+
elif event['destination inner site'] != -1:
72+
event['start site'] = fromevent['start site']
73+
event['start time'] = fromevent['start time']
74+
jumps.append(event)
75+
fromevent = None
76+
candidate_jump = None
77+
78+
# jump to another site is a candidate_event
79+
elif event['destination site'] != fromevent['destination site']:
8880
event['start site'] = fromevent['start site']
8981
event['start time'] = fromevent['start time']
9082
candidate_jump = event
83+
fromevent = None
9184

92-
# Also add a last candidate jump (if there is one
93-
if candidate_jump is not None:
94-
jumps.append(candidate_jump)
85+
if len(jumps) == 0:
86+
raise ValueError('No jumps found')
9587

9688
jumps = pd.DataFrame(data=jumps)
9789

@@ -134,6 +126,7 @@ def __init__(
134126
self.sites = transitions.sites
135127
self.conversion_method = conversion_method
136128
self.data = conversion_method(transitions, minimal_residence=minimal_residence)
129+
self.minimal_residence = minimal_residence
137130

138131
@property
139132
def n_jumps(self) -> int:
@@ -408,7 +401,14 @@ def split(self, n_parts: int) -> list[Jumps]:
408401
"""
409402
parts = self.transitions.split(n_parts)
410403

411-
return [Jumps(part, conversion_method=self.conversion_method) for part in parts]
404+
return [
405+
Jumps(
406+
part,
407+
conversion_method=self.conversion_method,
408+
minimal_residence=self.minimal_residence,
409+
)
410+
for part in parts
411+
]
412412

413413
@weak_lru_cache()
414414
def rates(self, n_parts: int = 10) -> pd.DataFrame:

tests/integration/jumps_test.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,14 @@ def test_site_inner_fraction(self, vasp_traj, structure):
2020
)
2121
jumps = Jumps(transitions=transitions, minimal_residence=100)
2222

23-
assert len(jumps.data) == 267
23+
assert len(jumps.data) == 258
2424
assert np.all(
2525
jumps.data[::100].to_numpy()
2626
== np.array(
2727
[
28-
[0, 94, 0, 282, 303],
29-
[15, 74, 8, 1271, 1286],
30-
[34, 49, 33, 3141, 3296],
28+
[0, 0, 94, 385, 442],
29+
[16, 34, 42, 3268, 3298],
30+
[36, 19, 11, 1763, 1789],
3131
]
3232
)
3333
)

0 commit comments

Comments
 (0)