def anim(sername, simname): sim = Simulation(sername, simname) # https://github.com/matplotlib/matplotlib/issues/16965 anim_fn = os.path.join(CACHEDIR, "graphics", sername, simname, f"{simname}.gif") os.makedirs(os.path.dirname(anim_fn), exist_ok=True) base_fn = sim.data_fn() if flask.request.values.get("maxind"): max_data_index = int(flask.request.values.get("maxind")) else: max_data_index = sim.status()['dataFileCounter'] datafiles = [f"{base_fn}.{ind}" for ind in range(max_data_index)] if (flask.request.values.get("nocache") or need_to_regenerate(anim_fn, datafiles)): ani = create_animation(sername, simname, maxframes=max_data_index, samplesize=3000) ani.save(anim_fn, writer="imagemagick") # ani.save(anim_fn, writer="ffmpeg") if flask.request.values.get("format") == "webm": clip = mp.VideoFileClip(anim_fn) webm_fn = f"{anim_fn}.webm" clip.write_videofile(webm_fn) with open(webm_fn, "rb") as webm_f: return Response(webm_f.read(), mimetype="video/webm") else: with open(anim_fn, "rb") as anim_f: return Response(anim_f.read(), mimetype="image/gif")
def showdataplot_page(sername, simname, ind): """A page that contains a .data file's plot.""" sim = Simulation(sername, simname) simstatus = sim.status() max_data_index = simstatus['dataFileCounter'] - 1 data_df, dimensions, headline = read_data_file(sim.data_fn(ind)) num, time, xmin, ymin, zmin, xmax, ymax, zmax = headline if dimensions == 2: return render_template("results/data2d_plot.html", sername=sername, simname=simname, ind=ind, time=time, dt=simstatus['timeStep'] * simstatus['dataFileSaveCount'], lines=data_df, mdi=max_data_index) elif dimensions == 3: return render_template("results/data3d_plot.html", sername=sername, simname=simname, ind=ind, time=time, dt=simstatus['timeStep'] * simstatus['dataFileSaveCount'], lines=data_df, mdi=max_data_index) else: raise ValueError("Number of dimensions should be 2 or 3.")
def serve_restart_raw(sername, simname, ind): """Serve a raw .restart. file.""" sim = Simulation(sername, simname) restart_fn = sim.restart_fn(ind) if not os.path.isfile(restart_fn): restart_fn = sim.restart_fn() restart_f = open(restart_fn, "r") return Response(restart_f.read(), mimetype="text/plain")
class AnimatedScatter(object): """An animated scatter plot using matplotlib.animations.FuncAnimation.""" # https://stackoverflow.com/questions/9401658/how-to-animate-a-scatter-plot def __init__(self, sername, simname, maxframes, samplesize): self.sername = sername self.simname = simname self.sim = Simulation(sername, simname) self.samplesize = samplesize # self.stream = self.data_stream() # Setup the figure and axes... self.fig = plt.Figure(figsize=(12, 6)) self.ax = self.fig.add_subplot(1, 1, 1) # Then setup FuncAnimation. self.ani = FuncAnimation(self.fig, self.update, interval=5, frames=maxframes, init_func=self.setup_plot, blit=True) def setup_plot(self): """Initial drawing of the scatter plot.""" x, y, s, c = [], [], [], [] self.scat = self.ax.scatter(x, y, c=c, s=s, vmin=0, vmax=1, cmap="jet", edgecolor="k") # self.ax.axis([-10, 10, -10, 10]) # For FuncAnimation's sake, we need to return the artist we'll be using # Note that it expects a sequence of artists, thus the trailing comma. return self.scat, def update(self, ind): """Update the scatter plot.""" # data = next(self.stream) data_fn = self.sim.data_fn(ind) print(ind) print(data_fn) data_df, dimensions, headline = read_data_file(data_fn) num, time, xmin, ymin, zmin, xmax, ymax, zmax = headline self.ax.set_xlim((xmin, xmax)) self.ax.set_ylim((ymin, ymax)) self.scat = self.ax.scatter(data_df.x, data_df.y, s=np.sqrt(data_df.r), c=data_df.sp, cmap=plt.get_cmap("viridis", 3), vmin=0, vmax=2) # We need to return the updated artist for FuncAnimation to draw.. # Note that it expects a sequence of artists, thus the trailing comma. return self.scat,
def __init__(self, sername, simname, maxframes, samplesize): self.sername = sername self.simname = simname self.sim = Simulation(sername, simname) self.samplesize = samplesize # self.stream = self.data_stream() # Setup the figure and axes... self.fig = plt.Figure(figsize=(12, 6)) self.ax = self.fig.add_subplot(1, 1, 1) # Then setup FuncAnimation. self.ani = FuncAnimation(self.fig, self.update, interval=5, frames=maxframes, init_func=self.setup_plot, blit=True)
def animate(ind): sim = Simulation(sername, simname) data_fn = sim.data_fn(ind) data_df, dimensions, headline = read_data_file(data_fn) num, time, xmin, ymin, zmin, xmax, ymax, zmax = headline if samplesize: try: data_df = data_df.sample(n=samplesize) except ValueError: pass ax.set_xlim([xmin, xmax]) ax.set_ylim([ymin, ymax]) pts = [(p.x, p.y) for p in data_df.itertuples()] path_collection.set_offsets(pts) path_collection.set_sizes(np.sqrt(data_df.r)) path_collection.set_array(data_df.sp) return path_collection,
def ene_plot_figview(sername, simname): """A plot of a .ene file, in PNG format.""" sim = Simulation(sername, simname) ene_fn = sim.ene_fn() eneplot_fn = os.path.join(CACHEDIR, "graphics", sername, simname, f"{simname}.ene.png") if (flask.request.values.get("nocache") or need_to_regenerate(eneplot_fn, [ene_fn])): logging.info("Generating a new image") os.makedirs(os.path.dirname(eneplot_fn), exist_ok=True) fig = create_ene_figure(ene_fn) FigureCanvas(fig).print_png(eneplot_fn) else: logging.info("Serving a cached image") with open(eneplot_fn, "rb") as eneplot_f: return Response(eneplot_f.read(), mimetype='image/png')
def data_plot_figview(sername, simname, ind): """A plot of a .data file, in PNG format by default.""" sim = Simulation(sername, simname) format = flask.request.values.get("format", "png") if format not in ["png", "svg", "pdf"]: raise NotImplementedError data_fn = sim.data_fn(ind) dataplot_fn = os.path.join(CACHEDIR, "graphics", sername, simname, f"{simname}.data.{ind}.{format}") logging.info("Generating a new image") os.makedirs(os.path.dirname(dataplot_fn), exist_ok=True) fig = create_data_figure(data_fn, **floatify(flask.request.values)) fig.savefig(dataplot_fn, format=format) with open(dataplot_fn, "rb", buffering=0) as dataplot_f: return Response(dataplot_f.read(), mimetype=MIMETYPE[format])
def depth_plot_figview(sername, simname, ind): sim = Simulation(sername, simname) data_fn = sim.data_fn(ind) format = flask.request.values.get("format", default="png") if format not in ["png", "svg", "pdf"]: raise NotImplementedError plot_fn = os.path.join(CACHEDIR, "graphics", sername, simname, ".".join([simname, "depth", ind, format])) logging.info(plot_fn) logging.info("Generating a new image") os.makedirs(os.path.dirname(plot_fn), exist_ok=True) fig = plot_depth(data_fn, **floatify(flask.request.values)) with NamedTemporaryFile(suffix="." + format) as ntf: fig.savefig(ntf, format=format) ntf.seek(0) return Response(ntf.read(), mimetype=MIMETYPE[format])
def cg_plot_figview(sername, simname, ind, field): if field not in {"depth", "rho", "px", "py", "u", "v"}: raise NotImplementedError format = flask.request.values.get("format", "png") if format not in ["png", "svg", "pdf"]: raise NotImplementedError sim = Simulation(sername, simname) data_fn = sim.data_fn(ind) logging.info("Generating new CG plots") cgfigs = plot_all_cg_fields(data_fn, kernel_width=0.4, **floatify(flask.request.values)) with TemporaryDirectory() as td: fn = os.path.join(td, ".".join([simname, field, ind, format])) cgfigs[field].savefig(fn, format=format) with open(fn, "rb", buffering=0) as plot_f: return Response(plot_f.read(), mimetype=MIMETYPE[format])
def showdatafile(sername, simname, ind): sim = Simulation(sername, simname) simstatus = sim.status() max_data_index = simstatus['dataFileCounter'] - 1 max_fstat_index = simstatus['fStatFileCounter'] - 1 ind = int(ind) if ind > max_data_index: return f"The index {ind} is greater than the maximum index {max_data_index} so far", 400 try: data_df, dimensions, headline = read_data_file(sim.data_fn(ind)) except FileNotFoundError: return f"{sim.data_fn(ind)} not found" num, time, xmin, ymin, zmin, xmax, ymax, zmax = headline if dimensions == 2: return render_template("results/data2d.html", sername=sername, simname=simname, ind=ind, time=time, dt=simstatus['timeStep'] * simstatus['dataFileSaveCount'], lines=data_df, mdi=max_data_index) if dimensions == 3: return render_template("results/data3d.html", sername=sername, simname=simname, ind=ind, time=time, dt=simstatus['timeStep'] * simstatus['dataFileSaveCount'], lines=data_df, mdi=max_data_index)
def simulation_view(sername, simname): """Serve a page showing some summary statistics of this simulation, as well as links to more details such as individual files, and logs. """ sim = Simulation(sername, simname) if not os.path.isdir(sim.simdir()): raise SimulationNotFoundError(sername, simname) simstatus = sim.status() print(simstatus) max_data_index = simstatus['dataFileCounter'] - 1 print(max_data_index) max_fstat_index = simstatus['fStatFileCounter'] - 1 return render_template('simulation.html', sername=sername, simname=simname, simstatus=simstatus, dt=simstatus['timeStep'] * simstatus['dataFileSaveCount'], mdi=max_data_index, mfi=max_fstat_index, ind=0)
def get_available_simulations(series_name: str) -> List[Simulation]: """List the simulations under the specified series. """ serdir = os.path.join(DPMDIR, series_name) if not os.path.isdir(serdir): raise SeriesNotFoundError simulation_names = [ d for d in os.listdir(serdir) if (os.path.isdir(os.path.join(serdir, d)) and os.path.isfile(os.path.join(serdir, d, f"{d}.config"))) ] simulations = [ Simulation(series_name, label) for label in sorted(simulation_names) ] return simulations
def start_job(job_id: int) -> subprocess.Popen: job = Job.query.get_or_404(job_id) driver, series, label, config = job.driver, job.series, job.label, job.config # Create a directory for the simulation sim = Simulation(series, label) simdir = sim.simdir() try: os.mkdir(simdir) except PermissionError as e: raise e # TODO except FileExistsError as e: raise SimulationAlreadyExistsError(series, label, driver) # Put the uploaded config file there saveto = sim.config_fn() if os.path.exists(saveto): raise SimulationAlreadyExistsError(series, label, driver) with open(saveto, "w") as fp: fp.write(config) logging.info(f"Saved config file to {saveto}") # Queue the simulation executable = os.path.join(DPMDIR, driver) stdout_f = open(sim.out_fn(), "a") stderr_f = open(sim.err_fn(), "a") command = [executable, saveto, "-name", label] print(command) subp = subprocess.Popen(['echo'] + command, cwd=simdir, stdout=stdout_f, stderr=stderr_f) job.status = 1 db.session.commit() return subp
def serve_data_raw(sername, simname, ind): """Serve a raw .data. file.""" sim = Simulation(sername, simname) dat_fn = sim.data_fn(ind) dat_f = open(dat_fn, "r") return Response(dat_f.read(), mimetype="text/plain")
def serve_ene_raw(sername, simname): """Serve a raw .ene file.""" sim = Simulation(sername, simname) ene_fn = sim.ene_fn() with open(ene_fn) as ene_f: return Response(ene_f.read(), mimetype="text/plain")
def showlogerr(sername, simname): sim = Simulation(sername, simname) with open(sim.err_fn(), "r") as err_f: return Response(err_f.read(), mimetype="text/plain")
def showconfig(sername, simname): sim = Simulation(sername, simname) with open(sim.config_fn(), "r") as config_f: return Response(config_f.read(), mimetype="text/plain")
def serve_fstat_raw(sername, simname, ind): """Serve a raw .fstat. file.""" sim = Simulation(sername, simname) fstat_fn = sim.fstat_fn(ind) fstat_f = open(fstat_fn, "r") return Response(fstat_f.read(), mimetype="text/plain")