Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Epic 1 changes made to Ijob and commandline #246

Closed
wants to merge 1 commit into from
Closed
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
157 changes: 85 additions & 72 deletions MDANSE/Scripts/mdanse
Original file line number Diff line number Diff line change
Expand Up @@ -291,90 +291,103 @@ class CommandLineParser(optparse.OptionParser):
@type parser: instance of MDANSEOptionParser
'''

if len(parser.rargs) != 1:
raise CommandLineParserError("Invalid number of arguments for %r option" % opt_str)

jobs = REGISTRY["job"]

name = parser.rargs[0]

# A name for the template is built.
filename = os.path.abspath('template_%s.py' % name.lower())
jobs[name].save(filename)
if len(parser.rargs) != 1:
raise CommandLineParserError("Invalid number of arguments for %r option" % opt_str)

jobs = REGISTRY["job"]

name = parser.rargs[0]

try:
job_instance = jobs[name]
except KeyError:
raise CommandLineParserError("The job %r is not a valid MDANSE job" % name)

# Try to save the template for the job.
try:
jobs[name].save(filename)
# Case where an error occured when writing the template.
except IOError:
raise CommandLineParserError("Could not write the job template as %r" % filename)
# If the job class has no save method, thisis not a valid MDANSE job.
except KeyError:
raise CommandLineParserError("The job %r is not a valid MDANSE job" % name)
# Otherwise, print some information about the saved template.
else:
print("Saved template for job %r as %r" % (name, filename))
try:
# Serialize the job instance to JSON format
json_template = job_instance.to_json()

def save_job_template(self, option, opt_str, value, parser):
'''
Save job templates.

@param option: the option that triggered the callback.
@type option: optparse.Option instance

@param opt_str: the option string seen on the command line.
@type opt_str: str
# Define the filename for the JSON template
filename = os.path.abspath('template_%s.json' % name.lower())

# Write the JSON template to the file
with open(filename, 'w') as json_file:
json_file.write(json_template)

@param value: the argument for the option.
@type value: str
print("Saved template for job %r as %r" % (name, filename))

