Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Implemented the algorithm. But it has not been tested.
- Loading branch information
Showing
1 changed file
with
291 additions
and
0 deletions.
There are no files selected for viewing
291 changes: 291 additions & 0 deletions
291
Code/Mantid/Framework/PythonInterface/plugins/algorithms/ExportVulcanSampleLogs.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,291 @@ | ||
"""*WIKI* | ||
== Assumption == | ||
1. All logs specified by user should be synchronized. | ||
== File format == | ||
* Column 0: | ||
* Column 1: | ||
* Column 2 to 2 + n: | ||
*WIKI*""" | ||
|
||
import mantid.simpleapi as api | ||
from mantid.api import * | ||
from mantid.kernel import * | ||
import os | ||
|
||
|
||
class ExportVulcanSampleLogs(PythonAlgorithm): | ||
""" Python algorithm to export sample logs to spread sheet file | ||
for VULCAN | ||
""" | ||
def category(self): | ||
""" Category | ||
""" | ||
return "Utilities;PythonAlgorithms" | ||
|
||
def name(self): | ||
""" Algorithm name | ||
""" | ||
return "ExportVulcanSampleLogs" | ||
|
||
def PyInit(self): | ||
""" Declare properties | ||
""" | ||
# Input workspace | ||
self.declareProperty(MatrixWorkspaceProperty("InputWorkspace", "", Direction.Input), | ||
"Name of data workspace containing sample logs to be exported. ") | ||
|
||
# Output file name | ||
self.declareProperty(FileProperty("OutputFilename", "", FileAction.Save, [".txt"]), | ||
"Name of the output sample environment log file name.") | ||
|
||
# Sample log names | ||
self.declareProperty(StringArrayProperty("SampleLogNames", values=[], validator=arrvalidator, | ||
direction=Direction.Input), "Names of sample logs to be exported in a same file.") | ||
|
||
# Header | ||
self.declareProperty("WriteHeaderFile", False, "Flag to generate a sample log header file.") | ||
|
||
self.declareProperty("Header", "", "String in the header file.") | ||
|
||
# Time zone | ||
timezones = ["America/New_York"] | ||
self.declareProperty("TimeZone", "America/New_York", StringListValidator(timezones)) | ||
|
||
return | ||
|
||
|
||
def PyExec(self): | ||
""" Main executor | ||
""" | ||
# Read inputs | ||
self._getProperties() | ||
|
||
# Read in logs | ||
logtimesdict, logvaluesdict, loglength = self._readSampleLogs() | ||
|
||
# Local time difference | ||
localtimediff = self._calLocalTimeDiff(logtimesdict) | ||
|
||
# Write log file | ||
self._writeLogFile(logtimesdict, logvaluedict, loglength, localtimediff) | ||
|
||
# Write header file | ||
if self._writeheader is True: | ||
testdatetime = self._wksp.getRun().getProperty("run_start").value | ||
description = "Type your description here" | ||
self._writeHeaderFile(testdatetime, description) | ||
|
||
return | ||
|
||
|
||
def _getProperties(self): | ||
""" Get and process properties | ||
""" | ||
self._wksp = self.getProperty("InputWorkspace").value | ||
|
||
self._outputfilename = self.getProperty("OutputFilename").value | ||
filedir = os.path.split(self._outputfilename)[0] | ||
if os.path.exists(filedir) is False: | ||
raise NotImplementedError("Directory %s does not exist. File cannot be written." % (filedir)) | ||
|
||
self._sampleloglist = self.getProperty("SampleLogNames").value | ||
if len(self._sampleloglist) == 0: | ||
raise NotImplementedError("Sample logs names cannot be empty.") | ||
|
||
self._writeheader = self.getProperty("WriteHeaderFile").value | ||
self._headercontent = self.getProperty("Header").value | ||
if self._writeheader is True and len(self._headercontent.strip()) == 0: | ||
self.log().warning("Header is empty. Thus WriteHeaderFile is forced to be False.") | ||
self._writeheader = False | ||
|
||
self._timezone = self.getProperty("TimeZon").value | ||
|
||
return | ||
|
||
|
||
def _calLocalTimeDiff(self, logtimesdict): | ||
""" Calcualte the time difference between local time and UTC in seconds | ||
""" | ||
# Find out local time | ||
if loglength > 0: | ||
# Locate time0 | ||
for key in logtimesdict.keys(): | ||
times = logtimesdict[key] | ||
if times is not None: | ||
time0 = logtimesdict[key][0] | ||
break | ||
# Local time difference | ||
localtimediff = getLocalTimeShiftInSecond(time0) | ||
else: | ||
localtimediff = 0 | ||
|
||
return localtimediff | ||
|
||
|
||
def _writeLogFile(self, logtimesdict, logvaluedict, loglength, localtimediff): | ||
""" Write the logs to file | ||
""" | ||
wbuf = "" | ||
|
||
# Init time | ||
if loglength > 0: | ||
for log in logtimesdict.keys(): | ||
if logtimesdict[log] is not None: | ||
time0 = logtimesdict[log][0] | ||
abstime_init = time0.totalNanoseconds() * 1.E-9 - localtimediff | ||
times = logtimesdict[log] | ||
break | ||
|
||
# Loop | ||
for i in xrange(loglength): | ||
abstime = times[i].totalNanoseconds() * 1.E-9 - localtimediff | ||
reltime = abstime - abstime_init | ||
# Write absoute time and relative time | ||
wbuf += "%.6f\t %.6f\t " % (abstime, reltime) | ||
# Write each log value | ||
for samplelog in lognames: | ||
if logvaluedict[samplelog] is not None: | ||
logvalue = logvaluedict[samplelog][i] | ||
else: | ||
logvalue = 0. | ||
wbuf += "%.6f\t " % (logvalue) | ||
wbuf += "\n" | ||
# ENDFOR | ||
|
||
try: | ||
ofile = open(self._outputfilename, "w") | ||
ofile.write(wbuf) | ||
ofile.close() | ||
except IOError as err: | ||
print err | ||
raise NotImplementedError("Unable to write file %s. Check permission." % (self._outputfilename) | ||
|
||
|
||
return | ||
|
||
|
||
def _readSampleLogs(self): | ||
""" Read sample logs | ||
""" | ||
# Get all properties' times and value and check whether all the logs are in workspaces | ||
samplerun = wksp.getRun() | ||
|
||
logtimesdict = {} | ||
logvaluedict = {} | ||
for samplename in lognames: | ||
# Check existence | ||
logexist = samplerun.hasProperty(samplename) | ||
|
||
if logexist is True: | ||
# Get hold of sample values | ||
p = samplerun.getProperty(samplename) | ||
logtimesdict[samplename] = p.times | ||
logvaluedict[samplename] = p.value | ||
|
||
else: | ||
# Add None | ||
self.log().warning("Sample log %s does not exist. " % (samplename)) | ||
logtimesdict[samplename] = None | ||
logvaluedict[samplename] = None | ||
|
||
# ENDIF | ||
# ENDFOR | ||
|
||
# Check properties' size | ||
loglength = sys.maxint | ||
for i in xrange(len(lognames)): | ||
if logtimesdict[lognames[i]] is not None: | ||
tmplength = len(logtimesdict[lognames[i]]) | ||
if loglength != tmplength: | ||
if loglength != sys.maxint: | ||
self.log().warning("Log %s has different length from previous ones. " % (lognames[i])) | ||
loglength = min(loglength, tmplength) | ||
# ENDIF | ||
# ENDIF | ||
# ENDFOR | ||
|
||
if loglength == sys.maxint: | ||
self.log().warning("None of given log names is found in workspace. ") | ||
loglength = 0 | ||
else: | ||
self.log().information("Final Log length = %d" % (loglength)) | ||
|
||
return (logtimesdict, logvaluedict, loglength) | ||
|
||
|
||
|
||
|
||
def _writeHeaderFile(self, testdatetime, description): | ||
""" Write the header file for a LoadFrame | ||
""" | ||
# Construct 3 lines of the header file | ||
line0 = "Test date: %s" % (str(testdatetime)) | ||
line1 = "Test description: %s" % (description) | ||
line2 = self._headercontent | ||
|
||
# Write file | ||
wbuf = line0 + "\n" + line1 + "\n" + line2 + "\n" | ||
headerfilename = self._outputfilename.split(".")[0] + "_header.txt" | ||
self.log().information("Writing header file %s ... " % (headerfilename)) | ||
|
||
try: | ||
ofile = open(headerfilename, "w") | ||
ofile.write(wbuf) | ||
ofile.close() | ||
except OSError as err: | ||
self.log().error(str(err)) | ||
|
||
return | ||
|
||
|
||
|
||
def getLocalTimeShiftInSecond(utctime): | ||
""" Calculate the difference between UTC time and local time of given | ||
DataAndTime | ||
""" | ||
from datetime import datetime | ||
from dateutil import tz | ||
|
||
print "Input UTC time = %s" % (str(utctime)) | ||
|
||
from_zone = tz.gettz('UTC') | ||
to_zone = tz.gettz(LOCAL_TIME_ZONE) | ||
|
||
t1str = (str(utctime)).split('.')[0] | ||
utc = datetime.strptime(t1str, '%Y-%m-%dT%H:%M:%S') | ||
|
||
utc = utc.replace(tzinfo=from_zone) | ||
sns = utc.astimezone(to_zone) | ||
|
||
shift_in_hr = utc.hour - sns.hour | ||
|
||
shift_in_sec = shift_in_hr * 3600. | ||
|
||
return shift_in_sec | ||
|
||
|
||
def convertToLocalTime(utctimestr): | ||
""" Convert UTC time in string to local time | ||
""" | ||
from datetime import datetime | ||
from dateutil import tz | ||
|
||
print "Input UTC time = %s" % (utctimestr) | ||
|
||
from_zone = tz.gettz('UTC') | ||
to_zone = tz.gettz(LOCAL_TIME_ZONE) | ||
|
||
t1str = (utctimestr).split('.')[0] | ||
utc = datetime.strptime(t1str, '%Y-%m-%dT%H:%M:%S') | ||
|
||
utc = utc.replace(tzinfo=from_zone) | ||
sns = utc.astimezone(to_zone) | ||
|
||
return str(sns) | ||
|
||
|
||
# Register algorithm with Mantid | ||
AlgorithmFactory.subscribe(ExportVulcanSampleLogs) |