job.py 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. import os
  2. import sys
  3. import glob
  4. from auto_namd.functions import *
  5. from auto_namd.simulation import Simulation
  6. class Job:
  7. """
  8. A class that represents a job/system residing in a unique directory path
  9. Attributes:
  10. self.path = absolute job directory path
  11. self.name = name of the job, derived from parent directory
  12. self.prefix = self.path + self.name
  13. self.pdb = latest .pdb file
  14. self.psf = latest .psf file
  15. self.coor = latest .coor file
  16. self.stage = current simulation stage
  17. self.step = current simulation steps
  18. """
  19. def __init__(self, path):
  20. self.path = path
  21. self.name = self.get_job_name()
  22. self.prefix = os.path.join(self.path, self.name)
  23. self.pdb, self.psf = self.get_pdb_and_psf()
  24. self.stage, self.step, self.coor = self.get_stage()
  25. def get_job_name(self):
  26. '''Get job name from path'''
  27. name = os.path.basename(self.path)
  28. return name
  29. def get_pdb_and_psf(self):
  30. pdb = glob.glob(f'{self.prefix}*_solv_ion.pdb')
  31. psf = glob.glob(f'{self.prefix}*_solv_ion.psf')
  32. if len(pdb) == 1 and len(psf) == 1:
  33. return pdb[0], psf[0]
  34. pdb = glob.glob(f'{self.prefix}.pdb')
  35. psf = glob.glob(f'{self.prefix}.psf')
  36. if len(pdb) == 1 and len(psf) == 1:
  37. return pdb[0], psf[0]
  38. else:
  39. print('No PDB or PSF files found, exiting...')
  40. sys.exit(1)
  41. def get_stage(self):
  42. coors_path = self.prefix + '*.coor'
  43. coors = glob.glob(coors_path)
  44. coors.sort(key=natural_key)
  45. if len(coors) >= 1:
  46. coor = coors[-1]
  47. stage = coor.split('_')[-2].split('.')[0]
  48. step = int(coor.split('_')[-1].split('.')[0])
  49. else:
  50. coor = ''
  51. stage = ''
  52. step = 0
  53. return stage, int(step), coor
  54. # allow the Simulation class to instantiate via the simulate() method
  55. def simulate(self, ffs_path, steps, namdbin, params):
  56. Simulation(self, ffs_path, steps, namdbin, params)
  57. def info(self):
  58. print(f'Job Path: {self.path}\n'
  59. f'Name: {self.name}\n'
  60. f'Working PDB: {self.pdb}\n'
  61. f'Working PSF: {self.psf}\n'
  62. f'Previous Step: {self.stage}\n'
  63. f'Previous Step Number: {str(self.step)}\n'
  64. )
  65. """Job control"""
  66. def get_next_job(jobs_path):
  67. jobs_path = san_path(jobs_path)
  68. job_dirs_l = get_jobs_from_path(jobs_path)
  69. jobs = create_job_instances(job_dirs_l)
  70. next_job = get_youngest_job(jobs)
  71. return next_job
  72. def get_jobs_from_path(jobs_path):
  73. # Only return job paths with a pdb file
  74. jobs_path = os.path.join(jobs_path, '**/*.pdb')
  75. job_dirs = glob.glob(jobs_path, recursive=True)
  76. job_dirs_l = []
  77. for job_dir in job_dirs:
  78. job_dirs_l.append(os.path.dirname(job_dir))
  79. if len(job_dirs_l) < 1:
  80. print('No valid jobs found in jobs path!')
  81. sys.exit(1)
  82. return job_dirs_l
  83. def create_job_instances(job_paths):
  84. job_instances = []
  85. for job_path in job_paths:
  86. job_instances.append(Job(job_path))
  87. return job_instances
  88. def get_youngest_job(jobs):
  89. jobs.sort(key=lambda x: (x.stage, x.step))
  90. return jobs[0]