FLEXPART Testing Environment CTBTO WO8
 All Classes Namespaces Files Functions Variables Pages
FlexpartExecutable.py
Go to the documentation of this file.
1 # -*- coding: utf-8 -*-
2 """
3 Created on Wed Mar 11 12:30:25 2015
4 
5 @author: morton
6 """
7 
8 import copy
9 import filecmp
10 import logging
11 import os
12 import shutil
13 import subprocess
14 import sys
15 
17 
18 
19  def __init__(self, srcdir=None, destdir=None,
20  makefile=None, parmodfile=None,
21  executable_name=None):
22 
23  """Set up the class
24 
25  srcdir : full path to location of FLEXPART src tree
26  destdir : full path to copy the FLEXPART src tree into.
27  Files will be copied directly in here
28  makefile : The makefile to use - if there is no leading path, then
29  file is assumed to be in srcdir. Otherwise, it is
30  assumed to be located as defined by the path
31  parmodfile : full path to an external (from source code) par_mod.F90
32  executable_name : The name of the expected executable (stripped path)
33  """
34 
35  # Reasons to abort ##########################
36 
37  # Test that srcdir is found
38  if os.path.isdir(srcdir):
39  self._srcdir = srcdir
40  else:
41  msg = 'srcdir not found: ' + srcdir
42  raise Exception(msg)
43 
44  # test for a destdir argument
45  if destdir:
46  # Make sure it doesn't already exist
47  if os.path.isdir(destdir):
48  msg = 'destdir cannot already exist: ' + destdir
49  raise Exception(msg)
50  else:
51  self._destdir = destdir
52  else:
53  msg = 'No destdir argument'
54  raise Exception(msg)
55 
56 
57  # test for a makefile argument. If the argument has a prefixed path,
58  # then put the whole path in the makefile name. Otherwise, it is
59  # assumed to be in the source directory
60  if makefile:
61  # Make sure the we get the correct path on the makefile
62  path_tuple = os.path.split(makefile)
63  #print path_tuple
64  if len(path_tuple[0]) == 0:
65  # No leading path
66  self._makefile = self._srcdir + '/' + makefile
67  else:
68  # Full path
69  self._makefile = makefile
70  #print self._makefile
71  # Now let's make sure it actually exists
72  if not os.path.isfile(self._makefile):
73  msg = 'source makefile not found: ' + makefile
74  self._makefile = None
75  raise Exception(msg)
76  else:
77  msg = 'No makefile argument'
78  raise Exception(msg)
79 
80  # test for executable_name argument
81  if executable_name:
82  self._path_to_executable = destdir + '/' + executable_name
83  else:
84  msg = 'No executable_name argument'
85  raise Exception(msg)
86 
87  # Test for external par_mod.F90 and, if it's valid, store path
88  self._parmodfile = None
89  if parmodfile:
90  if os.path.isfile(parmodfile):
91  self._parmodfile = parmodfile
92  else:
93  msg = 'parmodfile not found: ' + parmodfile
94  raise Exception(msg)
95 
96 
97  #print self._path_to_executable
98  self._destdir_ok = False # This indicates if copy to destdir was ok
99 
100  init_success = True
101 
102 
103  # Make sure destdir does not already exist
104  if not os.path.isdir(destdir):
105  # Copy the distribution from srcdir into destdir and validate success
106  try:
107  #print srcdir, destdir
108  shutil.copytree(srcdir, destdir)
109  logging.info('FlexpartExecutable: copying source code to temp location')
110 
111  # Compare the directories. Success would be indicated
112  # by an empty list diffs.diff_files
113  diffs = filecmp.dircmp(srcdir, destdir)
114  if diffs.diff_files:
115  logging.warning('FlexpartExecutable: src and dest differ')
116  init_success = False
117 
118 
119  except:
120  init_success = False
121  logging.warning('FlexpartExecutable: copy failed')
122 
123  # If we made it here, one last step is to copy in a substitute
124  # parmodfile, if it was specified
125  if init_success and self._parmodfile:
126  try:
127  shutil.copy(self._parmodfile, destdir + '/par_mod.F90')
128  except:
129  init_success = False
130  logging.warning('FlexpartExecutable: parmodfile copy failed')
131 
132  else:
133  init_success = False
134  logging.warning('FlexpartExecutable: destdir exists')
135 
136  if init_success:
137  self._destdir_ok = True
138 
139  # Remove any *.o and *.mod files
140  extensions = ('.o', '.mod')
141  for current_file in os.listdir(destdir):
142  if any(current_file.endswith(ext) for ext in extensions):
143  os.remove(destdir + '/' + current_file)
144 
145 
146 
147  def modify_makefile(self):
148  """ Can't remember why I might have considered this method """
149 
150  pass
151 
152  def executable_exists(self):
153  """ Returns True or False depending on whether the expected
154  executable exists. Note that this says nothing about whether it
155  is a good executable or not - simply that an executable file of the
156  expected name exists in the expected location """
157 
158  return_value = False
159  if self._path_to_executable and \
160  os.path.isfile(self._path_to_executable) and \
161  os.access(self._path_to_executable, os.X_OK):
162  return_value = True
163 
164  return return_value
165 
166  def compile_it(self):
167  """Compile the code. Return True or False depending on success"""
168 
169  make_command = 'make -f ' + self._makefile
170 
171  with open(self._destdir + '/compile.out', 'w') as out:
172  make_process = subprocess.Popen(make_command, shell=True,
173  stdout=out,
174  stderr=out,
175  cwd=self._destdir)
176 
177 
178  STATUS = make_process.wait()
179  #print 'STATUS: ' + str(STATUS)
180  if STATUS == 0:
181  return True
182  else:
183  return False
184 
185 
187 
188  """Return path to expected executable. Note that this does not
189  imply that the executable actually exists"""
190 
191  return copy.copy(self._path_to_executable)
192 
193 
194 if __name__ == "__main__":
195  SRC='/u1/uaf/morton/tmp/C3'
196  DEST='/u1/uaf/morton/tmp/Cblah'
197  try:
198  e = FlexpartExecutable(srcdir=SRC, destdir=DEST)
199  except:
200  print 'failed...'
201 
202 
203