Skip to content

Commit

Permalink
Implemented algorithm. Refs #8994.
Browse files Browse the repository at this point in the history
Implemented the algorithm.  But it has not been tested.
  • Loading branch information
wdzhou committed Feb 12, 2014
1 parent 5ada934 commit 8b90e5d
Showing 1 changed file with 291 additions and 0 deletions.
@@ -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)

0 comments on commit 8b90e5d

Please sign in to comment.