Skip to content
Open
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
13 changes: 12 additions & 1 deletion lammps_logfile/File.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ def __init__(self, ifile):
self.keywords = []
self.output_before_first_run = ""
self.partial_logs = []
self.num_timesteps = []
if hasattr(ifile, "read"):
self.logfile = ifile
else:
Expand All @@ -35,6 +36,11 @@ def read_file_to_dict(self):
if before_first_run_flag:
self.output_before_first_run += line

if line.startswith("run "):
splitted = line.split()
if splitted[1].isdigit():
self.num_timesteps.append(int(splitted[1]))

if keyword_flag:
keywords = line.split()
tmpString = ""
Expand All @@ -47,7 +53,7 @@ def read_file_to_dict(self):
line = contents[i]
else:
break
partialLogContents = pd.read_table(StringIO(tmpString), sep=r'\s+')
partialLogContents = pd.read_table(StringIO(tmpString), sep=r'\s+', error_bad_lines=False)

if (self.keywords != keywords):
# If the log keyword changes, i.e. the thermo data to be outputted chages,
Expand Down Expand Up @@ -123,3 +129,8 @@ def to_exdir_group(self, name, exdirfile):

def get_num_partial_logs(self):
return len(self.partial_logs)


def get_num_timesteps(self):
"""Return list of number of timesteps for each partial log."""
return self.num_timesteps
69 changes: 53 additions & 16 deletions lammps_logfile/cmd_interface.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,29 +2,66 @@
from lammps_logfile import running_mean
import argparse
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation

def get_parser():
parser = argparse.ArgumentParser(description="Plot contents from lammps log files")
parser.add_argument("input_file", type=str, help="Lammps log file containing thermo output from lammps simulation.")
parser.add_argument("-x", type=str, default="Time", help="Data to plot on the first axis")
parser.add_argument("-x", type=str, default="Time", help="Data to plot on the first axis.")
parser.add_argument("-y", type=str, nargs="+", help="Data to plot on the second axis. You can supply several names to get several plot lines in the same figure.")
parser.add_argument("-a", "--running_average", type=int, default=1, help="Optionally average over this many log entries with a running average. Some thermo properties fluctuate wildly, and often we are interested in te running average of properties like temperature and pressure.")
parser.add_argument("-a", "--running_average", type=int, default=1, help="Optionally average over this many log entries with a running average. Some thermo properties fluctuate wildly, and often we are interested in the running average of properties like temperature and pressure.")
parser.add_argument("-s", "--subplots", default=False, action='store_true', help="Show subplot panels for different graphs.")
parser.add_argument("-p", "--progress", default=False, action='store_true', help="Show progress of simulation. This requires that 'Step' is written to log file.")
parser.add_argument("-l", "--live", default=False, action='store_true', help="Show live visualisation of graphs. This is useful when monitoring thermo outputs during simulation.")
return parser


def create_progress_string(log):
"""Returning string with progress"""
try:
steps = log.get("Step")
except:
raise ValueError("'Step' is not written to logfile! Not able to monitor progress.")
rel_step = int(steps[-1] - steps[0])
num_steps = log.num_timesteps[-1]
return f"{rel_step}/{num_steps}"


def run():
args = get_parser().parse_args()
log = File(args.input_file)
x = log.get(args.x)
print(x)
for y in args.y:
data = log.get(y)
print(data)

if args.running_average >= 2:
x = running_mean(x, args.running_average)
data = running_mean(data, args.running_average)

plt.plot(x, data, label=y)
plt.legend()
plt.show()
if args.subplots:
fig, ax = plt.subplots(len(args.y), sharex=True, squeeze=False)
else:
fig = plt.figure()

def get_data(i=0):
log = File(args.input_file)
x = log.get(args.x)
#print(x)
plt.cla()
for i, y in enumerate(args.y):
data = log.get(y)
#print(data)

if args.running_average >= 2:
x = running_mean(x, args.running_average)
data = running_mean(data, args.running_average)

if args.subplots:
ax[i, 0].cla()
ax[i, 0].plot(x, data)
ax[-1, 0].set_xlabel(args.x)
ax[i, 0].set_ylabel(y)
else:
plt.plot(x, data, label=y)
plt.legend()
if args.progress:
fig.suptitle(create_progress_string(log))
plt.tight_layout(rect=[0, 0.03, 1, 0.95])

if args.live:
ani = FuncAnimation(fig, get_data, interval=1000)
else:
get_data()
plt.show()