Package nMOLDYN :: Package Tests :: Module StabilityTests
[hide private]
[frames] | no frames]

Source Code for Module nMOLDYN.Tests.StabilityTests

  1  """ 
  2  Test cases for stability of the current version of nMOLDYN versus nMoldyn v2.1.0, the last stable release  
  3  of nMoldyn. 
  4  Each test case is made of a benchmark of $n small tests corresponding to various input values.  
  5  For all of these small tests, the output of the tests with the reference version of nMOLDYN are  
  6  stored into files with the name: 
  7      * $PREFIX$TESTID_Reference.nc where $PREFIX is the prefix for the analysis to test and $TESTID the test number. 
  8        When running a stability test, the output of the current version are created on the fly with the name: 
  9      * $PREFIX$TESTID_Current.nc where $PREFIX is the prefix for the analysis to test and $TESTID the test number. 
 10        and each of the numeric variables of the reference and current NetCDF output file are checked to be equal within  
 11        a tolerance set to 1E-06. 
 12  """ 
 13   
 14  # The python distribution modules 
 15  import os 
 16  import sys 
 17  from timeit import default_timer 
 18  import unittest 
 19   
 20  # The ScientificPython modules 
 21  from Scientific import N 
 22  from Scientific.IO.NetCDF import NetCDFFile 
 23   
 24  # The nMOLDYN modules 
 25  from nMOLDYN.Analysis.Template import * 
 26  from nMOLDYN.Core.Logger import LogMessage 
 27   
 28  nmoldyn_tests_path = os.path.abspath(os.path.split(__file__)[0]) 
 29   
 30  availableTests = ['ARA','AVACF','DCSF','DISF','DISFG','EISF','MSD','VACF'] 
 31   