@param parser: the MDANSE option parser.
@type parser: instance of MDANSEOptionParser
'''
except IOError as e:
raise CommandLineParserError("Could not write the job template as %r: %s" % (filename, str(e)))
except Exception as e:
raise CommandLineParserError("An error occurred while saving the job template: %s" % str(e))

nargs = len(parser.rargs)

from MDANSE.Framework.Jobs.IJob import IJob
def save_job(self, option, opt_str, value, parser):
"""
Save job templates.

if nargs != 2:
print("Two arguments required resp. the name and the shortname of the class to be templated")
return
Args:
option: The option that triggered the callback.
opt_str: The option string seen on the command line.
value: The argument for the option.
parser: The MDANSE option parser.
"""

classname,shortname = parser.rargs
if len(parser.rargs) != 1:
raise CommandLineParserError("Invalid number of arguments for %r option" % opt_str)

try:
IJob.save_template(shortname,classname)
except (IOError,KeyError) as e:
LOGGER(str(e),'error',['console'])
return

if __name__ == "__main__":
jobs = REGISTRY["job"]
name = parser.rargs[0]

from MDANSE.__pkginfo__ import __version__, __date__
# Ensure the job class exists in the registry
if name not in jobs:
raise CommandLineParserError("The job %r is not a valid MDANSE job" % name)

# Creates the option parser.
parser = CommandLineParser(formatter=IndentedHelp(), version = 'MDANSE %s (%s)' % (__version__, __date__))
# Create a dictionary to represent the job
job_dict = {
"job_type": name,
"parameters": jobs[name].get_default_parameters() # Assuming get_default_parameters() returns a dictionary
}

# Creates a first the group of general options.
group = optparse.OptionGroup(parser, "General options")
group.add_option('-d', '--database', action='callback', callback=parser.display_element_info, help='Display chemical informations about a given element.')
group.add_option('-r', '--registry', action='callback', callback=parser.query_classes_registry, help='Display the contents of MDANSE classes registry.')
group.add_option('-t', '--traj', action='callback', callback=parser.display_trajectory_contents, help='Display the chemical contents of a trajectory.')
# Specify the filename for the saved job
filename = f"job_{name}.json"

# Add the goup to the parser.
parser.add_option_group(group)

# Creates a second group of job-specific options.
group = optparse.OptionGroup(parser, "Job managing options")
with open(filename, 'w') as json_file:
json.dump(job_dict, json_file, indent=4)

# Add the goup to the parser.
parser.add_option_group(group)
print(f"Saved template for job {name} as {filename}")


if __name__ == "__main__":
from MDANSE.__pkginfo__ import __version__, __date__

group.add_option('--jc', action='callback', callback=parser.check_job, help='Check the status of a given job.')
group.add_option('--jl', action='callback', callback=parser.display_jobs_list, help='Display the jobs list.')
group.add_option('--jr', action='callback', callback=parser.run_job, help='Run MDANSE job(s).')
group.add_option('--js', action='callback', callback=parser.save_job, help='Save a job script with default patameters.', metavar = "MDANSE_SCRIPT")
group.add_option('--jt', action='callback', callback=parser.save_job_template, help='Save a job template.', metavar = "MDANSE_SCRIPT")

# The command line is parsed.
options, _ = parser.parse_args()
# Create the option parser.
parser = CommandLineParser(formatter=IndentedHelp(), version='MDANSE %s (%s)' % (__version__, __date__))

# Create a group for general options.
general_options = optparse.OptionGroup(parser, "General options")
general_options.add_option('-d', '--database', action='callback', callback=parser.display_element_info,
help='Display chemical information about a given element.')
general_options.add_option('-r', '--registry', action='callback', callback=parser.query_classes_registry,
help='Display the contents of MDANSE classes registry.')
general_options.add_option('-t', '--traj', action='callback', callback=parser.display_trajectory_contents,
help='Display the chemical contents of a trajectory.')

# Add the general option group to the parser.
parser.add_option_group(general_options)

# Create a group for job-specific options.
job_options = optparse.OptionGroup(parser, "Job managing options")
job_options.add_option('--jc', action='callback', callback=parser.check_job, help='Check the status of a given job.')
job_options.add_option('--jl', action='callback', callback=parser.display_jobs_list, help='Display the jobs list.')
job_options.add_option('--jr', action='callback', callback=parser.run_job, help='Run MDANSE job(s).')
job_options.add_option('--js', action='callback', callback=parser.save_job,
help='Save a job script with default parameters.', metavar="MDANSE_SCRIPT")
job_options.add_option('--jt', action='callback', callback=parser.save_job_template, help='Save a job template.',
metavar="MDANSE_SCRIPT")

# Add the job-specific option group to the parser.
parser.add_option_group(job_options)

# The command line is parsed.
options, _ = parser.parse_args()
71 changes: 31 additions & 40 deletions MDANSE/Src/Framework/Jobs/IJob.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#
# **************************************************************************

import json
import abc
import glob
import os
Expand Down Expand Up @@ -156,47 +157,37 @@ def save(cls, jobFile, parameters=None):
#. jobFile (str): The name of the output job file.\n
#. parameters (dict): optional. If not None, the parameters with which the job file will be built.
"""

job_data = {
"job_type": cls._type,
"parameters": parameters if parameters else cls.get_default_parameters()
}

with open(jobFile, 'w') as json_file:
json.dump(job_data, json_file, indent=4)

f = open(jobFile, "w")

# The first line contains the call to the python executable. This is necessary for the file to
# be autostartable.
f.write("#!%s\n\n" % sys.executable)

# Writes the input file header.
f.write("########################################################\n")
f.write("# This is an automatically generated MDANSE run script #\n")
f.write("########################################################\n\n")

# Write the import.
f.write("from MDANSE import REGISTRY\n\n")

f.write("################################################################\n")
f.write("# Job parameters #\n")
f.write("################################################################\n\n")

# Writes the line that will initialize the |parameters| dictionary.
f.write("parameters = {}\n")

if parameters is None:
parameters = cls.get_default_parameters()

for k, v in sorted(parameters.items()):
f.write("parameters[%r] = %r\n" % (k, v))

f.write("\n")
f.write("################################################################\n")
f.write("# Setup and run the analysis #\n")
f.write("################################################################\n")
f.write("\n")

f.write('if __name__ == "__main__":\n')
f.write(" %s = REGISTRY[%r][%r]()\n" % (cls._type, "job", cls._type))
f.write(" %s.run(parameters,status=True)" % (cls._type))

f.close()

os.chmod(jobFile, stat.S_IRWXU)
@classmethod
def from_json(cls, filename):
"""
Load a job object from a JSON file.

Args:
filename (str): The name of the JSON file to load.

Returns:
IJob: An instance of the job class.
"""
with open(filename, 'r') as json_file:
job_data = json.load(json_file)

job_type = job_data["job_type"]
parameters = job_data["parameters"]

# Create an instance of the job class and set its parameters
job = cls()
job.set_parameters(parameters)

return job

def combine(self):
if self._status is not None:
Expand Down
Loading