Source code for pycif.plugins.models.lmdz_old.compile
import numpy as np
from pathlib import Path
import os
import subprocess
import shutil
import re
from logging import info, debug
[docs]
def compile(self):
# Copying the executables
comp_dir = "{}/model/".format(self.workdir)
try:
# If force-recompile = True, return IOError to avoid copying
if getattr(self, "force-recompile"):
raise IOError
# copying the executable
target = "{}/dispersion.e".format(comp_dir)
shutil.copy(self.fileexec, target)
# Keep in memory from where the executable was copied
with open("{}/README".format(comp_dir), "w") as f:
f.write("DISPERSION was copied from: {}".format(self.fileexec))
return
except IOError as e:
if not getattr(self, "auto-recompile"):
raise Exception(
"LMDZ could not find executables ({}) and was not asked to "
"compile them; specify auto-recompile = True in Yaml to do so"
.format(self.fileexec)
)
# Otherwise, re-compile
# Copying sources locally; overwrite folder if exists
if os.path.isdir("{}/sources".format(comp_dir)):
shutil.rmtree("{}/sources".format(comp_dir))
dir_sources = self.dir_sources if self.dir_sources != "" \
else os.path.dirname(self.fileexec)
# Check that the path is consistent with DISPERSION sources
if self.dir_sources != "" and not os.path.isdir(self.dir_sources):
raise Exception(
f"WARNING! Trying to compile DISPERSION from the following non existing "
f"folder: {self.dir_sources}"
)
elif self.dir_sources == "" and not os.path.dirname(self.fileexec):
raise Exception(
f"Warning! Trying to compile DISPERSION from the non-existing "
f"directory {dir_sources}, inferred from fileexec ({self.fileexec}). \n"
f"Please consider forcing a path to the sources with the argument "
f"'dir_sources' in your yml. \n The source path should include the files and "
f"folders: 'compile_dispersion', 'makefile.sef', 'libf', etc."
)
list_sources = os.listdir(dir_sources)
check_files = ["makefile.sed", "libf", "compile_dispersion", "def"]
if not np.all([f in list_sources for f in check_files]):
raise Exception(
f"WARNING! Try to compile DISPERSION from the following path: "
f"{dir_sources}. \n"
f"The path is not consistent with expected source directory. \n"
f"Please consider forcing a path to the sources with the argument "
f"'dir_sources' in your yml\n The source path should include the files and "
f"folders: 'compile_dispersion', 'makefile.sef', 'libf', etc."
)
shutil.copytree(
dir_sources,
"{}/sources".format(comp_dir),
ignore=shutil.ignore_patterns("*.a"),
)
# Now compile LMDZ
debug("Compiling LMDZ")
domain = self.domain
with open("{}/LMDZ_compiling.log".format(comp_dir), "w") as log:
process = subprocess.Popen(
f"./compile_dispersion "
f"-d {domain.nlon - 1}x{domain.nlat - 1}x{domain.nlev} "
f"-p {self.nfilun}x{self.nfilus} "
f"{'-c' if getattr(self, 'compile-clean') else ''} "
f"{'--debug' if getattr(self, 'compile-mode') == 'DEBUG' else ''}"
f"{'--gfortran' if self.compiler == 'gfortran' else ''}",
shell=True,
stdout=log,
cwd="{}/sources/".format(comp_dir),
stderr=subprocess.PIPE,
)
_, stderr = process.communicate()
# Print errors if no executable created (or if forced to)
exe_file = "{}/sources/dispersion.e".format(comp_dir)
if not os.path.isfile(exe_file) \
or getattr(self, "force-compile-stderr"):
debug("LMDZ returned errors during compiling.")
debug("There might be some bugs in the Fortran or in the "
"libraries loaded in the system:")
debug("### START OF LMDZ ERROR MESSAGE ###")
for ln in stderr.decode().split("\n"):
debug(ln)
debug("### END OF LMDZ ERROR MESSAGE ###")
# Copy executable at model root directory
shutil.copy(exe_file, comp_dir)