32 -class AnalysisTest(unittest.TestCase):
33
34 - def setUp(self):
35 """Overides the TestCase.setUp method. Initialization of the test variables. 36 """ 37 38 self.testPath = os.path.join(nmoldyn_tests_path,self.shortName) 39 40 self.details = '' 41 42 self.failures = {} 43 44 self.successes = {}
45
46 - def runTest(self):
47 48 # The time at whic the test starts. 49 self.start = default_timer() 50 51 test = [] 52 53 testContents = open(os.path.join(self.testPath, 'TestsContents.py'),'r') 54 exec testContents 55 testContents.close() 56 57 # Loop over the tests available for the selected test. 58 for testNumber in range(len(test)): 59 60 LogMessage('info', 'ANALYSIS: %s --- TEST No: %s' % (self.longName, testNumber+1),['console', 'file']) 61 62 self.details += '\nTest %s\n' % (testNumber + 1) 63 64 refParameters = {} 65 for key, val in template['REF'].items() + test[testNumber]['REF'].items(): 66 refParameters[key] = val 67 68 self.testParameters = {} 69 for key, val in template['NEW'].items() + test[testNumber]['NEW'].items(): 70 if key.lower() == 'analysis': 71 continue 72 self.testParameters[key] = val 73 74 analysis = eval(template['NEW']['analysis']) 75 analysis.runAnalysis() 76 77 for refVersionPrefix, refVersionVar, newVersionPrefix, newVersionVar in self.variables: 78 refVersionFile = os.path.join(self.testPath, refVersionPrefix + str(testNumber+1) + '_Reference.nc') 79 newVersionFile = template['NEW'][newVersionPrefix.lower()] 80 81 # Opens the NetCDF files coming from nMOLDYN reference and current versions. 82 ref = NetCDFFile(refVersionFile, 'r') 83 new = NetCDFFile(newVersionFile, 'r') 84 try: 85 if ref.variables[refVersionVar].typecode() in [N.Float, N.Float0, N.Int, N.Int32,N.Character]: 86 refVersionVals = ref.variables[refVersionVar].getValue() 87 newVersionVals = new.variables[newVersionVar].getValue() 88 errorMax = max(abs(N.ravel(refVersionVals - newVersionVals))) 89 self.details += '\tError for %s variable = %e\n' % (newVersionVar, errorMax) 90 self.assertAlmostEqual(errorMax, 0.0, 6) 91 92 if not self.failures.has_key(testNumber+1): 93 self.successes[testNumber+1] = {'REF' : refParameters, 'NEW' : self.testParameters} 94 95 except: 96 97 if self.successes.has_key(testNumber+1): 98 del self.successes[testNumber+1] 99 self.failures[testNumber+1] = {'REF' : refParameters, 'NEW' : self.testParameters} 100 101 finally: 102 103 ref.close() 104 new.close() 105 106 # The time at which the test ends. 107 self.end = default_timer()
108
109 - def tearDown(self):
110 """Overides the TestCase.tearDown method. Finalization of the test. 111 """ 112 113 # The number of successful tests. 114 nSuccesses = len(self.successes.keys()) 115 116 # The number of successful tests. 117 nFailures = len(self.failures.keys()) 118 119 # The number of tests performed. 120 nTests = nSuccesses + nFailures 121 122 # The percentages of successful tests. 123 rate = 100.0*(float(nSuccesses)/float(nTests)) 124 125 # The summary of the performed tests. 126 self.summary = '\n' 127 self.summary += '#########################################################' 128 self.summary += '\nSummary of tests run for %s analysis\n' % self.longName 129 self.summary += '\nNumber of tests run: %3d' % nTests 130 self.summary += '\n\nNumber of successes: %3d' % nSuccesses 131 self.summary += '\nSuccessful tests: ' 132 if not self.successes: 133 self.summary += ' None' 134 else: 135 for t in self.successes: 136 self.summary += '%s ' % t 137 138 self.summary += '\n\nNumber of failures: %3d' % nFailures 139 self.summary += '\nFailing tests:' 140 if not self.failures: 141 self.summary += ' -' 142 else: 143 for t in self.failures: 144 self.summary += ' ' 145 self.summary += '%s' % t 146 self.summary += '\n\nPercentage of success: %4.1f %%' % rate 147 self.summary += '\n\nTime to run all the tests: %5d seconds' % int(self.end - self.start) 148 self.summary += '\n\nDetails:' 149 self.summary += self.details
150
151 -class MSDTests(AnalysisTest):
152 # The test shortname. 153 shortName = 'MSD' 154 155 # The test longname. 156 longName = 'Mean-Square Displacement' 157 158 # The number of test. 159 numberOfTests = 14 160 161 info = '%d tests about %s analysis.' % (numberOfTests,longName) 162 163 # The nested list of the correspondance between the old and new names of the variables to compare between the old 164 # and new version of nMOLDYN. For each list, 165 # element 0 is the prefix of the old version netcdf filename. 166 # element 1 is the name of the variable to test within the old version netcdf filename. 167 # element 2 is the prefix of the new version netcdf filename. 168 # element 3 is the name of the variable to test within the new version netcdf filename. 169 variables = [['MSD','column1','MSD','time'], ['MSD','column2','MSD','msd']] 170
171 - def runTest(self):
173
174 -class VACFTests(AnalysisTest):
175 # The test shortname. 176 shortName = 'VACF' 177 178 # The test longname. 179 longName = 'Velocity AutoCorrelation Function' 180 181 # The number of test. 182 numberOfTests = 14 183 184 info = '%d tests about %s analysis.' % (numberOfTests,longName) 185 186 # The nested list of the correspondance between the old and new names of the variables to compare between the old 187 # and new version of nMOLDYN. For each list, 188 # element 0 is the prefix of the old version netcdf filename. 189 # element 1 is the name of the variable to test within the old version netcdf filename. 190 # element 2 is the prefix of the new version netcdf filename. 191 # element 3 is the name of the variable to test within the new version netcdf filename. 192 variables = [['VACF','column1','VACF','time'], ['VACF','column2','VACF','vacf']] 193
194 - def runTest(self):
196
197 -class ARATests(AnalysisTest):
198 # The test shortname. 199 shortName = 'ARA' 200 201 # The test longname. 202 longName = 'Auto-Regressive Analysis' 203 204 # The number of test. 205 numberOfTests = 12 206 207 info = '%d tests about %s analysis.' % (numberOfTests,longName) 208 209 # The nested list of the correspondance between the old and new names of the variables to compare between the old 210 # and new version of nMOLDYN. For each list, 211 # element 0 is the prefix of the old version netcdf filename. 212 # element 1 is the name of the variable to test within the old version netcdf filename. 213 # element 2 is the prefix of the new version netcdf filename. 214 # element 3 is the name of the variable to test within the new version netcdf filename. 215 variables = [['MSD','column1','ARA','time_msd'], ['MSD','column2','ARA','msd'],\ 216 ['VACF','column1','ARA','time_vacf'], ['VACF','column2','ARA','vacf'],\ 217 ['DOS','column1','ARA','frequency'], ['DOS','column2','ARA','dos'],\ 218 ['MEMORY','column1','ARA','time_memory'], ['MEMORY','column2','ARA','memory_function']] 219
220 - def runTest(self):
222
223 -class AVACFTests(AnalysisTest):
224 # The test shortname. 225 shortName = 'AVACF' 226 227 # The test longname. 228 longName = 'Angular Velocity AutoCorrelation Function' 229 230 # The number of test. 231 numberOfTests = 14 232 233 info = '%d tests about %s analysis.' % (numberOfTests,longName) 234 235 # The nested list of the correspondance between the old and new names of the variables to compare between the old 236 # and new version of nMOLDYN. For each list, 237 # element 0 is the prefix of the old version netcdf filename. 238 # element 1 is the name of the variable to test within the old version netcdf filename. 239 # element 2 is the prefix of the new version netcdf filename. 240 # element 3 is the name of the variable to test within the new version netcdf filename. 241 variables = [['AVACF','column1','AVACF','time'], ['AVACF','column2','AVACF','avacf-total']] 242
243 - def runTest(self):
245
246 -class DOSTests(AnalysisTest):
247 # The test shortname. 248 shortName = 'DOS' 249 250 # The test longname. 251 longName = 'Density Of States' 252 253 # The number of test. 254 numberOfTests = 14 255 256 info = '%d tests about %s analysis.' % (numberOfTests,longName) 257 258 # The nested list of the correspondance between the old and new names of the variables to compare between the old 259 # and new version of nMOLDYN. For each list, 260 # element 0 is the prefix of the old version netcdf filename. 261 # element 1 is the name of the variable to test within the old version netcdf filename. 262 # element 2 is the prefix of the new version netcdf filename. 263 # element 3 is the name of the variable to test within the new version netcdf filename. variables = [['AVACF','column1','AVACF','time'], ['AVACF','column2','AVACF','avacf-total']] 264 variables = [['DOS','column1','DOS','frequency'], ['DOS','column2','DOS','dos']] 265
266 - def runTest(self):
268
269 -class DCSFTests(AnalysisTest):
270 # The test shortname. 271 shortName = 'DCSF' 272 273 # The test longname. 274 longName = 'Dynamic Coherent Structure Factor' 275 276 # The number of test. 277 numberOfTests = 12 278 279 info = '%d tests about %s analysis.' % (numberOfTests,longName) 280 281 # The nested list of the correspondance between the old and new names of the variables to compare between the old 282 # and new version of nMOLDYN. For each list, 283 # element 0 is the prefix of the old version netcdf filename. 284 # element 1 is the name of the variable to test within the old version netcdf filename. 285 # element 2 is the prefix of the new version netcdf filename. 286 # element 3 is the name of the variable to test within the new version netcdf filename. variables = [['AVACF','column1','AVACF','time'], ['AVACF','column2','AVACF','avacf-total']] 287 variables = [['Fqt','q','DCSF','q'], ['Fqt','time','DCSF','time'], ['Fqt','sf','DCSF','Fqt-total'],\ 288 ['Sqw','q','DCSF','q'], ['Sqw','frequency','DCSF','frequency'],['Sqw','dsf','DCSF','Sqw-total']] 289
290 - def runTest(self):
292
293 -class DISFTests(AnalysisTest):
294 # The test shortname. 295 shortName = 'DISF' 296 297 # The test longname. 298 longName = 'Dynamic Incoherent Structure Factor' 299 300 # The number of test. 301 numberOfTests = 12 302 303 info = '%d tests about %s analysis.' % (numberOfTests,longName) 304 # The nested list of the correspondance between the old and new names of the variables to compare between the old 305 # and new version of nMOLDYN. For each list, 306 # element 0 is the prefix of the old version netcdf filename. 307 # element 1 is the name of the variable to test within the old version netcdf filename. 308 # element 2 is the prefix of the new version netcdf filename. 309 # element 3 is the name of the variable to test within the new version netcdf filename. variables = [['AVACF','column1','AVACF','time'], ['AVACF','column2','AVACF','avacf-total']] 310 variables = [['Fqt','q','DISF','q'], ['Fqt','time','DISF','time'], ['Fqt','sf','DISF','Fqt-total'],\ 311 ['Sqw','q','DISF','q'], ['Sqw','frequency','DISF','frequency'],['Sqw','dsf','DISF','Sqw-total']] 312
313 - def runTest(self):
315
316 -class DISFGTests(AnalysisTest):
317 318 # The test shortname. 319 shortName = 'DISFG' 320 321 # The test longname. 322 longName = 'Dynamic Incoherent Structure Factor' 323 324 # The number of test. 325 numberOfTests = 12 326 327 info = '%d tests about %s analysis.' % (numberOfTests,longName) 328 329 # The nested list of the correspondance between the old and new names of the variables to compare between the old 330 # and new version of nMOLDYN. For each list, 331 # element 0 is the prefix of the old version netcdf filename. 332 # element 1 is the name of the variable to test within the old version netcdf filename. 333 # element 2 is the prefix of the new version netcdf filename. 334 # element 3 is the name of the variable to test within the new version netcdf filename. variables = [['AVACF','column1','AVACF','time'], ['AVACF','column2','AVACF','avacf-total']] 335 variables = [['Fqt','q','DISFG','q'], ['Fqt','time','DISFG','time'], ['Fqt','sf','DISFG','Fqt-total'],\ 336 ['Sqw','q','DISFG','q'], ['Sqw','frequency','DISFG','frequency'],['Sqw','dsf','DISFG','Sqw-total']] 337
338 - def runTest(self):
340
341 -class EISFTests(AnalysisTest):
342 # The test shortname. 343 shortName = 'EISF' 344 345 # The test longname. 346 longName = 'Elastic Incoherent Structure Factor' 347 348 # The number of test. 349 numberOfTests = 12 350 351 info = '%d tests about %s analysis.' % (numberOfTests,longName) 352 353 # The nested list of the correspondance between the old and new names of the variables to compare between the old 354 # and new version of nMOLDYN. For each list, 355 # element 0 is the prefix of the old version netcdf filename. 356 # element 1 is the name of the variable to test within the old version netcdf filename. 357 # element 2 is the prefix of the new version netcdf filename. 358 # element 3 is the name of the variable to test within the new version netcdf filename. variables = [['AVACF','column1','AVACF','time'], ['AVACF','column2','AVACF','avacf-total']] 359 variables = [['EISF','column1','EISF','q'], ['EISF','column2','EISF','eisf-total']] 360
361 - def runTest(self):
363
364 -class ALLTests(AnalysisTest):
365 # The test shortname. 366 shortName = 'ALL' 367 368 # The test longname. 369 longName = 'All available tests' 370 371 # The number of test. 372 numberOfTests = 12 373 374 variables = None 375 376 info = '' 377 for n in availableTests: 378 t = eval(n+'Tests()') 379 info += '%d tests about %s analysis.\n' % (t.numberOfTests,t.longName) 380 del t 381
382 - def runTest(self):
383 self.summary = '' 384 for n in availableTests: 385 t = eval(n+'Tests()') 386 t.run() 387 self.summary += t.summary
388 389 if __name__ == '__main__': 390 391 selectedTests = [n.upper() for n in sys.argv[1:]] 392 393 if 'ALL' in selectedTests: 394 selectedTests = availableTests 395 396 try: 397 globalSummary = '' 398 for n in selectedTests: 399 t = eval(n.strip().upper()+'Tests()') 400 t.run() 401 globalSummary += t.summary 402 print globalSummary 403 404 except: 405 print 'One or several unknown tests' 406