Module EDUtilsUnit
[hide private]
[frames] | no frames]

Source Code for Module EDUtilsUnit

  1  # -*- coding: utf8 -*- 
  2  # 
  3  #    Project: The EDNA Kernel 
  4  #             http://www.edna-site.org 
  5  # 
  6  #    File: "$Id: EDUtilsPath.py 1484 2010-05-05 07:08:21Z svensson $" 
  7  # 
  8  #    Copyright (C) 2008-2009 European Synchrotron Radiation Facility 
  9  #                            Grenoble, France 
 10  # 
 11  #    Principal authors: Jérôme Kieffer (jerome.kieffer@esrf.fr) 
 12  #  
 13  # 
 14  #    This program is free software: you can redistribute it and/or modify 
 15  #    it under the terms of the GNU Lesser General Public License as published 
 16  #    by the Free Software Foundation, either version 3 of the License, or 
 17  #    (at your option) any later version. 
 18  # 
 19  #    This program is distributed in the hope that it will be useful, 
 20  #    but WITHOUT ANY WARRANTY; without even the implied warranty of 
 21  #    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
 22  #    GNU Lesser General Public License for more details. 
 23  # 
 24  #    You should have received a copy of the GNU General Public License 
 25  #    and the GNU Lesser General Public License  along with this program.   
 26  #    If not, see <http://www.gnu.org/licenses/>. 
 27  # 
 28  __authors__ = [ "Jérôme Kieffer" ] 
 29  __contact__ = "jerome.kieffer@esrf.fr" 
 30  __license__ = "LGPLv3+" 
 31  __copyright__ = "European Synchrotron Radiation Facility, Grenoble, France" 
 32   
 33   
 34  import math 
 35  from EDVerbose import EDVerbose 
 36  from XSDataCommon import XSDataString 
37 38 39 -class EDUtilsUnit:
40 """ 41 This is a static utility class for handling unit (meter ... and subunit) in XSData / XML data structures. 42 """ 43 44 dictLength = {("m", "meter", None): 1.0, 45 ("cm", "centimeter"): 1.0e-2, 46 ("mm", "millimeter"): 1.0e-3, 47 ("um", "µm", "micron", "micrometer"):1.0e-6, 48 ("nm", "nanometer"):1.0e-9, 49 ("pm", "picometer"): 1.0e-12, 50 ("A", "Angstrom", "angstrom"):1.0e-10, 51 ("km", "kilometer"): 1.e3, 52 } 53 54 dictAngle = {("rad", "r", None):1.0, 55 ("deg", "°"): math.pi / 180.0, 56 ("grad", "g"): math.pi / 200.0, 57 } 58 59 dictTime = { ("s", "sec", "second", None):1.0, 60 ("ms", "millisec", "millisecond"):1.0e-3, 61 ("mn", "min", "minute"):60.0, 62 ("h", "hour", "heure"):3600.0 63 } 64 65 @staticmethod
66 - def getSIValue(_object):
67 """ 68 convert any object into the international System unit. 69 @param _object: any object 70 @return: value in the international system 71 @rtype: float 72 """ 73 fValue = None 74 75 unit = _object.getUnit() 76 if unit is None: 77 EDVerbose.DEBUG("No unit specified for object %s" % _object.__class__) 78 fValue = _object.getValue() 79 else: 80 if EDUtilsUnit.getClassName(_object) in ["XSDataWavelength", "XSDataDisplacement", "XSDataLength"]: 81 fValue = EDUtilsUnit.getValueLength(_object.getValue(), unit.getValue()) 82 elif EDUtilsUnit.getClassName(_object) in ["XSDataAngle"]: 83 fValue = EDUtilsUnit.getValueAngle(_object.getValue(), unit.getValue()) 84 elif EDUtilsUnit.getClassName(_object) in ["XSDataTime"]: 85 fValue = EDUtilsUnit.getValueTime(_object.getValue(), unit.getValue()) 86 87 return fValue
88 89 90 @staticmethod
91 - def getValue(_object, _strUnit):
92 """ 93 convert any object into the international System unit. 94 @param _object: any object 95 @param _strUnit: unit name like "um" or "deg" 96 @return: value in the international system 97 @rtype: float 98 """ 99 fValue = None 100 unit = _object.getUnit() 101 if unit is None: 102 EDVerbose.DEBUG("No unit specified for object %s" % _object.__class__) 103 fValue = _object.getValue() 104 else: 105 if unit.getValue() == _strUnit: 106 fValue = _object.getValue() 107 else: 108 if EDUtilsUnit.getClassName(_object) in ["XSDataWavelength", "XSDataDisplacement", "XSDataLength"]: 109 fValue = EDUtilsUnit.getValueLength(_object.getValue(), unit.getValue()) / EDUtilsUnit.getUnitScaleLength(_strUnit) 110 elif EDUtilsUnit.getClassName(_object) in ["XSDataAngle"]: 111 fValue = EDUtilsUnit.getValueAngle(_object.getValue(), unit.getValue()) / EDUtilsUnit.getUnitScaleAngle(_strUnit) 112 elif EDUtilsUnit.getClassName(_object) in ["XSDataTime"]: 113 fValue = EDUtilsUnit.getValueTime(_object.getValue(), unit.getValue()) / EDUtilsUnit.getUnitScaleTime(_strUnit) 114 return fValue
115 116 117 @staticmethod
118 - def toXSD(_classXSData, _strObject,):
119 """Convert a string or possibly any object to an XSD object 120 121 @param _classXSData: the XSDataClass to be forced into 122 @type _classXSData: class derived from XSData 123 @param _strObject: the string representation of a physical object like "1.54 A" 124 @type _strObject: string (floats are accepted) 125 """ 126 xsd = _classXSData() 127 if isinstance(_strObject, (unicode, str)): 128 listWords = _strObject.split(None, 1) 129 if len(listWords) > 0: 130 try: 131 fValue = float(listWords[0]) 132 except Exception: 133 EDVerbose.ERROR("Trying to create XSData object from %s; fValue not a float !" % _strObject) 134 135 else: 136 xsd.setValue(fValue) 137 if len(listWords) == 2: 138 xsd.setUnit(XSDataString(listWords[1])) 139 else: 140 EDVerbose.WARNING("Trying to create XSData object from %s " % _strObject) 141 elif isinstance(_strObject, (float, int)): 142 xsd.setValue(_strObject) 143 return xsd
144 145 146 @staticmethod
147 - def getClassName(_object):
148 """ 149 Retrieves the name of the class 150 @return: the name of the class 151 @rtype: string 152 """ 153 return str(_object.__class__).replace("<class '", "").replace("'>", "").split(".")[-1]
154 155 156 @staticmethod
157 - def getUnitScaleLength(_unit):
158 """ 159 Return the fScale factor of an unit versus SI unit (meter) 160 @param _unit: the name of the unit 161 @return : the numeric fScale factor (0.001 for mm) 162 """ 163 fScale = None 164 for oneUnit in EDUtilsUnit.dictLength: 165 if _unit in oneUnit: 166 fScale = EDUtilsUnit.dictLength[oneUnit] 167 break 168 if fScale is None: 169 EDVerbose.WARNING("Unrecognized length unit: %s" % _unit) 170 fScale = 1.0 171 return fScale
172 173 174 @staticmethod
175 - def getUnitScaleAngle(_unit):
176 """ 177 Return the fScale factor of an unit versus SI unit (radian) 178 @param _unit: the name of the unit 179 @return : the numeric fScale factor (0.001 for mm) 180 """ 181 fScale = None 182 for oneUnit in EDUtilsUnit.dictAngle: 183 if _unit in oneUnit: 184 fScale = EDUtilsUnit.dictAngle[oneUnit] 185 break 186 if fScale is None: 187 EDVerbose.WARNING("Unrecognized Angle unit: %s" % _unit) 188 fScale = 1.0 189 return fScale
190 191 192 @staticmethod
193 - def getUnitScaleTime(_unit):
194 """ 195 Return the fScale factor of an unit versus SI unit (seconds) 196 @param _unit: the name of the unit 197 @return : the numeric fScale factor (60 for mn) 198 """ 199 fScale = None 200 for oneUnit in EDUtilsUnit.dictTime: 201 if _unit in oneUnit: 202 fScale = EDUtilsUnit.dictTime[oneUnit] 203 break 204 if fScale is None: 205 EDVerbose.WARNING("Unrecognized Time unit: %s" % _unit) 206 fScale = 1.0 207 return fScale
208 209 210 @staticmethod
211 - def getValueLength(_value, _unit):
212 """ 213 Convert a length like fValue to meter (SI) 214 @param _value: the fValue in unit 215 @type _value: float 216 @param _unit: the name of the unit 217 @type _unit: string 218 """ 219 return _value * EDUtilsUnit.getUnitScaleLength(_unit)
220 221 222 @staticmethod
223 - def getValueAngle(_value, _unit):
224 """ 225 Convert an angle like fValue to radian (SI) 226 @param _value: the fValue in unit 227 @type _value: float 228 @param _unit: the name of the unit 229 @type _unit: string 230 """ 231 return _value * EDUtilsUnit.getUnitScaleAngle(_unit)
232 233 234 @staticmethod
235 - def getValueTime(_value, _unit):
236 """ 237 Convert an time like fValue to seconds (SI) 238 @param _value: the fValue in unit 239 @type _value: float 240 @param _unit: the name of the unit 241 @type _unit: string 242 """ 243 return _value * EDUtilsUnit.getUnitScaleTime(_unit)
244