PageRenderTime 91ms CodeModel.GetById 23ms RepoModel.GetById 1ms app.codeStats 1ms

/beam-3dveglab-vlab/src/main/resources/auxdata/VLabImpl.py

https://github.com/anarisris/esa-beam
Python | 4461 lines | 4383 code | 25 blank | 53 comment | 25 complexity | f8677628c1450eb62c12d9bfef56fdc0 MD5 | raw file
  1. #
  2. # Copyright (C) 2010-2014 Netcetera Switzerland (info@netcetera.com)
  3. #
  4. # This program is free software; you can redistribute it and/or modify it
  5. # under the terms of the GNU General Public License as published by the Free
  6. # Software Foundation; either version 3 of the License, or (at your option)
  7. # any later version.
  8. # This program is distributed in the hope that it will be useful, but WITHOUT
  9. # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  10. # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
  11. # more details.
  12. #
  13. # You should have received a copy of the GNU General Public License along
  14. # with this program; if not, see http://www.gnu.org/licenses/
  15. #
  16. # @(#) $Id: $
  17. #
  18. # Authors: Cyrill Schenkel, Daniel Kueckenbrink, Joshy Cyriac, Marcel Kessler, Jason Brazile
  19. #
  20. ##############################################################################
  21. # Three ways to run it:
  22. #
  23. # 1. embedded within the BEAM processor (normal case)
  24. #
  25. # 2. standalone tests - headless (either jython or python)
  26. #
  27. # jython -Dpython.path=jcommon-1.0.16.jar:jfreechart-1.0.13.jar VLabImpl.py
  28. # python VLabImpl.py
  29. #
  30. # 3. standalone with a 'fake' swing-based gui
  31. #
  32. # java -jar ${HOME}/beam-4.11/lib/jython-2.5.2.jar -Dvlab.fakebeam=1 -Dpython.path=${HOME}/beam-4.11/lib/jcommon-1.0.16.jar:${HOME}/beam-4.11/lib/jfreechart-1.0.13.jar VLabImpl.py
  33. #
  34. # Those BEAM-supplied jars can also be obtained like this:
  35. # wget -U "Mozilla/5.0" http://repo1.maven.org/maven2/jfree/jfreechart/1.0.13/jfreechart-1.0.13.jar
  36. # wget -U "Mozilla/5.0" http://repo1.maven.org/maven2/jfree/jcommon/1.0.16/jcommon-1.0.16.jar
  37. #
  38. #
  39. import sys, math, operator, array, time, struct
  40. from array import array
  41. class VLAB:
  42. """VLAB contains conf. constants, static utility methods, and test methods"""
  43. COPYRIGHT_INFO = 'Copyright (C) 2010-2014 Netcetera Switzerland (info@netcetera.com)'
  44. PROCESSOR_NAME = 'BEAM VLab Processor'
  45. PROCESSOR_SNAME = 'beam-vlab'
  46. REQUEST_TYPE = 'VLAB'
  47. UI_TITLE = 'VLab - Processor'
  48. VERSION_STRING = '1.0 (20 July 2014)'
  49. DEFAULT_LOG_PREFIX = 'vlab'
  50. LOGGER_NAME = 'beam.processor.vlab'
  51. D_PRODNAME = 'vlab_out.dim'
  52. P_CONDITION = '.condition'
  53. P_EXPRESSION = '.expression'
  54. P_OUTPUT = '.output'
  55. # NOTE: Once released, random number generation should NOT be reproducible
  56. CONF_RND_REPRODUCE = True
  57. JCB = 'JComboBox'
  58. JTF = 'JTextField'
  59. JTD = (JTF, False)
  60. K_LIBRAT = 'librat'
  61. K_DART = 'DART'
  62. K_DUMMY = 'dummy'
  63. K_LAEGERN = 'Laegern'
  64. K_THARANDT = 'Tharandt'
  65. K_RAMI = 'RAMI'
  66. K_USER_DEFINED = 'User defined (UserDefined.obj)'
  67. K_YES = 'Yes'
  68. K_NO = 'No'
  69. K_SENTINEL2 = 'MSI (Sentinel 2)'
  70. K_SENTINEL3 = 'OLCI (Sentinel 3)'
  71. K_MODIS = 'MODIS'
  72. K_MERIS = 'MERIS'
  73. K_LANDSAT_OLI = 'Landsat (OLI)'
  74. K_LANDSAT_ETM = 'Landsat (ETM)'
  75. K_RURAL = 'Rural'
  76. K_MARITIME = 'Maritime'
  77. K_URBAN = 'Urban'
  78. K_TROPOSPHERIC = 'Tropospheric'
  79. DBG = 'debug'
  80. INF = 'info'
  81. ERR = 'error'
  82. plst = []
  83. if sys.platform.startswith('java'):
  84. from java.util.logging import Logger
  85. from java.util.logging import FileHandler
  86. from java.util.logging import Level
  87. logger = Logger.getLogger(LOGGER_NAME)
  88. # comment these out
  89. # logfh = FileHandler('%s.log' % LOGGER_NAME)
  90. # logfh.setLevel(Level.FINEST)
  91. # logger.addHandler(logfh)
  92. else:
  93. import logging
  94. logger = logging.getLogger(LOGGER_NAME)
  95. logger.setLevel(logging.DEBUG)
  96. logch = logging.StreamHandler()
  97. logch.setLevel(logging.DEBUG)
  98. logger.addHandler(logch)
  99. # comment these out
  100. # logfh = logging.FileHandler('%s.log' % LOGGER_NAME)
  101. # logfh.setLevel(logging.DEBUG)
  102. # logger.addHander(logfh)
  103. model = (
  104. {'Forward Modeling': (
  105. {'Model Selection': (
  106. ('3D Scene', '3dScene', JCB, (K_RAMI, K_LAEGERN, K_THARANDT, K_USER_DEFINED)),
  107. ('RT Processor', 'RTProcessor', JCB, (K_DUMMY, K_LIBRAT, K_DART)))},
  108. {'Spectral Characteristics': (
  109. ('Sensor', 'Sensor', JCB, (K_SENTINEL2, K_SENTINEL3, K_MODIS, K_MERIS, K_LANDSAT_OLI, K_LANDSAT_ETM)),
  110. ('Bands', 'Bands', JTF, '1, 2, 3, 4, 5, 6, 7, 8, 9, 10'))},
  111. {'Viewing Characteristics': (
  112. ('Zenith', 'ViewingZenith', JTF, '20.0'),
  113. ('Azimuth', 'ViewingAzimuth', JTF, '0.0'))},
  114. {'Illumination Characteristics':(
  115. ('Zenith', 'IlluminationZenith', JTF, '20.0'),
  116. ('Azimuth', 'IlluminationAzimuth', JTF, '0.0'))},
  117. {'Scene Parameters': (
  118. ('Pixel Size', 'ScenePixel', JTD, 'not available yet'),
  119. ('(Alt A) Filename', 'SceneLocFile', JTD, 'not available yet'),
  120. ('(Alt B) XC', 'SceneXC', JTD, 'not available yet'),
  121. ('(Alt B) XW', 'SceneXW', JTD, 'not available yet'),
  122. ('(Alt B) YC', 'SceneYC', JTD, 'not available yet'),
  123. ('(Alt B) YW', 'SceneYW', JTD, 'not available yet'))},
  124. {'Atmospheric Parameters': (
  125. ('CO2 Mixing Ratio', 'AtmosphereCO2', JTF, '1.6'),
  126. ('Aerosol Profile', 'AtmosphereAerosol', JCB, (K_RURAL, K_MARITIME, K_URBAN, K_TROPOSPHERIC)),
  127. ('Water Vapor', 'AtmosphereWater', JTF, '0.0'),
  128. ('Ozone Column', 'AtmosphereOzone', JTF, '300'))},
  129. {'Output Parameters': (
  130. ('Result file prefix','OutputPrefix', JTF, 'HET01_DIS_UNI_NIR_20.obj'),
  131. ('Result Directory', 'OutputDirectory', JTF, 'dart.rpv.rami.2'),
  132. ('Image file', 'ImageFile', JCB, (K_YES, K_NO)),
  133. ('Ascii file', 'AsciiFile', JCB, (K_YES, K_NO)))}
  134. )},
  135. {'DHP Simulation': (
  136. {'Model Selection': (
  137. ('3D Scene', 'DHP_3dScene', JCB, (K_RAMI, K_LAEGERN, K_THARANDT)),
  138. (),
  139. ('Resolution', 'DHP_Resolution', JTF, '4000000'),
  140. ())},
  141. {'DHP Location': (
  142. ('X', 'DHP_X', JTD, 'not available yet'),
  143. ('Y', 'DHP_Y', JTD, 'not available yet'))},
  144. {'DHP Properties': (
  145. ('Zenith', 'DHP_Zenith', JTF, '0.0'),
  146. ('Azimuth', 'DHP_Azimuth', JTF, '0.0'))},
  147. {'DHP Imaging Plane': (
  148. ('Orientation', 'DHP_Orientation', JTD, 'not available yet'),
  149. ('Height(z)', 'DHP_Height', JTD, 'not available yet'))},
  150. {'Output Parameters': (
  151. ('Result file prefix','DHP_OutputPrefix', JTF, 'RAMI00_'),
  152. ('Result Directory', 'DHP_OutputDirectory', JTF, ''),
  153. ('Image file', 'DHP_ImageFile', JCB, (K_YES, K_NO)),
  154. ('Ascii file', 'DHP_AsciiFile', JCB, (K_YES, K_NO)))}
  155. )},
  156. )
  157. # set parameter names
  158. for tabGroups in model:
  159. for tabName in tabGroups:
  160. for group in tabGroups[tabName]:
  161. for groupName in group:
  162. for groupTuple in group[groupName]:
  163. if len(groupTuple) == 4:
  164. (lbl, nm, typ, vals) = groupTuple
  165. exec('P_' + nm + ' = nm')
  166. exec('L_' + nm + ' = lbl')
  167. plst.append(nm)
  168. def __init__(self):
  169. self.cmap = {}
  170. self.vmap = {}
  171. def me():
  172. """Returns name of currently executing method"""
  173. nm = ''
  174. try:
  175. raise ZeroDivisionError
  176. except ZeroDivisionError:
  177. nm = sys.exc_info()[2].tb_frame.f_back.f_code.co_name
  178. return nm+'()'
  179. me = staticmethod(me)
  180. def lineSeparator():
  181. """Return the OS line separator"""
  182. if sys.platform.startswith('java'):
  183. from java.lang import System
  184. if sys.platform.startswith('java1.6'):
  185. return System.getProperty('line.separator')
  186. elif sys.platform.startswith('java1.7'):
  187. return System.lineSeparator()
  188. else:
  189. import os
  190. os.linesep
  191. lineSeparator = staticmethod(lineSeparator)
  192. def listdir(path):
  193. """list files in the directory given by path"""
  194. if sys.platform.startswith('java'):
  195. from java.io import File
  196. array = File(path).list()
  197. listFile = []
  198. if array != None:
  199. for i in xrange(len(array)):
  200. listFile.append(array[i])
  201. return listFile
  202. else:
  203. import os
  204. return os.listdir(path)
  205. listdir = staticmethod(listdir)
  206. def getenv(key, default=None):
  207. if sys.platform.startswith('java'):
  208. from java.lang.System import getenv
  209. return getenv(key)
  210. else:
  211. import os
  212. return os.getenv(key)
  213. getenv = staticmethod(getenv)
  214. def checkFile(fname):
  215. """open a file if it exists, otherwise die"""
  216. try:
  217. fp = open(fname, 'r+')
  218. return fp
  219. except IOError, e:
  220. raise RuntimeError(e)
  221. checkFile = staticmethod(checkFile)
  222. def fileExists(fname):
  223. """check if fname exists as a file"""
  224. if sys.platform.startswith('java'):
  225. from java.io import File
  226. return File(fname).exists()
  227. else:
  228. import os
  229. return os.path.exists(fname)
  230. fileExists = staticmethod(fileExists)
  231. def getFullPath(fname):
  232. """return canonical/absolute path of given fname"""
  233. if sys.platform.startswith('java'):
  234. from java.io import File
  235. return File(fname).getCanonicalPath()
  236. else:
  237. import os
  238. return os.path.abspath(fname)
  239. getFullPath = staticmethod(getFullPath)
  240. def copyDir(dname, target):
  241. """Recursively copy 'dname' directory to 'target'.
  242. /!\If 'target' already exists it will be removed or overwrited.
  243. """
  244. if sys.platform.startswith('java'):
  245. # import java module
  246. from java.io import File
  247. from java.io import FileInputStream
  248. from java.io import FileOutputStream
  249. from java.util import Scanner
  250. from java.lang import String
  251. dnameFile = File(dname)
  252. targetFile = File(target)
  253. # recursive copy
  254. if dnameFile.isDirectory():
  255. # Create folder if not exists
  256. if not targetFile.exists():
  257. targetFile.mkdir()
  258. # Copy all content recursively
  259. for fname in dnameFile.list().tolist():
  260. VLAB.copyDir(dname + File.separator + fname, target + File.separator + fname)
  261. else:
  262. # Read dname file
  263. istream = FileInputStream(dname)
  264. scan = Scanner(istream).useDelimiter("\\Z")
  265. # Test if file is empty
  266. if scan.hasNextLine():
  267. content = String(scan.next())
  268. else:
  269. content = String("")
  270. scan.close()
  271. # Create and write target
  272. if not targetFile.exists():
  273. targetFile.createNewFile()
  274. ostream = FileOutputStream(target)
  275. ostream.write(content.getBytes())
  276. ostream.flush()
  277. ostream.close()
  278. else:
  279. import shutil, os
  280. # remove exisiting target
  281. if os.path.isdir(target) or os.path.isfile(target):
  282. shutil.rmtree(target)
  283. # recursive copy of dnma to target
  284. shutil.copytree(dname, target)
  285. copyDir = staticmethod(copyDir)
  286. def XMLEditNode(fname, nodeName, attributName, value, multiple=False):
  287. """ Edit a given node (nodeName) in a given XML file (fname)
  288. attributName and value could be either a list of string or a string
  289. """
  290. if sys.platform.startswith('java'):
  291. from javax.xml.parsers import DocumentBuilderFactory
  292. from javax.xml.transform import TransformerFactory
  293. from javax.xml.transform import OutputKeys
  294. from javax.xml.transform.dom import DOMSource
  295. from javax.xml.transform.stream import StreamResult
  296. from java.io import File
  297. # Get whole tree
  298. tree = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(fname)
  299. # Get nodeName
  300. node = tree.getElementsByTagName(nodeName)
  301. # Check if we get only one node (as expected)
  302. if node.getLength() == 0:
  303. raise IOError("Cannot found '%s' in file '%s'" % (nodeName, fname))
  304. elif node.getLength() == 1:
  305. nodes = [node.item(0)]
  306. else:
  307. if not multiple:
  308. raise IOError("Get multiple nodes for '%s' in file '%s'" % (nodeName, fname))
  309. else:
  310. nodes = [ node.item(i) for i in xrange(node.getLength()) ]
  311. for node in nodes:
  312. # Modify the node attribute
  313. if isinstance(attributName, list) and isinstance(value, list):
  314. for att, val in zip(attributName, value):
  315. node.setAttribute(att, val)
  316. elif isinstance(attributName, str) and isinstance(value, str):
  317. node.setAttribute(attributName, value)
  318. else:
  319. raise ValueError("Wrong parameter used: attributName and value should be both either a list of string or a string")
  320. # Write new XML tree in fname
  321. transformer = TransformerFactory.newInstance().newTransformer()
  322. transformer.setOutputProperty(OutputKeys.INDENT, "yes")
  323. source = DOMSource(tree)
  324. result = StreamResult(File(fname))
  325. transformer.transform(source, result)
  326. else:
  327. import xml.etree.ElementTree as ET
  328. # Get whole tree from xml
  329. tree = ET.parse(fname)
  330. # Get nodeName
  331. #nodes = tree.findall(".//*%s" % nodeName) # This line seems to not work for root child node!! Bug?
  332. nodes = tree.findall(".//*../%s" % nodeName)
  333. # Check if we get only one node (as expected)
  334. if len(nodes) == 0:
  335. raise IOError("Cannot found '%s' in file '%s'" % (nodeName, fname))
  336. elif len(nodes) > 1 and not multiple:
  337. raise IOError("Get multiple nodes for '%s' in file '%s'" % (nodeName, fname))
  338. for node in nodes:
  339. # Modify the node attribute
  340. if isinstance(attributName, list) and isinstance(value, list):
  341. for att, val in zip(attributName, value):
  342. node.set(att, val)
  343. elif isinstance(attributName, str) and isinstance(value, str):
  344. node.set(attributName, value)
  345. else:
  346. raise ValueError("Wrong parameter used: attributName and value should be both either a list of string or a string")
  347. # Write new XML tree in fname
  348. tree.write(fname)
  349. XMLEditNode = staticmethod(XMLEditNode)
  350. def XMLReplaceNodeContent(fname, parent, subnode, attributName, value, spectralBands=False):
  351. """ Edit an XML file (fname) and replace the content of a node with subnode(s) (subnode) within attribute(s) and value(s).
  352. attributName and value could be either a list of string or a string
  353. """
  354. if sys.platform.startswith('java'):
  355. from javax.xml.parsers import DocumentBuilderFactory
  356. from javax.xml.transform import TransformerFactory
  357. from javax.xml.transform import OutputKeys
  358. from javax.xml.transform.dom import DOMSource
  359. from javax.xml.transform.stream import StreamResult
  360. from java.io import File
  361. # Get whole tree
  362. tree = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(fname)
  363. # Get nodeName
  364. node = tree.getElementsByTagName(parent)
  365. # Check if we get only one node (as expected)
  366. if node.getLength() > 1:
  367. raise IOError("Get multiple nodes for '%s' in file '%s'" % (parent, fname))
  368. elif node.getLength() == 0:
  369. raise IOError("Cannot found '%s' in file '%s'" % (parent, fname))
  370. else:
  371. node = node.item(0)
  372. # Remove content node
  373. while node.hasChildNodes():
  374. node.removeChild(node.getFirstChild())
  375. # Modify the node attribute
  376. elem = tree.createElement(subnode)
  377. if spectralBands:
  378. elem.setAttribute("bandNumber", "0")
  379. elem.setAttribute("spectralDartMode", "0")
  380. if isinstance(attributName, list) and isinstance(value, list):
  381. if isinstance(value[0], list):
  382. for bandNumber, val in enumerate(value):
  383. if spectralBands:
  384. elem.setAttribute("bandNumber", str(bandNumber))
  385. for atr, v in zip(attributName, val):
  386. elem.setAttribute(atr, v)
  387. node.appendChild(elem.cloneNode(True))
  388. else:
  389. elem = tree.createElement(subnode)
  390. for atr, v in zip(attributName, value):
  391. elem.setAttribute(atr, v)
  392. node.appendChild(elem)
  393. elif isinstance(attributName, str) and isinstance(value, str):
  394. elem = tree.createElement(subnode)
  395. elem.setAttribute(attributName, value)
  396. node.appendChild(elem)
  397. else:
  398. raise ValueError("Wrong parameter used: attributName and value should be both either a list of string or a string")
  399. # Write new XML tree in fname
  400. transformer = TransformerFactory.newInstance().newTransformer()
  401. transformer.setOutputProperty(OutputKeys.INDENT, "yes")
  402. source = DOMSource(tree)
  403. result = StreamResult(File(fname))
  404. transformer.transform(source, result)
  405. else:
  406. import xml.etree.ElementTree as ET
  407. # Get whole tree from xml
  408. tree = ET.parse(fname)
  409. # Get nodeName
  410. #nodes = tree.findall(".//*%s" % nodeName) # This line seems to not work for root child node!! Bug?
  411. node = tree.findall(".//*../%s" % parent)
  412. # Check if we get only one node (as expected)
  413. if len(node) > 1:
  414. raise IOError("Get multiple nodes for '%s' in file '%s'" % (parent, fname))
  415. elif len(node) == 0:
  416. raise IOError("Cannot found '%s' in file '%s'" % (parent, fname))
  417. else:
  418. node = node[0]
  419. # Remove content of node
  420. node.clear()
  421. # Modify the node attribute
  422. if spectralBands:
  423. attrib = {"bandNumber":"0", "spectralDartMode":"0"}
  424. else:
  425. attrib = {}
  426. if isinstance(attributName, list) and isinstance(value, list):
  427. if isinstance(value[0], list):
  428. for bandNumber, val in enumerate(value):
  429. if spectralBands:
  430. attrib["bandNumber"] = str(bandNumber)
  431. for atr, v in zip(attributName, val):
  432. attrib[atr] = v
  433. node.append(ET.Element(subnode, attrib=attrib))
  434. else:
  435. for atr, v in zip(attributName, value):
  436. attrib[atr] = v
  437. node.append(ET.Element(subnode, attrib=attrib))
  438. elif isinstance(attributName, str) and isinstance(value, str):
  439. attrib[attributName] = value
  440. node.append(ET.Element(subnode, attrib=attrib))
  441. else:
  442. raise ValueError("Wrong parameter used: attributName and value should be both either a list of string or a string")
  443. # Write new XML tree in fname
  444. tree.write(fname)
  445. XMLReplaceNodeContent = staticmethod(XMLReplaceNodeContent)
  446. def XMLAddNode(fname, parent, treeNodes, nodesSetup):
  447. """ Add a node (subnode) to a given parent in the provided fname file.
  448. """
  449. if sys.platform.startswith('java'):
  450. from javax.xml.parsers import DocumentBuilderFactory
  451. from javax.xml.transform import TransformerFactory
  452. from javax.xml.transform import OutputKeys
  453. from javax.xml.transform.dom import DOMSource
  454. from javax.xml.transform.stream import StreamResult
  455. from java.io import File
  456. # Get whole tree
  457. tree = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(fname)
  458. # Get nodeName
  459. node = tree.getElementsByTagName(parent)
  460. # Check if we get only one node (as expected)
  461. if node.getLength() > 1:
  462. raise IOError("Get multiple nodes for '%s' in file '%s'" % (parent, fname))
  463. elif node.getLength() == 0:
  464. raise IOError("Cannot found '%s' in file '%s'" % (parent, fname))
  465. else:
  466. node = node.item(0)
  467. # Create all the new nodes
  468. nodes = {parent:node}
  469. for name in treeNodes:
  470. nodes[name] = (tree.createElement(name))
  471. for atr, val in zip(*[ nodesSetup[name][key] for key in nodesSetup[name].iterkeys() if key in ["attribute", "value"] ]):
  472. nodes[name].setAttribute(atr, val)
  473. # Add all created node to its parent (previous node in the list)
  474. for name, elem in nodes.iteritems():
  475. if name != parent:
  476. nodes[nodesSetup[name]["parent"]].appendChild(elem)
  477. # Write new XML tree in fname
  478. transformer = TransformerFactory.newInstance().newTransformer()
  479. transformer.setOutputProperty(OutputKeys.INDENT, "yes")
  480. source = DOMSource(tree)
  481. result = StreamResult(File(fname))
  482. transformer.transform(source, result)
  483. else:
  484. import xml.etree.ElementTree as ET
  485. # Get whole tree from xml
  486. tree = ET.parse(fname)
  487. # Get nodeName
  488. #nodes = tree.findall(".//*%s" % nodeName) # This line seems to not work for root child node!! Bug?
  489. node = tree.findall(".//*../%s" % parent)
  490. # Check if we get only one node (as expected)
  491. if len(node) > 1:
  492. raise IOError("Get multiple nodes for '%s' in file '%s'" % (parent, fname))
  493. elif len(node) == 0:
  494. raise IOError("Cannot found '%s' in file '%s'" % (parent, fname))
  495. else:
  496. node = node[0]
  497. # Create all the new nodes
  498. nodes = {parent:node}
  499. for name in treeNodes:
  500. attrib = {}
  501. for atr, val in zip(*[ nodesSetup[name][key] for key in nodesSetup[name].iterkeys() if key in ["attribute", "value"] ]):
  502. attrib[atr] = val
  503. nodes[name] = ET.Element(name, attrib)
  504. # Add all created node to its parent (previous node in the list)
  505. for name, elem in nodes.iteritems():
  506. if name != parent:
  507. nodes[nodesSetup[name]["parent"]].append(elem)
  508. # Write new XML tree in fname
  509. tree.write(fname)
  510. XMLAddNode = staticmethod(XMLAddNode)
  511. def XMLGetNodeAttributeValue(fname, nodeName, attributName):
  512. """ Return the value of the given attributName for the given nodeName
  513. """
  514. if sys.platform.startswith('java'):
  515. from javax.xml.parsers import DocumentBuilderFactory
  516. from org.w3c.dom import Element
  517. # Get whole tree
  518. tree = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(fname)
  519. # Get nodeName
  520. node = tree.getElementsByTagName(nodeName)
  521. # Check if we get only one node (as expected)
  522. if node.getLength() > 1:
  523. raise IOError("Get multiple nodes for '%s' in file '%s'" % (nodeName, fname))
  524. elif node.getLength() == 0:
  525. raise IOError("Cannot found '%s' in file '%s'" % (nodeName, fname))
  526. else:
  527. node = node.item(0)
  528. # Check if that node has attributName
  529. if node.hasAttribute(attributName):
  530. return node.getAttributes().getNamedItem(attributName).getNodeValue()
  531. else:
  532. raise IOError("Attribute name '%s' not found for node '%s' in file '%s'" % (attributName, nodeName, fname))
  533. else:
  534. import xml.etree.ElementTree as ET
  535. # Get whole tree from xml
  536. tree = ET.parse(fname)
  537. # Get nodeName
  538. #nodes = tree.findall(".//*%s" % nodeName) # This line seems to not work for root child node!! Bug?
  539. node = tree.findall(".//*../%s[@%s]" % (nodeName, attributName))
  540. # Check if we get only one node (as expected)
  541. if len(node) > 1:
  542. raise IOError("Get multiple nodes for '%s' in file '%s'" % (nodeName, fname))
  543. elif len(node) == 0:
  544. raise IOError("Cannot found '%s' in file '%s'" % (nodeName, fname))
  545. else:
  546. node = node[0]
  547. # Check if that node has an attributName
  548. if attributName in node.keys():
  549. return node.get(attributName)
  550. else:
  551. raise IOError("Attribute name '%s' not found for node '%s' in file '%s'" % (attributName, nodeName, fname))
  552. XMLGetNodeAttributeValue = staticmethod(XMLGetNodeAttributeValue)
  553. def getBandsFromGUI(bands):
  554. """ Return a DART spectral bands list: ["deltaLambda", "meanLambda"] in micro meter
  555. In case of several bands the result should be a list of list:
  556. [["deltaLambda0", "meanLambda0"], ["deltaLambda1", "meanLambda1"], ["deltaLambda2", "meanLambda2"], ...]
  557. e.g.: [["0.02", "0.56"], ["0.02", "0.58"], ["0.02", "0.60"], ["0.02", "0.62"]]
  558. """
  559. # TODO: You should write the spectral band converter here!
  560. return [["0.02", "0.56"], ["0.02", "0.58"], ["0.02", "0.60"], ["0.02", "0.62"]]
  561. getBandsFromGUI = staticmethod(getBandsFromGUI)
  562. class path:
  563. def exists(path):
  564. if sys.platform.startswith('java'):
  565. from java.io import File
  566. return File(path).exists()
  567. else:
  568. import os
  569. return os.path.exists(path)
  570. exists = staticmethod(exists)
  571. def isabs(path):
  572. if sys.platform.startswith('java'):
  573. from java.io import File
  574. return File(path).isAbsolute()
  575. else:
  576. import os
  577. return os.path.isabs(path)
  578. isabs = staticmethod(isabs)
  579. def isdir(path):
  580. if sys.platform.startswith('java'):
  581. from java.io import File
  582. return File(path).isDirectory()
  583. else:
  584. import os
  585. return os.path.isdir(path)
  586. isdir = staticmethod(isdir)
  587. def join(path, *args):
  588. if sys.platform.startswith('java'):
  589. from java.io import File
  590. f = File(path)
  591. for a in args:
  592. g = File(a)
  593. if g.isAbsolute() or len(f.getPath()) == 0:
  594. f = g
  595. else:
  596. f = File(f, a)
  597. return f.getPath()
  598. else:
  599. import os
  600. return os.path.join(path, *args)
  601. join = staticmethod(join)
  602. def isfile(path):
  603. if sys.platform.startswith('java'):
  604. from java.io import File
  605. return File(path).isfile()
  606. else:
  607. import os
  608. return os.path.isfile(path)
  609. isfile = staticmethod(isfile)
  610. def normcase(path):
  611. if sys.platform.startswith('java'):
  612. from java.io import File
  613. return File(path).getPath()
  614. else:
  615. import os
  616. return os.path.normcase(path)
  617. normcase = staticmethod(normcase)
  618. def normpath(path):
  619. if sys.platform.startswith('java'):
  620. from java.io import File
  621. return File(path).getCanonicalPath()
  622. else:
  623. import os
  624. return os.path.normpath(path)
  625. normpath = staticmethod(normpath)
  626. def split(path):
  627. if sys.platform.startswith('java'):
  628. from java.io import File
  629. f=File(path)
  630. d=f.getParent()
  631. if not d:
  632. if f.isAbsolute():
  633. d = path
  634. else:
  635. d = ""
  636. return (d, f.getName())
  637. else:
  638. import os
  639. return os.path.split(path)
  640. split = staticmethod(split)
  641. def frange(end, start=0, inc=0):
  642. """a jython-compatible range function with float increments"""
  643. import math
  644. if not start:
  645. start = end + 0.0
  646. end = 0.0
  647. else: end += 0.0
  648. if not inc:
  649. inc = 1.0
  650. count = int(math.ceil((start - end) / inc))
  651. L = [None] * count
  652. L[0] = end
  653. for i in (xrange(1,count)):
  654. L[i] = L[i-1] + inc
  655. return L
  656. frange = staticmethod(frange)
  657. def openFileIfNotExists(filename):
  658. """open file exclusively"""
  659. if sys.platform.startswith('java'):
  660. from java.io import File
  661. File(filename).getParentFile().mkdirs()
  662. if File(filename).createNewFile():
  663. return open(filename, 'w')
  664. else:
  665. return None
  666. else:
  667. import os
  668. try:
  669. # os.O_EXCL => open exclusive => acquire a lock on the file
  670. fd = os.open(filename, os.O_CREAT|os.O_EXCL|os.O_WRONLY|os.O_TRUNC)
  671. except:
  672. return None
  673. fobj = os.fdopen(fd,'w')
  674. return fobj
  675. openFileIfNotExists = staticmethod(openFileIfNotExists)
  676. def rndInit(seed = None):
  677. """initialize the randon number generator"""
  678. if sys.platform.startswith('java'):
  679. from java.util import Random
  680. if seed == None:
  681. return Random()
  682. else:
  683. return Random(seed)
  684. else:
  685. import random
  686. random.seed(seed)
  687. return None
  688. rndInit = staticmethod(rndInit)
  689. def rndNextFloat(randState):
  690. """return the next pseudo-random floating point number in the sequence"""
  691. if sys.platform.startswith('java'):
  692. from java.util import Random
  693. return randState.nextFloat()
  694. else:
  695. import random
  696. return random.random()
  697. rndNextFloat = staticmethod(rndNextFloat)
  698. def r2d(v):
  699. """jython-compatible conversion of radians to degrees"""
  700. if sys.platform.startswith('java'):
  701. from java.lang import Math
  702. return Math.toDegrees(v)
  703. else:
  704. return math.degrees(v)
  705. r2d = staticmethod(r2d)
  706. def d2r(v):
  707. """jython-compatible conversion of degrees to radians"""
  708. if sys.platform.startswith('java'):
  709. from java.lang import Math
  710. return Math.toRadians(float(v))
  711. else:
  712. return math.radians(v)
  713. d2r = staticmethod(d2r)
  714. def mkDirPath(path):
  715. """create directory (including non-existing parents) for the given path"""
  716. if sys.platform.startswith('java'):
  717. from java.io import File
  718. if not File(path).isDirectory():
  719. if not File(path).mkdirs():
  720. raise RuntimeError('failed to mkdir %s' % path)
  721. else:
  722. import os
  723. try:
  724. os.stat(path)
  725. except:
  726. os.makedirs(path)
  727. mkDirPath = staticmethod(mkDirPath)
  728. def fPath(d,n):
  729. """get file path of the file defined by directory d and file name n"""
  730. if sys.platform.startswith('java'):
  731. from java.io import File
  732. return File(d, n).getPath()
  733. else:
  734. import os
  735. return os.path.join(d, n)
  736. fPath = staticmethod(fPath)
  737. def savetxt(a, b, fmt=False):
  738. """save text b in a text file named a"""
  739. fh = open(a, 'w')
  740. if not fmt:
  741. fmt = '%s'
  742. for row in b:
  743. for element in row:
  744. fh.write(fmt % element + ' ')
  745. fh.write('\n')
  746. fh.close()
  747. savetxt = staticmethod(savetxt)
  748. def osName():
  749. """return which OS we are currently running on"""
  750. if sys.platform.startswith('java'):
  751. from java.lang import System
  752. oname = System.getProperty('os.name')
  753. else:
  754. import os
  755. oname = os.name
  756. if not oname.endswith('x'): oname = 'Windows'
  757. return oname
  758. osName = staticmethod(osName)
  759. def expandEnv(instr):
  760. """potentially expand environment variables in the given string"""
  761. outstr = instr
  762. m = {'$HOME':'HOME','%HOMEDRIVE%':'HOMEDRIVE','%HOMEPATH%':'HOMEPATH'}
  763. for e in m:
  764. if outstr.find(e) != -1:
  765. if sys.platform.startswith('java'):
  766. from java.lang import System
  767. repl = System.getenv(m[e])
  768. else:
  769. import os
  770. repl = os.getenv(m[e])
  771. if repl != None:
  772. outstr = outstr.replace(e, repl)
  773. return outstr
  774. expandEnv = staticmethod(expandEnv)
  775. if sys.platform.startswith('java'):
  776. from java.lang import Runnable
  777. class Helper(Runnable):
  778. def __init__(self, nm, strm, fName):
  779. self.nm=nm; self.strm=strm; self.fp=None
  780. if fName != None:
  781. if VLAB.fileExists(fName):
  782. self.fp = open(fName, 'w')
  783. else:
  784. self.fp = VLAB.openFileIfNotExists(fName)
  785. def run(self):
  786. """helper class for slurping up child streams"""
  787. from java.io import BufferedReader
  788. from java.io import InputStreamReader
  789. line = None; br = BufferedReader(InputStreamReader(self.strm))
  790. line = br.readLine()
  791. while (line != None):
  792. if self.fp != None:
  793. self.fp.write(line + VLAB.lineSeparator())
  794. self.fp.flush()
  795. VLAB.logger.info('%s %s' %(self.nm, line.rstrip()))
  796. line = br.readLine()
  797. br.close()
  798. if self.fp != None:
  799. self.fp.close()
  800. else:
  801. def helper(nm, strm):
  802. """helper method for slurping up child streams"""
  803. for line in strm: VLAB.logger.info('%s %s' %(nm, line.rstrip()))
  804. if not strm.closed: strm.close()
  805. helper = staticmethod(helper)
  806. def doExec(cmdrec):
  807. """run the specified external program under windows or unix"""
  808. cmdLine = []
  809. osName = VLAB.osName()
  810. if osName.startswith('Windows'):
  811. cmd=cmdrec['windows']
  812. cmdLine = ['cmd', '/c']
  813. else:
  814. cmd=cmdrec['linux']
  815. exe = VLAB.expandEnv(cmd['exe'])
  816. if not (VLAB.fileExists(exe) or osName.startswith('Windows')):
  817. raise RuntimeError('Cannot find exe "%s"' % exe)
  818. cmdLine.append(exe)
  819. for i in cmd['cmdline']:
  820. cmdLine.append(VLAB.expandEnv(i))
  821. VLAB.logger.info('cmdLine is [%s]' % cmdLine)
  822. if sys.platform.startswith('java'):
  823. from java.lang import ProcessBuilder
  824. from java.lang import Thread
  825. from java.io import BufferedWriter
  826. from java.io import OutputStreamWriter
  827. from java.io import File
  828. pb = ProcessBuilder(cmdLine)
  829. if 'cwd' in cmd and cmd['cwd'] != None:
  830. pb.directory(File(VLAB.expandEnv(cmd['cwd'])))
  831. if 'env' in cmd and cmd['env'] != None:
  832. env = pb.environment()
  833. cmdenv = cmd['env']
  834. for e in cmdenv:
  835. env[e] = VLAB.expandEnv(cmdenv[e])
  836. proc = pb.start()
  837. stdoutfName = None
  838. if 'stdout' in cmd and cmd['stdout'] != None:
  839. stdoutfName = VLAB.expandEnv(cmd['stdout'])
  840. stderrfName = None
  841. if 'stderr' in cmd and cmd['stderr'] != None:
  842. stderrfName = VLAB.expandEnv(cmd['stderr'])
  843. outs = Thread(VLAB.Helper('out', proc.getInputStream(), stdoutfName))
  844. errs = Thread(VLAB.Helper('err', proc.getErrorStream(), stderrfName))
  845. outs.start(); errs.start()
  846. bw = BufferedWriter(OutputStreamWriter(proc.getOutputStream()))
  847. if 'stdin' in cmd and cmd['stdin'] != None:
  848. inFile = VLAB.expandEnv(cmd['stdin'])
  849. VLAB.logger.info('stdin is [%s]' % inFile)
  850. if 'cwd' in cmd and cmd['cwd'] != None:
  851. if not VLAB.fileExists(inFile):
  852. # try pre-pending the cwd
  853. inFile = VLAB.fPath(VLAB.expandEnv(cmd['cwd']), inFile)
  854. if not VLAB.fileExists(inFile):
  855. raise RuntimeError('Cannot find stdin "%s"' % cmd['cwd'])
  856. fp = open(inFile, 'r')
  857. for line in fp:
  858. bw.write(line)
  859. bw.close()
  860. fp.close()
  861. exitCode = proc.waitFor()
  862. outs.join(); errs.join()
  863. else:
  864. import threading, subprocess, os
  865. if 'cwd' in cmd and cmd['cwd'] != None:
  866. os.chdir(VLAB.expandEnv(cmd['cwd']))
  867. if 'env' in cmd and cmd['env'] != None:
  868. cmdenv = cmd['env']
  869. for e in cmdenv:
  870. os.putenv(e, VLAB.expandEnv(cmdenv[e]))
  871. if 'stdin' in cmd and cmd['stdin'] != None:
  872. proc = subprocess.Popen(cmdLine, stdin=open(VLAB.expandEnv(cmd['stdin']),'r'),stdout=subprocess.PIPE, stderr=subprocess.PIPE)
  873. else:
  874. proc = subprocess.Popen(cmdLine, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
  875. t1 = threading.Thread(target=VLAB.helper, args=('out', proc.stdout))
  876. t2 = threading.Thread(target=VLAB.helper, args=('err', proc.stderr))
  877. t1.start(); t2.start()
  878. exitCode = proc.wait()
  879. t1.join(); t2.join()
  880. VLAB.logger.info('exitCode=%d' % exitCode)
  881. doExec = staticmethod(doExec)
  882. def valuesfromfile(path, transpose=False):
  883. """Returns a 2D array with the values of the csv file at 'path'.
  884. Keyword arguments:
  885. transpose -- transpose the matrix with the values
  886. """
  887. fp = open(path)
  888. values = [line.strip().split() for line in fp
  889. if not line.startswith('#')]
  890. fp.close()
  891. values = [[float(value) for value in row] for row in values]
  892. if transpose:
  893. values = zip(*values)
  894. return values
  895. valuesfromfile = staticmethod(valuesfromfile)
  896. def fabsa(x):
  897. """Return the element-wise abs() of the given array."""
  898. return map(lambda x : math.fabs(x), x)
  899. fabsa = staticmethod(fabsa)
  900. def cosa(arcs):
  901. """Return the element-wise cos() of 'arcs' array given in degrees."""
  902. return map(lambda x : math.cos(VLAB.d2r(x)), arcs)
  903. cosa = staticmethod(cosa)
  904. def replacerectinarray(array, replacement, xul, yul, xlr, ylr):
  905. """Replace the array with the specified rectangle substituted with
  906. replacement.
  907. (array[xul:xlr,yul:ylr])
  908. +---------------+
  909. |(xul, yul) |
  910. | |
  911. | (xlr, ylr)|
  912. +---------------+
  913. """
  914. ri = 0
  915. for x in xrange(xul, xlr):
  916. array[x][yul:ylr] = replacement[ri]
  917. ri += 1
  918. return array
  919. replacerectinarray = staticmethod(replacerectinarray)
  920. def replaceinarray(haystack, predicate, replacement):
  921. """Return 'haystack' with 'predicate' matches replaced by 'replacement'"""
  922. return map(lambda item : {True: replacement, False: item}[predicate(item)],
  923. haystack)
  924. replaceinarray = staticmethod(replaceinarray)
  925. def sqrta(values):
  926. """Return the element-wise sqrt() of the given array."""
  927. return map(math.sqrt, values)
  928. sqrta = staticmethod(sqrta)
  929. def suba(lista, listb):
  930. """Subtract the values of a list from the values of another list."""
  931. if len(lista) != len(listb):
  932. raise ValueError("Arguments have to be of same length.")
  933. return map(operator.sub, lista, listb)
  934. suba = staticmethod(suba)
  935. def adda(lista, listb):
  936. """Add the values of a list to the values of another list."""
  937. if len(lista) != len(listb):
  938. raise ValueError("Arguments have to be of same length.")
  939. return map(operator.add, lista, listb)
  940. adda = staticmethod(adda)
  941. def diva(lista, listb):
  942. """Return the element-wise division of 'lista' by 'listb'."""
  943. if len(lista) != len(listb):
  944. raise ValueError("Arguments have to be of same length.")
  945. return map(operator.div, lista, listb)
  946. diva = staticmethod(diva)
  947. def mula(lista, listb):
  948. """Return the element-wise multiplication of 'lista' with 'listb'."""
  949. if len(lista) != len(listb):
  950. raise ValueError("Arguments have to be of same length.")
  951. return map(operator.mul, lista, listb)
  952. mula = staticmethod(mula)
  953. def powa(values, exponent):
  954. """Returns the element-wise exp('exponent') of the given array."""
  955. if isinstance(exponent, (list, tuple)):
  956. return map(lambda x, y : x ** y, values, exponent)
  957. return map(lambda x : x ** exponent, values)
  958. powa = staticmethod(powa)
  959. def treemap(fn, tree):
  960. """Applies `fn' to every value in `tree' which isn't a list and
  961. returns a list with the same shape as tree and the value of `fn'
  962. applied to the values in their place.
  963. """
  964. result = []
  965. for node in tree:
  966. if isinstance(node, (list, tuple)):
  967. result += [VLAB.treemap(fn, node)]
  968. else:
  969. result += [fn(node)]
  970. return result
  971. treemap = staticmethod(treemap)
  972. def makemaskeq(array, value):
  973. return VLAB.treemap(lambda x : x == value, array)
  974. makemaskeq = staticmethod(makemaskeq)
  975. def awhere(mask):
  976. """Returns the coordinates of the cells which evaluate true."""
  977. result = []
  978. if isinstance(mask, (list, tuple)):
  979. for i, cell in enumerate(mask):
  980. result += [[i] + sub for sub in VLAB.awhere(cell)
  981. if isinstance(sub, (list, tuple))]
  982. return result
  983. else:
  984. if mask:
  985. return [[]]
  986. else:
  987. return []
  988. awhere = staticmethod(awhere)
  989. def aclone(tree):
  990. """Make a deep copy of `tree'."""
  991. if isinstance(tree, (list, tuple)):
  992. return list(map(VLAB.aclone, tree))
  993. return tree
  994. aclone = staticmethod(aclone)
  995. def make_chart(title, x_label, y_label, dataset):
  996. """Helper for creating Charts"""
  997. if sys.platform.startswith('java'):
  998. from org.jfree.chart import ChartFactory, ChartFrame, ChartUtilities
  999. from org.jfree.chart.axis import NumberTickUnit
  1000. from org.jfree.chart.plot import PlotOrientation
  1001. from org.jfree.data.xy import XYSeries, XYSeriesCollection
  1002. chart = ChartFactory.createScatterPlot(title, x_label, y_label, dataset,
  1003. PlotOrientation.VERTICAL, True,
  1004. True, False)
  1005. plot = chart.getPlot()
  1006. domain_axis = plot.getDomainAxis()
  1007. domain_axis.setRange(-70, 70)
  1008. range_axis = plot.getRangeAxis()
  1009. range_axis.setRange(0.0, 0.4)
  1010. range_axis.setTickUnit(NumberTickUnit(0.05))
  1011. return chart
  1012. else:
  1013. # TODO: re-merge original python implementation
  1014. raise Exception("original make_chart()")
  1015. return None
  1016. make_chart = staticmethod(make_chart)
  1017. def make_dataset():
  1018. """Dataset helper for supporting chart creation"""
  1019. if sys.platform.startswith('java'):
  1020. from org.jfree.data.xy import XYSeriesCollection
  1021. return XYSeriesCollection()
  1022. else:
  1023. # TODO: re-merge original python implementation
  1024. raise Exception("original make_dataset()")
  1025. return None
  1026. make_dataset = staticmethod(make_dataset)
  1027. def plot(dataset, x, y, label):
  1028. """plot dataset with x and y values and the given label"""
  1029. if sys.platform.startswith('java'):
  1030. from org.jfree.data.xy import XYSeries
  1031. series = XYSeries(label)
  1032. for next_x, next_y in zip(x, y):
  1033. series.add(float(next_x), float(next_y))
  1034. dataset.addSeries(series)
  1035. else:
  1036. # TODO: re-merge original python implementation
  1037. raise Exception("original plot()")
  1038. return None
  1039. plot = staticmethod(plot)
  1040. def save_chart(chart, filename):
  1041. """save the generated chart in the given filename"""
  1042. if sys.platform.startswith('java'):
  1043. from java.io import File
  1044. from org.jfree.chart import ChartUtilities
  1045. ChartUtilities.saveChartAsPNG(File(filename), chart, 800, 600)
  1046. else:
  1047. # TODO: re-merge original python implementation
  1048. raise Exception("save_chart")
  1049. pass
  1050. save_chart = staticmethod(save_chart)
  1051. def maskand(array, mask):
  1052. return map(lambda a, b : a & b, array, mask)
  1053. maskand = staticmethod(maskand)
  1054. def unique(array):
  1055. """return unique values in the given input array"""
  1056. sortedarray = list(array)
  1057. sortedarray.sort()
  1058. result = []
  1059. def addifunique(x, y):
  1060. if x != y:
  1061. result.append(x)
  1062. return y
  1063. result.append(reduce(addifunique, sortedarray))
  1064. return result
  1065. unique = staticmethod(unique)
  1066. def ravel(a):
  1067. def add(a, i):
  1068. if not(isinstance(a, (list, tuple))):
  1069. a = [a]
  1070. if isinstance(i, (list, tuple)):
  1071. return a + ravel(i)
  1072. else:
  1073. return a + [i]
  1074. return reduce(add, a)
  1075. ravel = staticmethod(ravel)
  1076. def min_l_bfgs_b(f, initial_guess, args=(), bounds=None, epsilon=1e-8):
  1077. """The `approx_grad' is not yet implemented, because it's not yet
  1078. used."""
  1079. if sys.platform.startswith('java'):
  1080. from java.lang import ClassLoader
  1081. from java.io import File
  1082. for path in sys.path:
  1083. if path.endswith('.jar'):
  1084. libdir = File(path).getParent()
  1085. break
  1086. VLAB.logger.info(libdir)
  1087. # hack taken from: http://blog.cedarsoft.com/2010/11/setting-java-library-path-programmatically
  1088. System.setProperty("java.library.path", libdir)
  1089. syspathfield = ClassLoader.getDeclaredField("sys_paths")
  1090. syspathfield.setAccessible(True);
  1091. syspathfield.set(None, None)
  1092. from lbfgsb import DifferentiableFunction, FunctionValues, Bound, Minimizer
  1093. class function(DifferentiableFunction):
  1094. def __init__(self, function, args=()):
  1095. self.function = function
  1096. self.args = args
  1097. def getValues(self, x):
  1098. f = self.function(x, *self.args)
  1099. g = VLAB.approx_fprime(x, self.function, epsilon, *self.args)
  1100. return FunctionValues(f, g)
  1101. min = Minimizer()
  1102. min.setBounds([Bound(bound[0], bound[1]) for bound in bounds])
  1103. result = min.run(function(f, args), VLAB.ravel(initial_guess))
  1104. return result.point
  1105. min_l_bfgs_b = staticmethod(min_l_bfgs_b)
  1106. def approx_fprime(xk, f, epsilon, *args):
  1107. f0 = f(xk, *args)
  1108. grad = [0. for i in xrange(len(xk))]
  1109. ei = [0. for i in xrange(len(xk))]
  1110. for k in xrange(len(xk)):
  1111. ei[k] = 1.0
  1112. d = map(lambda i : i * epsilon, ei)
  1113. grad[k] = (f(VLAB.adda(xk, d), *args) - f0) / d[k]
  1114. ei[k] = 0.0
  1115. return grad
  1116. approx_fprime = staticmethod(approx_fprime)
  1117. def doLibradtran(args):
  1118. q = {
  1119. 'rpv_file': args['rpv_file'],
  1120. 'outfile' : args['outfile'],
  1121. 'infile' : args['infile'],
  1122. }
  1123. for k in args:
  1124. q[k] = args[k]
  1125. if args['scene'] == VLAB.K_LAEGERN:
  1126. q['latitude'] = '47.481667'
  1127. q['longitude'] = '-8.394722,17'
  1128. elif args['scene'] == VLAB.K_THARANDT:
  1129. q['latitude'] = '50.9676498'
  1130. q['longitude'] = '-13.520354'
  1131. if args['aerosol'] == VLAB.K_RURAL:
  1132. q['aerosol'] = '1'
  1133. elif args['aerosol'] == VLAB.K_MARITIME:
  1134. q['aerosol'] = '2'
  1135. elif args['aerosol'] == VLAB.K_URBAN:
  1136. q['aerosol'] = '5'
  1137. elif args['aerosol'] == VLAB.K_TROPOSPHERIC:
  1138. q['aerosol'] = '6'
  1139. # TODO: verify these
  1140. if args['sensor'] == VLAB.K_SENTINEL2:
  1141. q['wavelength'] = '443 2190'
  1142. elif args['sensor'] == VLAB.K_SENTINEL3:
  1143. q['wavelength'] = '400 2400'
  1144. elif args['sensor'] == VLAB.K_MODIS:
  1145. q['wavelength'] = '405 2155'
  1146. elif args['sensor'] == VLAB.K_MERIS:
  1147. q['wavelength'] = '412 900'
  1148. elif args['sensor'] == VLAB.K_LANDSAT_OLI:
  1149. q['wavelength'] = '433 2300'
  1150. elif args['sensor'] == VLAB.K_LANDSAT_ETM:
  1151. q['wavelength'] = '450 2300'
  1152. if VLAB.osName().startswith('Windows'):
  1153. q['solar_file'] = VLAB.expandEnv('%HOMEDRIVE%%HOMEPATH%\\.beam\\beam-vlab\\auxdata\\libRadtran_win32\\data\\solar_flux\\NewGuey2003.day')
  1154. else:
  1155. q['solar_file'] = VLAB.expandEnv('$HOME/.beam/beam-vlab/auxdata/libRadtran_lin64/data/solar_flux/NewGuey2003.dat')
  1156. sdata = """
  1157. solar_file %s
  1158. correlated_k LOWTRAN
  1159. rte_solver cdisort
  1160. rpv_file %s
  1161. deltam on
  1162. nstr 6
  1163. zout TOA
  1164. output_user lambda uu
  1165. quiet
  1166. """ % (q['solar_file'],
  1167. q['rpv_file'])
  1168. if 'aerosol' in q:
  1169. sdata += "aerosol_default\n"
  1170. sdata += "aerosol_haze %s\n" % (q['aerosol'])
  1171. if 'O3' in q:
  1172. sdata += "dens_column O3 %s\n" % (q['O3'])
  1173. if 'CO2' in q:
  1174. sdata += "co2_mixing_ratio %s\n" % (q['CO2'])
  1175. if 'H2O' in q:
  1176. sdata += "h2o_mixing_ratio %s\n" % (q['H2O'])
  1177. if 'umu' in q:
  1178. sdata += "umu %s\n" % (q['umu'])
  1179. if 'phi' in q:
  1180. sdata += "phi %s\n" % (q['phi'])
  1181. if 'latitude' in q:
  1182. sdata += "latitude %s\n" % (q['latitude'])
  1183. if 'longitude' in q:
  1184. sdata += "longitude %s\n" % (q['longitude'])
  1185. if 'time' in q:
  1186. sdata += "time %s\n" % (q['time'])
  1187. if 'sza' in q:
  1188. sdata += "sza %s\n" % (q['sza'])
  1189. if 'phi0' in q:
  1190. sdata += "phi0 %s\n" % (q['phi0'])
  1191. if 'wavelength' in q:
  1192. sdata += "wavelength %s\n" % (q['wavelength'])
  1193. fp = open(q['infile'], 'w')
  1194. fp.write(sdata)
  1195. fp.close()
  1196. cmd = {
  1197. 'linux' : {
  1198. 'cwd' : '$HOME/.beam/beam-vlab/auxdata/libRadtran_lin64/examples',
  1199. 'exe' : '$HOME/.beam/beam-vlab/auxdata/libRadtran_lin64/bin/uvspec',
  1200. 'cmdline' : [],
  1201. 'stdin' : q['infile'],
  1202. 'stdout' : q['outfile'],
  1203. 'stderr' : None,
  1204. 'env' : None
  1205. },
  1206. 'windows' : {
  1207. 'cwd' : '%HOMEDRIVE%%HOMEPATH%\\.beam\\beam-vlab\\auxdata\\libRadtran_win32\\examples',
  1208. 'exe' : '%HOMEDRIVE%%HOMEPATH%\\.beam\\beam-vlab\\auxdata\\libRadtran_win32\\uvspec.exe',
  1209. 'cmdline' : [],
  1210. 'stdin' : q['infile'],
  1211. 'stdout' : q['outfile'],
  1212. 'stderr' : None,
  1213. 'env' : None
  1214. }
  1215. }
  1216. VLAB.logger.info('%s: spawning libradtran...' % VLAB.me())
  1217. VLAB.doExec(cmd)
  1218. doLibradtran = staticmethod(doLibradtran)
  1219. ###########################################################################
  1220. #
  1221. # Minimize_* functions...
  1222. #
  1223. # Nelder-Mead simplex minimization of a nonlinear (multivariate) function.
  1224. #
  1225. # The programming interface is via the minimize() function; see below.
  1226. #
  1227. # This code has been adapted from the C-coded nelmin.c which was
  1228. # adapted from the Fortran-coded nelmin.f which was, in turn, adapted
  1229. # from the papers
  1230. #
  1231. # J.A. Nelder and R. Mead (1965)
  1232. # A simplex method for function minimization.
  1233. # Computer Journal, Volume 7, pp 308-313.
  1234. #
  1235. # R. O'Neill (1971)
  1236. # Algorithm AS47. Function minimization using a simplex algorithm.
  1237. # Applied Statistics, Volume 20, pp 338-345.
  1238. #
  1239. # and some examples are in
  1240. #
  1241. # D.M. Olsson and L.S. Nelson (1975)
  1242. # The Nelder-Mead Simplex procedure for function minimization.
  1243. # Technometrics, Volume 17 No. 1, pp 45-51.
  1244. #
  1245. # For a fairly recent and popular incarnation of this minimizer,
  1246. # see the amoeba function in the famous "Numerical Recipes" text.
  1247. #
  1248. # P. Jacobs
  1249. # School of Engineering, The University of Queensland
  1250. # 07-Jan-04
  1251. #
  1252. # Modifications by C. Schenkel
  1253. # Netcetera
  1254. # 31-Oct-13
  1255. #
  1256. ###########################################################################
  1257. def Minimize_create_new_point(c1, p1, c2, p2):
  1258. """
  1259. Create a new N-dimensional point as a weighting of points p1 and p2.
  1260. """
  1261. p_new = []
  1262. for j in range(len(p1)):
  1263. p_new.append(c1 * p1[j] + c2 * p2[j])
  1264. return p_new
  1265. Minimize_create_new_point = staticmethod(Minimize_create_new_point)
  1266. def Minimize_take_a_step(smplx, Kreflect, Kextend, Kcontract):
  1267. """
  1268. Try to move away from the worst point in the simplex.
  1269. The new point will be inserted into the simplex (in place).
  1270. """
  1271. i_low = smplx.lowest()
  1272. i_high = smplx.highest()
  1273. x_high = smplx.vertex_list[i_high]
  1274. f_high = smplx.f_list[i_high]
  1275. # Centroid of simplex excluding worst point.
  1276. x_mid = smplx.centroid(i_high)
  1277. f_mid = smplx.f(x_mid)
  1278. smplx.nfe += 1
  1279. # First, try moving away from worst point by
  1280. # reflection through centroid
  1281. x_refl = VLAB.Minimize_create_new_point(1.0+Kreflect, x_mid, -Kreflect, x_high)
  1282. f_refl = smplx.f(x_refl)
  1283. smplx.nfe += 1
  1284. if f_refl < f_mid:
  1285. # The reflection through the centroid is good,
  1286. # try to extend in the same direction.
  1287. x_ext = VLAB.Minimize_create_new_point(Kextend, x_refl, 1.0-Kextend, x_mid)
  1288. f_ext = smplx.f(x_ext)
  1289. smplx.nfe += 1
  1290. if f_ext < f_refl:
  1291. # Keep the extension because it's best.
  1292. smplx.replace_vertex(i_high, x_ext, f_ext)
  1293. else:
  1294. # Settle for the original reflection.
  1295. smplx.replace_vertex(i_high, x_refl, f_refl)
  1296. else:
  1297. # The reflection is not going in the right direction, it seems.
  1298. # See how many vertices are better than the reflected point.
  1299. count = 0
  1300. for i in range(smplx.N+1):
  1301. if smplx.f_list[i] > f_refl: count += 1
  1302. if count <= 1:
  1303. # Not too many points are higher than the original reflection.
  1304. # Try a contraction on the reflection-side of the centroid.
  1305. x_con = VLAB.Minimize_create_new_point(1.0-Kcontract, x_mid, Kcontract, x_high)
  1306. f_con = smplx.f(x_con)
  1307. smplx.nfe += 1
  1308. if f_con < f_high:
  1309. # At least we haven't gone uphill; accept.
  1310. smplx.replace_vertex(i_high, x_con, f_con)
  1311. else:
  1312. # We have not been successful in taking a single step.
  1313. # Contract the simplex about the current lowest point.
  1314. smplx.contract_about_one_point(i_low)
  1315. else:
  1316. # Retain the original reflection because there are many
  1317. # vertices with higher values of the objective function.
  1318. smplx.replace_vertex(i_high, x_refl, f_refl)
  1319. return
  1320. Minimize_take_a_step = staticmethod(Minimize_take_a_step)
  1321. def Minimize_minimize(f, x, dx=None, tol=1.0e-6,
  1322. maxfe=300, n_check=20, delta=0.001,
  1323. Kreflect=1.0, Kextend=2.0, Kcontract=0.5, args=()):
  1324. """
  1325. Locate a minimum of the objective function, f.
  1326. Input:
  1327. f : user-specified function f(x)
  1328. x : list of N coordinates
  1329. args : Extra arguments passed to f, i.e. ``f(x, *args)''.
  1330. dx : list of N increments to apply to x when forming
  1331. the initial simplex. Their magnitudes determine the size
  1332. and shape of the initial simplex.
  1333. tol : the terminating limit for the standard-deviation
  1334. of the simplex function values.
  1335. maxfe : maximum number of function evaluations that we will allow
  1336. n_check : number of steps between convergence checks
  1337. delta : magnitude of the perturbations for checking a local minimum
  1338. and for the scale reduction when restarting
  1339. Kreflect, Kextend, Kcontract: coefficients for locating the new vertex
  1340. Output:
  1341. Returns a tuple consisting of
  1342. [0] a list of coordinates for the best x location,
  1343. corresponding to min(f(x)),
  1344. [1] the function value at that point,
  1345. [2] a flag to indicate if convergence was achieved
  1346. [3] the number of function evaluations and
  1347. [4] the number of restarts (with scale reduction)
  1348. """
  1349. converged = 0
  1350. N = len(x)
  1351. if dx == None:
  1352. dx = [0.1] * N
  1353. smplx = Minimize_NMSimplex(x, dx, f, args)
  1354. while (not converged) and (smplx.nfe < maxfe):
  1355. # Take some steps and then check for convergence.
  1356. for i in range(n_check):
  1357. VLAB.Minimize_take_a_step(smplx, Kreflect, Kextend, Kcontract)
  1358. # Pick out the current best vertex.
  1359. i_best = smplx.lowest()
  1360. x_best = list(smplx.get_vertex(i_best))
  1361. f_best = smplx.f_list[i_best]
  1362. # Check the scatter of vertex values to see if we are
  1363. # close enough to call it quits.
  1364. mean, stddev = smplx.f_statistics()
  1365. if stddev < tol:
  1366. # All of the points are close together but we need to
  1367. # test more carefully.
  1368. converged = smplx.test_for_minimum(i_best, delta)
  1369. if not converged:
  1370. # The function evaluations are all very close together
  1371. # but we are not at a true minimum; rescale the simplex.
  1372. smplx.rescale(delta)
  1373. return x_best, f_best, converged, smplx.nfe, smplx.nrestarts
  1374. Minimize_minimize = staticmethod(Minimize_minimize)
  1375. #
  1376. # from here to "VLAB end" is used only for testing
  1377. #
  1378. def fakebye(self, event):
  1379. """fake beam callback for existing the program"""
  1380. me=self.__class__.__name__ +'::'+VLAB.me()
  1381. VLAB.logger.info('%s: exiting' % me)
  1382. sys.exit()
  1383. def fakeDoProcessing(self, params):
  1384. """fake beam helper for driving processing in test mode"""
  1385. me=self.__class__.__name__ +'::'+VLAB.me()
  1386. VLAB.logger.info('%s: starting' % me)
  1387. VLAB.logger.info('params: %s' % params)
  1388. if params[VLAB.P_RTProcessor] == VLAB.K_DART:
  1389. rtProcessor = DART()
  1390. elif params[VLAB.P_RTProcessor] == VLAB.K_LIBRAT:
  1391. rtProcessor = LIBRAT()
  1392. elif params[VLAB.P_RTProcessor] == VLAB.K_DUMMY:
  1393. rtProcessor = DUMMY()
  1394. else:
  1395. raise RuntimeError('unknown processor: <%s>' % params[VLAB.P_RTProcessor])
  1396. rtProcessor.doProcessing(None, params)
  1397. VLAB.logger.info('%s : %s' % (me, 'finished'))
  1398. def fakerun(self, event):
  1399. """fake beam callback for running a processor"""
  1400. me=self.__class__.__name__ +'::'+VLAB.me()
  1401. VLAB.logger.info('%s: starting' % me)
  1402. params = {}
  1403. for i in self.plst:
  1404. if type(self.vmap[i]) == str:
  1405. params[i] = self.cmap[i].text
  1406. elif type(self.vmap[i]) == tuple:
  1407. lst = self.vmap[i]
  1408. params[i] = lst[self.cmap[i].selectedIndex]
  1409. self.fakeDoProcessing(params)
  1410. def fakebeam(self):
  1411. """fake beam Swing GUI"""
  1412. me=self.__class__.__name__ +'::'+VLAB.me()
  1413. VLAB.logger.info('%s: starting' % me)
  1414. from javax import swing
  1415. from java import awt
  1416. v = 5; h = 10; self.window = swing.JFrame(VLAB.PROCESSOR_NAME)
  1417. self.window.windowClosing = self.fakebye
  1418. self.window.contentPane.layout = awt.BorderLayout()
  1419. tabbedPane = swing.JTabbedPane()
  1420. self.window.contentPane.add("Center", tabbedPane)
  1421. for tabGroups in VLAB.model:
  1422. for tabName in tabGroups:
  1423. tab = swing.JPanel()
  1424. tab.layout = swing.BoxLayout(tab, swing.BoxLayout.PAGE_AXIS)
  1425. tabbedPane.addTab(tabName, tab)
  1426. for group in tabGroups[tabName]:
  1427. tab.add(swing.JLabel(''))
  1428. p = swing.JPanel()
  1429. p.layout = awt.GridLayout(0, 4);
  1430. p.layout.vgap = v;p.layout.hgap = h
  1431. for groupName in group:
  1432. p.border = swing.BorderFactory.createTitledBorder(groupName)
  1433. for groupTuple in group[groupName]:
  1434. if len(groupTuple) == 4:
  1435. (lbl, nm, typ, vals) = groupTuple
  1436. p.add(swing.JLabel(lbl+':', swing.SwingConstants.RIGHT))
  1437. self.vmap[nm] = vals
  1438. if type(vals) == tuple:
  1439. self.cmap[nm] = swing.JComboBox(self.vmap[nm])
  1440. else:
  1441. if type(typ) == tuple:
  1442. exec('self.cmap[nm] = swing.'+typ[0]+'(self.vmap[nm])')
  1443. self.cmap[nm].setEditable(typ[1])
  1444. else:
  1445. exec('self.cmap[nm] = swing.'+typ+'(self.vmap[nm])')
  1446. self.plst.append(nm)
  1447. p.add(self.cmap[nm])
  1448. else:
  1449. p.add(swing.JLabel(""))
  1450. p.add(swing.JLabel(""))
  1451. tab.add(p)
  1452. # hack
  1453. for i in range(50):
  1454. tab.add(swing.Box.createVerticalGlue())
  1455. tab.add(swing.JLabel(''))
  1456. p = swing.JPanel()
  1457. p.layout = awt.GridLayout(0, 8)
  1458. p.layout.hgap = 4
  1459. for i in range(1,5):
  1460. p.add(swing.JLabel(""))
  1461. p.add(swing.JButton("Run", actionPerformed=self.fakerun))
  1462. p.add(swing.JButton("Close", actionPerformed=self.fakebye))
  1463. p.add(swing.JButton("Help"))
  1464. tab.add(p)
  1465. self.window.pack(); self.window.show()
  1466. # TESTS
  1467. def selftests(self):
  1468. """run a pre-defined set of tests"""
  1469. me=self.__class__.__name__ +'::'+VLAB.me()
  1470. VLAB.logger.info('%s: starting' % me)
  1471. # scenario 1
  1472. params = {
  1473. VLAB.P_3dScene : 'RAMI',
  1474. VLAB.P_AtmosphereCO2 : '1.6',
  1475. VLAB.P_ViewingAzimuth : '0.0',
  1476. VLAB.P_AtmosphereWater : '0.0',
  1477. VLAB.P_OutputPrefix : 'RAMI_',
  1478. VLAB.P_ViewingZenith : '20.0',
  1479. VLAB.P_AtmosphereAerosol : 'Rural',
  1480. VLAB.P_DHP_Zenith : '20.0',
  1481. VLAB.P_SceneYW : '100',
  1482. VLAB.P_DHP_3dScene : 'RAMI',
  1483. VLAB.P_Bands : '1, 2, 3, 4, 5, 6, 7, 8, 9, 10',
  1484. VLAB.P_OutputDirectory : '',
  1485. VLAB.P_AtmosphereOzone : '300',
  1486. VLAB.P_SceneLocFile : '',
  1487. VLAB.P_SceneYC : '100',
  1488. VLAB.P_DHP_OutputDirectory : '',
  1489. VLAB.P_DHP_OutputPrefix : 'RAMI00_',
  1490. VLAB.P_RTProcessor : VLAB.K_DUMMY,
  1491. VLAB.P_SceneXW : '50',
  1492. VLAB.P_IlluminationAzimuth : '0.0',
  1493. VLAB.P_Sensor : 'MSI (Sentinel 2)',
  1494. VLAB.P_AsciiFile : 'Yes',
  1495. VLAB.P_ImageFile : 'Yes',
  1496. VLAB.P_SceneXC : '-50',
  1497. VLAB.P_DHP_Y : '0',
  1498. VLAB.P_DHP_X : '0',
  1499. VLAB.P_DHP_ImageFile : 'Yes',
  1500. VLAB.P_DHP_AsciiFile : 'Yes',
  1501. VLAB.P_DHP_Resolution : '100x100',
  1502. VLAB.P_DHP_Azimuth : '0.0',
  1503. VLAB.P_IlluminationZenith : '20.0',
  1504. VLAB.P_DHP_RTProcessor : VLAB.K_DUMMY,
  1505. VLAB.P_DHP_Height : '0',
  1506. VLAB.P_DHP_Orientation : '0',
  1507. VLAB.P_ScenePixel : '8'
  1508. }
  1509. self.fakeDoProcessing(params)
  1510. # scenario 2
  1511. params[VLAB.P_RTProcessor] = VLAB.K_LIBRAT
  1512. self.fakeDoProcessing(params)
  1513. # scenario 3
  1514. params[VLAB.P_RTProcessor] = VLAB.K_DART
  1515. self.fakeDoProcessing(params)
  1516. #### VLAB end ################################################################
  1517. class Minimize_NMSimplex:
  1518. """
  1519. Stores the (nonlinear) simplex as a list of lists.
  1520. In an N-dimensional problem, each vertex is a list of N coordinates
  1521. and the simplex consists of N+1 vertices.
  1522. """
  1523. def __init__(self, x, dx, f, args):
  1524. """
  1525. Initialize the simplex.
  1526. Set up the vertices about the user-specified vertex, x,
  1527. and the set of step-sizes dx.
  1528. f is a user-specified objective function f(x).
  1529. """
  1530. self.N = len(x)
  1531. self.vertex_list = []
  1532. self.f_list = []
  1533. self.dx = list(dx)
  1534. self.f = lambda x : f(x, *args)
  1535. self.nfe = 0
  1536. self.nrestarts = 0
  1537. for i in range(self.N + 1):
  1538. p = list(x)
  1539. if i >= 1: p[i-1] += dx[i-1]
  1540. self.vertex_list.append(p)
  1541. self.f_list.append(f(p, *args))
  1542. self.nfe += 1
  1543. def rescale(self, ratio):
  1544. """
  1545. Pick out the current minimum and rebuild the simplex about that point.
  1546. """
  1547. i_min = self.lowest()
  1548. for i in range(self.N):
  1549. self.dx[i] *= ratio
  1550. x = self.get_vertex(i_min)
  1551. self.vertex_list = []
  1552. self.f_list = []
  1553. for i in range(self.N + 1):
  1554. p = list(x)
  1555. if i >= 1: p[i-1] += self.dx[i-1]
  1556. self.vertex_list.append(p)
  1557. self.f_list.append(self.f(p))
  1558. self.nfe += 1
  1559. self.nrestarts += 1
  1560. return
  1561. def get_vertex(self, i):
  1562. return list(self.vertex_list[i])
  1563. def replace_vertex(self, i, x, fvalue):
  1564. self.vertex_list[i] = list(x)
  1565. self.f_list[i] = fvalue
  1566. return
  1567. def lowest(self, exclude=-1):
  1568. """
  1569. Returns the index of the lowest vertex, excluding the one specified.
  1570. """
  1571. if exclude == 0:
  1572. indx = 1
  1573. else:
  1574. indx = 0
  1575. lowest_f_value = self.f_list[indx]
  1576. for i in range(self.N + 1):
  1577. if i == exclude: continue
  1578. if self.f_list[i] < lowest_f_value:
  1579. lowest_f_value = self.f_list[i]
  1580. indx = i
  1581. return indx
  1582. def highest(self, exclude=-1):
  1583. """
  1584. Returns the index of the highest vertex, excluding the one specified.
  1585. """
  1586. if exclude == 0:
  1587. indx = 1
  1588. else:
  1589. indx = 0
  1590. highest_f_value = self.f_list[indx]
  1591. for i in range(self.N + 1):
  1592. if i == exclude: continue
  1593. if self.f_list[i] > highest_f_value:
  1594. highest_f_value = self.f_list[i]
  1595. indx = i
  1596. return indx
  1597. def f_statistics(self):
  1598. """
  1599. Returns mean and standard deviation of the vertex fn values.
  1600. """
  1601. sum = 0.0
  1602. for i in range(self.N + 1):
  1603. sum += self.f_list[i]
  1604. mean = sum / (self.N + 1)
  1605. sum = 0.0
  1606. for i in range(self.N +1):
  1607. diff = self.f_list[i] - mean
  1608. sum += diff * diff
  1609. std_dev = math.sqrt(sum / self.N)
  1610. return mean, std_dev
  1611. def centroid(self, exclude=-1):
  1612. """
  1613. Returns the centroid of all vertices excluding the one specified.
  1614. """
  1615. xmid = [0.0]*self.N
  1616. for i in range(self.N + 1):
  1617. if i == exclude: continue
  1618. for j in range(self.N):
  1619. xmid[j] += self.vertex_list[i][j]
  1620. for j in range(self.N):
  1621. xmid[j] /= self.N
  1622. return xmid
  1623. def contract_about_one_point(self, i_con):
  1624. """
  1625. Contract the simplex about the vertex i_con.
  1626. """
  1627. p_con = self.vertex_list[i_con]
  1628. for i in range(self.N + 1):
  1629. if i == i_con: continue
  1630. p = self.vertex_list[i]
  1631. for j in range(self.N):
  1632. p[j] = 0.5 * (p[j] + p_con[j])
  1633. self.f_list[i] = self.f(p)
  1634. self.nfe += 1
  1635. return
  1636. def test_for_minimum(self, i_min, delta):
  1637. """
  1638. Perturb the minimum vertex and check that it is a local minimum.
  1639. """
  1640. is_minimum = 1 # Assume it is true and test for failure.
  1641. f_min = self.f_list[i_min]
  1642. for j in range(self.N):
  1643. # Check either side of the minimum, perturbing one
  1644. # coordinate at a time.
  1645. p = self.get_vertex(i_min)
  1646. p[j] += self.dx[j] * delta
  1647. f_p = self.f(p)
  1648. self.nfe += 1
  1649. if f_p < f_min:
  1650. is_minimum = 0
  1651. break
  1652. p[j] -= self.dx[j] * delta * 2
  1653. f_p = self.f(p)
  1654. self.nfe += 1
  1655. if f_p < f_min:
  1656. is_minimum = 0
  1657. break
  1658. return is_minimum
  1659. #
  1660. # end Minimize_NMSimplex
  1661. #
  1662. #### DUMMY start #############################################################
  1663. class DUMMY:
  1664. """A dummy processor for testing the VLAB plugin """
  1665. def __init__(self):
  1666. me=self.__class__.__name__ +'::'+VLAB.me()
  1667. VLAB.logger.info('%s: constructor completed...' % me)
  1668. def doProcessing(self, pm, args):
  1669. """do processing for DUMMY processor"""
  1670. me=self.__class__.__name__ +'::'+VLAB.me()
  1671. VLAB.logger.info('%s: doExec() on %s' % (me, args))
  1672. cmd = {
  1673. 'linux' : {
  1674. 'cwd' : '$HOME/.beam/beam-vlab/auxdata/dummy_lin64/',
  1675. 'exe' : '$HOME/.beam/beam-vlab/auxdata/dummy_lin64/dummy',
  1676. 'cmdline' : [ '-e', '1', '-r', '5' ],
  1677. 'stdin' : None,
  1678. 'stdout' : None,
  1679. 'stderr' : None,
  1680. 'env' : None
  1681. },
  1682. 'windows' : {
  1683. 'cwd' : '%HOMEDRIVE%%HOMEPATH%/.beam/beam-vlab/auxdata/dummy_win32',
  1684. 'exe' : '%HOMEDRIVE%%HOMEPATH%/.beam/beam-vlab/auxdata/dummy_win32//dummy.exe',
  1685. 'cmdline' : [ '-e', '1', '-r', '5' ],
  1686. 'stdin' : None,
  1687. 'stdout' : None,
  1688. 'stderr' : None,
  1689. 'env' : None
  1690. }
  1691. }
  1692. VLAB.doExec(cmd)
  1693. if (pm != None):
  1694. pm.beginTask("Computing BRF...", 10)
  1695. # ensure at least 1 second to ensure progress popup feedback
  1696. time.sleep(1)
  1697. VLAB.logger.info('%s: finished running...' % me)
  1698. #### DUMMY end ###############################################################
  1699. #### DART start ##############################################################
  1700. ##############################################################################
  1701. #
  1702. # Dart_* integration routines
  1703. #
  1704. # Authors: Nicolas Lauret, Fabian Schneider
  1705. #
  1706. # converted to "BEAM-limited jython" by Jason Brazile
  1707. #
  1708. #==============================================================================
  1709. #title :Dart_DARTDao.py
  1710. #description :This script can be used to recover DART images and spectral bands
  1711. #coding :utf-8
  1712. #author :Nicolas Lauret, (Fabian Schneider)
  1713. #date :20130328
  1714. #version :1.0
  1715. #usage :see Dart_DartImages.py
  1716. #==============================================================================
  1717. def Dart_enum(**enums):
  1718. return type('Enum', (), enums)
  1719. Dart_ProjectionPlane = Dart_enum(SENSOR_PLANE=0, ORTHOPROJECTION=1, BOA_PLANE=2)
  1720. Dart_DataUnit = Dart_enum(BRF_TAPP=0, RADIANCE=1)
  1721. Dart_DataLevel = Dart_enum(BOA=0, SENSOR=1, TOA=2, ATMOSPHERE_ONLY=3)
  1722. Dart_SpectralBandMode = Dart_enum(VISIBLE=0, VISIBLE_AND_THERMAL=1, THERMAL=2)
  1723. class Dart_DARTEnv :
  1724. simulationsDirectory = 'simulations'
  1725. inputDirectory = 'input'
  1726. outputDirectory = 'output'
  1727. sequenceDirectory = 'sequence'
  1728. libPhaseDirectory = 'lib_phase'
  1729. bandRootDirectory = 'BAND'
  1730. brfDirectory = 'BRF'
  1731. tappDirectory = 'Tapp'
  1732. radianceDirectory = 'Radiance'
  1733. toaDirectory = 'TOA'
  1734. radiativeBudgetDirectory = 'RADIATIVE_BUDGET'
  1735. iterRootDirectory = 'ITER'
  1736. couplDirectory = 'COUPL'
  1737. sensorDirectory = 'SENSOR'
  1738. #imageDirectoy = VLAB.path.join('IMAGES_DART', 'Non_Projected_Image')
  1739. imageDirectoy = 'IMAGES_DART'
  1740. orthoProjectedImageDirectory = 'IMAGE_PROJETEE'
  1741. nonProjectedImageDirectory = 'Non_Projected_Image'
  1742. brfFile = 'brf'
  1743. radianceFile = 'radiance'
  1744. radianceAtmoFile = 'AtmosphereRadiance'
  1745. tappFile = 'tapp'
  1746. radiativeBudgetFile = 'RadiativeBudget'
  1747. propertiesFile = 'simulation.properties.txt'
  1748. # Class SpectralBand
  1749. class Dart_SpectralBand:
  1750. def __init__(self) :
  1751. self.index = 0
  1752. self.lambdaMin = 0.
  1753. self.lambdaMax = 0.
  1754. self.mode = Dart_SpectralBandMode.VISIBLE
  1755. def __str__(self):
  1756. return 'Dart_SpectralBand(' + str(self.index) + ': [' + str(self.lambdaMin) + '; ' + str(self.lambdaMax) + ']; ' + str(self.mode) + ')'
  1757. def getCentralWaveLength(self):
  1758. return (self.lambdaMax + self.lambdaMin) / 2.
  1759. def getBandWidth(self):
  1760. return (self.lambdaMax - self.lambdaMin)
  1761. # Class Direction
  1762. class Dart_Direction :
  1763. def __init__(self, theta, phi, solidAngle = 1, angularSector = 1, index = -1) :
  1764. self.theta = theta
  1765. self.phi = phi
  1766. self.solidAngle = solidAngle
  1767. self.angularSector = angularSector
  1768. self.index = index
  1769. def __str__(self):
  1770. return 'Dart_Direction(' + str(self.theta) + ', ' + str(self.phi) + ')'
  1771. def equal(self, dir2) :
  1772. return abs(self.theta - dir2.theta) < 0.001 and abs(self.phi - dir2.phi) < 0.001
  1773. # Class BRF, Tapp, Radiance, per direction
  1774. class Dart_BRF :
  1775. def __init__(self) :
  1776. self.valeursParDirections = []
  1777. def __str__(self):
  1778. string = '<BDAverage'
  1779. for (direction, moyenne) in self.valeursParDirections :
  1780. string += '\n' + str(direction) + ' : ' + str(moyenne)
  1781. string += '>'
  1782. return string
  1783. def addValeurDansDirection (self, direction, valeur) :
  1784. self.valeursParDirections.append((direction, valeur))
  1785. def getValueForDirection(self, directionRecherchee) :
  1786. for (directionCourante, valeurCourante) in self.valeursParDirections :
  1787. if (directionCourante.equal(directionRecherchee)) :
  1788. return valeurCourante
  1789. def getValue(self, indiceDirection) :
  1790. return self.valeursParDirections[indiceDirection]
  1791. # Classe Images par direction
  1792. # FIXME Is this class still needed?
  1793. class Dart_Images :
  1794. def __init__(self) :
  1795. self.matrice2DparDirections = []
  1796. def addMatriceDansDirection (self, direction, matrice) :
  1797. self.matrice2DparDirections.append((direction, matrice))
  1798. def getMatrice2D(self, directionRecherchee) :
  1799. for (directionCourante, matriceCourante) in self.matrice2DparDirections :
  1800. if (directionCourante.equal(directionRecherchee)) :
  1801. return matriceCourante
  1802. # Classe Bilan Radiatif par type
  1803. # FIXME Is this class still needed?
  1804. class Dart_BilanRadiatif :
  1805. def __init__(self) :
  1806. self.matriceParType = []
  1807. def getTypeBilan(self) :
  1808. typeBilans = []
  1809. for (typeBilanCourant, matriceCourante) in self.matriceParType :
  1810. typeBilans.append(typeBilanCourant)
  1811. return typeBilans
  1812. def contientTypeBilan(self, typeBilan) :
  1813. for (typeBilanCourant, matriceCourante) in self.matriceParType :
  1814. if typeBilanCourant == typeBilan :
  1815. return True
  1816. return False
  1817. def Dart_getModeFromString(modeString):
  1818. if modeString == 'T':
  1819. return Dart_SpectralBandMode.THERMAL
  1820. elif modeString == 'R+T':
  1821. return Dart_SpectralBandMode.VISIBLE_AND_THERMAL
  1822. else :
  1823. return Dart_SpectralBandMode.VISIBLE
  1824. def Dart_getNumMaxIteration(path) :
  1825. dirList = [f for f in VLAB.listdir(path) if (f[0] != '.') and (VLAB.path.isdir(VLAB.path.join(path, f))) and f.startswith(Dart_DARTEnv.iterRootDirectory) and f != Dart_DARTEnv.iterRootDirectory + 'X']
  1826. maxIter = -1
  1827. for rep in dirList :
  1828. numIter = int(rep.split(Dart_DARTEnv.iterRootDirectory)[1])
  1829. if numIter > maxIter :
  1830. maxIter = numIter
  1831. return maxIter
  1832. def Dart_readProperties(propertyPath):
  1833. # propFile= file(propertyPath, "rU" )
  1834. propFile= file(propertyPath, "r" )
  1835. propDict= dict()
  1836. for propLine in propFile:
  1837. propDef= propLine.strip()
  1838. if len(propDef) == 0:
  1839. continue
  1840. if propDef[0] in ( '!', '#' ):
  1841. continue
  1842. punctuation= [ propDef.find(c) for c in ':= ' ] + [ len(propDef) ]
  1843. found= min( [ pos for pos in punctuation if pos != -1 ] )
  1844. name= propDef[:found].rstrip()
  1845. value= propDef[found:].lstrip(":= ").rstrip()
  1846. propDict[name]= value
  1847. propFile.close()
  1848. return propDict;
  1849. def Dart_readPropertiesFromFile(stringFile):
  1850. properties = StringIO.StringIO(stringFile)
  1851. propertiesLines = properties.readlines()
  1852. propertiesDico = {}
  1853. for line in propertiesLines:
  1854. prop,valeur = line.rstrip("\n\r\t").split(':')[0],line.rstrip("\n\r\t").split(':')[1]
  1855. propertiesDico[prop] = valeur
  1856. return propertiesDico
  1857. class Dart_DARTSimulation :
  1858. def __init__(self, name, rootSimulations) :
  1859. self.name = name
  1860. self.rootSimulationsDirectory = rootSimulations
  1861. def __str__(self):
  1862. return self.name
  1863. def getAbsolutePath(self) :
  1864. return VLAB.path.join(self.rootSimulationsDirectory.getAbsolutePath(), self.name)
  1865. def isValid(self) :
  1866. if self.name != '' and VLAB.path.exists(self.getAbsolutePath()) :
  1867. dirList=[f for f in VLAB.listdir(self.getAbsolutePath()) if (f[0] != '.') and (VLAB.path.isdir(VLAB.path.join(self.getAbsolutePath(), f)))]
  1868. for directory in dirList:
  1869. # On test si le dossier contient des dossiers output, input et/ou sequence
  1870. # On relance la methode recursivement sur les eventuels autres dossiers (hors input, output et sequence)
  1871. if (directory == Dart_DARTEnv.inputDirectory) or (directory == Dart_DARTEnv.outputDirectory) or (directory == Dart_DARTEnv.sequenceDirectory) :
  1872. return True
  1873. return False
  1874. def getProperties(self):
  1875. return Dart_readProperties(VLAB.path.join(self.getAbsolutePath(), Dart_DARTEnv.outputDirectory, Dart_DARTEnv.propertiesFile))
  1876. def getSpectralBands(self):
  1877. properties = self.getProperties()
  1878. nbSpectralBand = int(properties['phase.nbSpectralBands'])
  1879. bandes = []
  1880. for numBand in range(nbSpectralBand):
  1881. bande = Dart_SpectralBand()
  1882. bande.index = numBand
  1883. bande.lambdaMin = float(properties['dart.band' + str(numBand) + '.lambdaMin'])
  1884. bande.lambdaMax = float(properties['dart.band' + str(numBand) + '.lambdaMax'])
  1885. bande.mode = Dart_getModeFromString(properties['dart.band' + str(numBand) + '.mode'])
  1886. bandes.append(bande)
  1887. return bandes
  1888. def getSceneGeolocation(self) :
  1889. properties = self.getProperties()
  1890. return (float(properties['dart.maket.latitude']), float(properties['dart.maket.longitude']))
  1891. def getDiscretizedDirection(self):
  1892. properties = self.getProperties()
  1893. nbDD = int(properties['direction.numberOfDirections'])
  1894. discretizedDirections = []
  1895. for i in range(nbDD) :
  1896. discretizedDirections.append(Dart_Direction(float(properties['direction.direction' + str(i) +'.thetaCenter']), float(properties['direction.direction' + str(i) +'.phiCenter']), solidAngle = float(properties['direction.direction' + str(i) +'.omega']), angularSector = int(properties['direction.direction' + str(i) +'.angularSector']), index = i))
  1897. return discretizedDirections
  1898. def getUserDirections(self) :
  1899. properties = self.getProperties()
  1900. nbUD = int(properties['direction.nbOfAdditionalSpots'])
  1901. userDirections = []
  1902. for i in range(nbUD) :
  1903. additionalSpotIndex = int(properties['direction.additionalSpot' + str(i) + '.directionIndex'])
  1904. userDirections.append(Dart_Direction(float(properties['direction.direction' + str(additionalSpotIndex) +'.thetaCenter']), float(properties['direction.direction' + str(additionalSpotIndex) +'.phiCenter']), index = additionalSpotIndex))
  1905. return userDirections
  1906. def listNomsSequences(self) :
  1907. sequencePath = VLAB.path.join(self.getAbsolutePath(), Dart_DARTEnv.sequenceDirectory)
  1908. listNom = []
  1909. if (VLAB.path.exists(sequencePath)) :
  1910. dirList=[f for f in VLAB.listdir(sequencePath) if (f[0] != '.') and (VLAB.path.isdir(VLAB.path.join(sequencePath, f)))]
  1911. for sequence in dirList :
  1912. nomSequence = sequence.rpartition('_')[0]
  1913. if (not nomSequence in listNom) :
  1914. listNom.append(nomSequence)
  1915. listNom.sort()
  1916. return listNom
  1917. def listSequences(self, nom) :
  1918. sequencePath = VLAB.path.join(self.getAbsolutePath(), Dart_DARTEnv.sequenceDirectory)
  1919. listSequence = [f for f in VLAB.listdir(sequencePath) if (f[0] != '.') and (VLAB.path.isdir(VLAB.path.join(sequencePath, f))) and f.startswith(nom + '_')]
  1920. listSequence.sort(lambda a, b: cmp(int(a[len(nom)+1:]),int(b[len(nom)+1:])))
  1921. listSimuSequence = [Dart_DARTSimulation(VLAB.path.join(self.name, Dart_DARTEnv.sequenceDirectory, s), self.rootSimulationsDirectory) for s in listSequence]
  1922. return listSimuSequence
  1923. def getSequence(self, nomSequence, numeroSequence) :
  1924. return Dart_DARTSimulation(VLAB.path.join(self.name, Dart_DARTEnv.sequenceDirectory, nomSequence + '_' + str(numeroSequence)), self.rootSimulationsDirectory);
  1925. def getSubdirectory(self, spectralBand = 0, dataType = Dart_DataUnit.BRF_TAPP, level = Dart_DataLevel.BOA, iteration = 'last') :
  1926. simulationPath = self.getAbsolutePath()
  1927. bandPath = VLAB.path.join(simulationPath, Dart_DARTEnv.outputDirectory, Dart_DARTEnv.bandRootDirectory + str(spectralBand))
  1928. brfPath = ''
  1929. if dataType == Dart_DataUnit.RADIANCE :
  1930. brfPath = VLAB.path.join(bandPath, Dart_DARTEnv.radianceDirectory)
  1931. if (level == Dart_DataLevel.TOA or level == Dart_DataLevel.ATMOSPHERE_ONLY) :
  1932. brfPath = VLAB.path.join(brfPath, Dart_DARTEnv.toaDirectory) # Radiance/TOA
  1933. elif (level == Dart_DataLevel.SENSOR) :
  1934. brfPath = VLAB.path.join(brfPath, Dart_DARTEnv.sensorDirectory) # Radiance/SENSOR
  1935. elif (not iteration == 'last') :
  1936. brfPath = VLAB.path.join(brfPath, iteration) # Radiance/ITER...
  1937. else :
  1938. # Recherche du dossier COUPL
  1939. tmpPath = VLAB.path.join(brfPath, Dart_DARTEnv.couplDirectory) # Radiance/COUPL
  1940. if (not VLAB.path.exists(tmpPath)) :
  1941. # Recherche du dossier ITERX
  1942. tmpPath = VLAB.path.join(brfPath, Dart_DARTEnv.iterRootDirectory + 'X') # Radiance/ITERX
  1943. if (not VLAB.path.exists(tmpPath)) :
  1944. # Recherche du dossier ITER de plus fort nombre
  1945. tmpPath = VLAB.path.join(brfPath, Dart_DARTEnv.iterRootDirectory + str(Dart_getNumMaxIteration(brfPath)))
  1946. brfPath = tmpPath;
  1947. else :
  1948. if (level == Dart_DataLevel.BOA) :
  1949. # Test de la presence d'un dossier brf, sinon tapp
  1950. brfPath = VLAB.path.join(bandPath, Dart_DARTEnv.brfDirectory)
  1951. if (not VLAB.path.exists(brfPath)) :
  1952. # on essaie le dossier tapp
  1953. brfPath = VLAB.path.join(bandPath, Dart_DARTEnv.tappDirectory)
  1954. if (not iteration == 'last') :
  1955. brfPath = VLAB.path.join(brfPath, iteration) # BRF_TAPP/ITER...
  1956. else :
  1957. tmpPath = VLAB.path.join(brfPath, Dart_DARTEnv.couplDirectory) # BRF_TAPP/COUPL
  1958. if (not VLAB.path.exists(tmpPath)) :
  1959. # Recherche du dossier ITERX
  1960. tmpPath = VLAB.path.join(brfPath, Dart_DARTEnv.iterRootDirectory + 'X') # BRF_TAPP/ITERX
  1961. if (not VLAB.path.exists(tmpPath)) :
  1962. # Recherche du dossier ITER de plus fort nombre
  1963. tmpPath = VLAB.path.join(brfPath, Dart_DARTEnv.iterRootDirectory + str(Dart_getNumMaxIteration(brfPath)))
  1964. brfPath = tmpPath;
  1965. elif (level == Dart_DataLevel.SENSOR) :
  1966. brfPath = VLAB.path.join(bandPath, Dart_DARTEnv.sensorDirectory) # SENSOR
  1967. else :
  1968. brfPath = VLAB.path.join(bandPath, Dart_DARTEnv.toaDirectory) # TOA
  1969. return brfPath
  1970. def getAveragePerDirection(self, spectralBand = 0, dataType = Dart_DataUnit.BRF_TAPP, level = Dart_DataLevel.BOA, iteration = 'last') :
  1971. brfPath = self.getSubdirectory(spectralBand, dataType, level, iteration)
  1972. brf = Dart_BRF()
  1973. if (VLAB.path.exists(brfPath)) :
  1974. # recherche du nom de fichier contenant le brf/tapp/radiance
  1975. if (dataType == Dart_DataUnit.RADIANCE) :
  1976. if (level == Dart_DataLevel.ATMOSPHERE_ONLY):
  1977. brfPath = VLAB.path.join(brfPath, Dart_DARTEnv.radianceAtmoFile)
  1978. else:
  1979. brfPath = VLAB.path.join(brfPath, Dart_DARTEnv.radianceFile)
  1980. else :
  1981. tmpPath = VLAB.path.join(brfPath, Dart_DARTEnv.brfFile)
  1982. if (not VLAB.path.exists(tmpPath)) :
  1983. tmpPath = VLAB.path.join(brfPath, Dart_DARTEnv.tappFile)
  1984. brfPath = tmpPath
  1985. if (VLAB.path.exists(brfPath) and VLAB.path.isfile(brfPath)) :
  1986. # lecture du fichier et remplissage du conteneur
  1987. fichierBRF = open(brfPath, "r")
  1988. lines = fichierBRF.readlines()
  1989. for line in lines :
  1990. split = line.split()
  1991. brf.addValeurDansDirection(Dart_Direction(float(split[0]), float(split[1])), float(split[2]))
  1992. fichierBRF.close()
  1993. return brf
  1994. def getImageNameInDirection(self, direction):
  1995. properties = self.getProperties()
  1996. imageNumber = properties['dart.products.images.number']
  1997. imageIndex = 0
  1998. found = False
  1999. imageName = None
  2000. while (imageIndex < imageNumber and not found):
  2001. directionIndex = int(properties['dart.products.image' + str(imageIndex) + '.directionIndex'])
  2002. if (directionIndex == direction.index):
  2003. imageName = properties['dart.products.image' + str(imageIndex) + '.name']
  2004. found = True
  2005. else:
  2006. imageIndex = imageIndex + 1
  2007. return imageName
  2008. def getImageMinMaxInDirection(self, direction, spectralBand = 0, dataType = Dart_DataUnit.BRF_TAPP, level = Dart_DataLevel.BOA, iteration = 'last', projectionPlane=Dart_ProjectionPlane.SENSOR_PLANE) :
  2009. brfPath = self.getSubdirectory(spectralBand, dataType, level, iteration)
  2010. minImage = None
  2011. maxImage = None
  2012. if (VLAB.path.exists(brfPath)) :
  2013. imageDirPath = VLAB.path.join(brfPath, Dart_DARTEnv.imageDirectoy)
  2014. if (projectionPlane == Dart_ProjectionPlane.ORTHOPROJECTION):
  2015. imageDirPath = VLAB.path.join(imageDirPath, Dart_DARTEnv.orthoProjectedImageDirectory)
  2016. elif (projectionPlane == Dart_ProjectionPlane.BOA_PLANE):
  2017. imageDirPath = VLAB.path.join(imageDirPath, Dart_DARTEnv.nonProjectedImageDirectory)
  2018. imageName = self.getImageNameInDirection(direction)
  2019. mprPath = VLAB.path.join(imageDirPath, imageName + '.mpr')
  2020. if (VLAB.path.exists(mprPath)):
  2021. mprFile = open(mprPath, "r")
  2022. lines = mprFile.readlines()
  2023. for line in lines :
  2024. split = line.split('=')
  2025. if (split[0].startswith('MinMax')):
  2026. splitSplit = split[1].split(':')
  2027. minImage = float(splitSplit[0])
  2028. maxImage = float(splitSplit[1])
  2029. mprFile.close()
  2030. return (minImage, maxImage)
  2031. mprFile.close()
  2032. return (minImage, maxImage)
  2033. def getImageInDirection(self, direction, spectralBand = 0, dataType = Dart_DataUnit.BRF_TAPP, level = Dart_DataLevel.BOA, iteration = 'last', projectionPlane=Dart_ProjectionPlane.SENSOR_PLANE):
  2034. brfPath = self.getSubdirectory(spectralBand, dataType, level, iteration)
  2035. VLAB.logger.info('brfPath is %s' % brfPath)
  2036. data = []
  2037. if (VLAB.path.exists(brfPath)):
  2038. imageDirPath = VLAB.path.join(brfPath, Dart_DARTEnv.imageDirectoy)
  2039. if (projectionPlane == Dart_ProjectionPlane.ORTHOPROJECTION):
  2040. imageDirPath = VLAB.path.join(imageDirPath, Dart_DARTEnv.orthoProjectedImageDirectory)
  2041. elif (projectionPlane == Dart_ProjectionPlane.BOA_PLANE):
  2042. imageDirPath = VLAB.path.join(imageDirPath, Dart_DARTEnv.nonProjectedImageDirectory)
  2043. imageName = self.getImageNameInDirection(direction)
  2044. # Recovery of the size of the image, in pixels
  2045. mprPath = VLAB.path.join(imageDirPath, imageName + '.mpr')
  2046. VLAB.logger.info('mprPath is %s' % mprPath)
  2047. if (VLAB.path.exists(mprPath)):
  2048. sizeX = 0
  2049. sizeY = 0
  2050. mprFile = open(mprPath, "r")
  2051. lines = mprFile.readlines()
  2052. for line in lines:
  2053. split = line.split('=')
  2054. if (split[0].startswith('Size')):
  2055. splitSplit = split[1].split(' ')
  2056. sizeX = int(splitSplit[0])
  2057. sizeY = int(splitSplit[1])
  2058. mprFile.close()
  2059. mpSharpPath = VLAB.path.join(imageDirPath, imageName + '.mp#')
  2060. if (VLAB.path.exists(mpSharpPath)):
  2061. mpSharpFile = open(mpSharpPath, "rb")
  2062. for x in range(sizeX):
  2063. line = []
  2064. for y in range(sizeY):
  2065. line.append(struct.unpack('d', mpSharpFile.read(8))[0])
  2066. data.append(line)
  2067. mpSharpFile.close()
  2068. return data
  2069. def getIterMaxPath(self, spectralBand, iterX=True):
  2070. """ Return the iterYY folder where YY is X is exist and iterX is True or the iterMax folder
  2071. """
  2072. # Get spectralBand folder
  2073. iterFolder = VLAB.path.join(self.rootSimulationsDirectory, self.name, "output", spectralBand, "BRF")
  2074. # Get list of iter folders
  2075. iters = [ folder.lstrip('ITER') for folder in VLAB.listdir(iterFolder)
  2076. if folder.startswith('ITER')]
  2077. # Get iterX is exists otherwise select iterMax
  2078. if iterX and 'X' in iters:
  2079. return VLAB.path.join(iterFolder, "ITERX")
  2080. else:
  2081. if 'X' in iters:
  2082. iters.remove('X')
  2083. iters = [ int(i) for i in iters ]
  2084. return VLAB.path.join(iterFolder, "ITER" + str(max(iters)))
  2085. class Dart_DARTRootSimulationDirectory :
  2086. def __init__(self) :
  2087. pass
  2088. def samefile(self, path1, path2) :
  2089. return VLAB.path.normcase(VLAB.path.normpath(path1)) == VLAB.path.normcase(VLAB.path.normpath(path2))
  2090. def getAbsolutePath(self) :
  2091. return VLAB.path.join(DART.SDIR)#, Dart_DARTEnv.simulationsDirectory)
  2092. def getSimulationsList(self) :
  2093. rootSimulationPath = self.getAbsolutePath()
  2094. # Liste de tous les fichier/dossier non cache du repertoire
  2095. dirList=[f for f in VLAB.listdir(rootSimulationPath) if (f[0] != '.') and (VLAB.path.isdir(VLAB.path.join(rootSimulationPath, f)))]
  2096. dirList.sort()
  2097. listSimulations = []
  2098. for directory in dirList:
  2099. self.listSimulationsInPath(listSimulations, directory)
  2100. return listSimulations
  2101. def listSimulationsInPath(self, listSimulations, path) :
  2102. rootPath = path
  2103. if not VLAB.path.isabs(path):
  2104. rootPath = VLAB.path.join(self.getAbsolutePath(), path)
  2105. dirList=[f for f in VLAB.listdir(rootPath) if (f[0] != '.') and (VLAB.path.isdir(VLAB.path.join(rootPath, f)))]
  2106. dirList.sort()
  2107. isSimulation = False
  2108. for directory in dirList:
  2109. # On test si le dossier contient des dossiers output, input et/ou sequence
  2110. # On relance la methode recursivement sur les eventuels autres dossiers (hors input, output et sequence)
  2111. if (directory != Dart_DARTEnv.inputDirectory) and (directory != Dart_DARTEnv.outputDirectory) and (directory != Dart_DARTEnv.sequenceDirectory) :
  2112. self.listSimulationsInPath(listSimulations, VLAB.path.join(path, directory))
  2113. else :
  2114. isSimulation = True
  2115. if isSimulation :
  2116. self.addSimulation(listSimulations, path)
  2117. def addSimulation(self, listSimulations, path):
  2118. simulation = self.getSimulation(path)
  2119. if simulation.isValid() :
  2120. listSimulations.append(simulation)
  2121. def getSimulation(self, name) :
  2122. rootSimulationPath = self.getAbsolutePath()
  2123. rootPath = name
  2124. if not VLAB.path.isabs(name):
  2125. rootPath = VLAB.path.join(rootSimulationPath, name)
  2126. simulationName = ''
  2127. if not VLAB.path.exists(rootPath) :
  2128. simulationName = name
  2129. elif not self.samefile(rootPath, rootSimulationPath) :
  2130. if VLAB.path.isdir(rootPath):
  2131. (head, tail) = VLAB.path.split(rootPath)
  2132. while not self.samefile(head, rootSimulationPath) and head !='' :
  2133. simulationName = VLAB.path.join(tail, simulationName)
  2134. (head, tail) = VLAB.path.split(head)
  2135. else :
  2136. if head != '' :
  2137. simulationName = VLAB.path.join(tail, simulationName)
  2138. else :
  2139. simulationName = ''
  2140. return Dart_DARTSimulation(simulationName, self)
  2141. class Dart_DARTDao :
  2142. def __init__(self) :
  2143. pass
  2144. def getRootSimulationDirectory(self) :
  2145. return Dart_DARTRootSimulationDirectory()
  2146. def getSimulationsList(self) :
  2147. return self.getRootSimulationDirectory().getSimulationsList()
  2148. def getSimulation(self, name) :
  2149. return self.getRootSimulationDirectory().getSimulation(name)
  2150. # FIXME Is this class still needed?
  2151. def Dart_Bandes(simulationProperties):
  2152. propertiesDico = Dart_readPropertiesFromFile(simulationProperties)
  2153. i = int(propertiesDico['phase.nbSpectralBands'])
  2154. bandes = []
  2155. for j in range(i):
  2156. bande = {}
  2157. bande['spectralBandwidth'] = round(float(propertiesDico['dart.band' + str(j) + '.lambdaMax']) - float(propertiesDico['dart.band' + str(j) + '.lambdaMin']),4)
  2158. a = float(propertiesDico['dart.band' + str(j) + '.lambdaMin']) + bande['spectralBandwidth'] / 2
  2159. bande['centralWavelength'] = round(float(a),4)
  2160. bande['mode'] = propertiesDico['dart.band' + str(j) + '.mode']
  2161. bandes.append(bande)
  2162. return bandes
  2163. class Dart_dolibradtran:
  2164. def main(q):
  2165. # generate arguments for doLibradtran
  2166. r = {
  2167. 'CO2' : q[VLAB.P_AtmosphereCO2],
  2168. 'H2O' : q[VLAB.P_AtmosphereWater],
  2169. 'O3' : q[VLAB.P_AtmosphereOzone],
  2170. 'scene' : q['obj'],
  2171. 'aerosol' : q[VLAB.P_AtmosphereAerosol],
  2172. 'sensor' : q['wb'],
  2173. 'rpv_file' : '%s/rami.TOA/rpv.rami.libradtran.dat.all' % LIBRAT.SDIR,
  2174. 'infile' : '%s/%s/input/%s' % (DART.SDIR, q['simulationName'], 'UVSPEC-in.txt'),
  2175. 'outfile' : '%s/%s/output/%s' % (DART.SDIR, q['simulationName'], q['ipfile']),
  2176. }
  2177. #
  2178. # TODO: loop over something to produce umu, phi ,phi0, sza, etc.
  2179. #
  2180. VLAB.doLibradtran(r)
  2181. #==============================================================================
  2182. #title :Dart_DartImages.py
  2183. #description :This script can be used to write a *.bsq binary file and a corresponding ENVI header *.hdr from DART output images
  2184. #required scripts :Dart_DARTDao.py
  2185. #author :Fabian Schneider, Nicolas Lauret
  2186. #date :20130328
  2187. #version :1.0
  2188. #usage :see writeDataCube.py
  2189. #==============================================================================
  2190. class Dart_DartImages :
  2191. def __init__(self) :
  2192. pass
  2193. # http://rightfootin.blogspot.ch/2006/09/more-on-python-flatten.html, based on Mike C. Fletcher's BasicTypes library
  2194. def flatten( self, l, ltypes=(list, tuple)):
  2195. ltype = type(l)
  2196. l = list(l)
  2197. i = 0
  2198. while i < len(l):
  2199. while isinstance(l[i], ltypes):
  2200. if not l[i]:
  2201. l.pop(i)
  2202. i -= 1
  2203. break
  2204. else:
  2205. l[i:i + 1] = l[i]
  2206. i += 1
  2207. return ltype(l)
  2208. def getImagesBandsAsList( self, args ) :
  2209. simulation = Dart_DARTDao().getSimulation( args['di_simName'] )
  2210. imagesList = []
  2211. spectralBandsList = []
  2212. if args['di_isSeq']:
  2213. sequencesList = simulation.listSequences( args['di_sequence'] )
  2214. for sequence in sequencesList:
  2215. # Recover the number of Spectral Band
  2216. spectralBands = sequence.getSpectralBands()
  2217. # Recover the Directions
  2218. if args['ii_isUsrDir']:
  2219. directions = sequence.getUserDirections()
  2220. else:
  2221. directions = simulation.getDiscretizedDirection()
  2222. # Recover the images in the defined direction for each spectral band
  2223. for band in spectralBands:
  2224. VLAB.logger.info('spectralBand: %s' % (band))
  2225. imagesList.append(sequence.getImageInDirection( directions[ args['ii_dirNum'] ], band.index, args['ii_dType'], args['ii_iLevel'], args['ii_iter'], args['ii_projPlane'] ))
  2226. spectralBandsList.append( band )
  2227. else:
  2228. # Recover the number of Spectral Band
  2229. spectralBands = simulation.getSpectralBands()
  2230. # Recover the Directions
  2231. if args['ii_isUsrDir']:
  2232. directions = sequence.getUserDirections()
  2233. else:
  2234. directions = simulation.getDiscretizedDirection()
  2235. # Recover the images in the defined direction for each spectral band
  2236. for band in spectralBands:
  2237. imagesList.append(simulation.getImageInDirection( directions[ args['ii_dirNum'] ], band.index, args['ii_dType'], args['ii_iLevel'], args['ii_iter'], args['ii_projPlane'] ))
  2238. spectralBandsList.append( band )
  2239. VLAB.logger.info('imagesList has %d entries' % len(imagesList))
  2240. VLAB.logger.info('spectralBandsList has %d entries' % len(spectralBandsList))
  2241. return imagesList, spectralBandsList
  2242. def writeDataCube( self, args ) :
  2243. imagesList, spectralBandsList = self.getImagesBandsAsList( args )
  2244. # write BSQ binary file
  2245. if (len(args['OutputDirectory']) == 0):
  2246. args['OutputDirectory'] = '%s/%s/' % (DART.SDIR, args['di_simName'])
  2247. fname = '%s/%s%s.bsq' % (args['OutputDirectory'], args['OutputPrefix'], args['di_outfname'])
  2248. VLAB.logger.info('writing output bsq %s' % (fname))
  2249. fout = open( fname, 'wb')
  2250. flatarray = array('f', self.flatten( imagesList ))
  2251. flatarray.tofile(fout)
  2252. fout.close()
  2253. # ENVI header information, more infos on: http://geol.hu/data/online_help/ENVI_Header_Format.html
  2254. samples = 0
  2255. lines = 0
  2256. if (len(imagesList) > 0):
  2257. lines = len( imagesList[0] )
  2258. if (len(imagesList[0]) > 0):
  2259. samples = len( imagesList[0][0] )
  2260. bands = len( imagesList )
  2261. headerOffset = 0
  2262. fileType = 'ENVI Standard'
  2263. dataType = 4
  2264. interleave = 'BSQ'
  2265. byteOrder = 0
  2266. xStart = 1
  2267. yStart = 1
  2268. defaultBands = '{0}'
  2269. wavelengthUnits = 'Nanometers'
  2270. wavelength = ''
  2271. fwhm = ''
  2272. for band in spectralBandsList:
  2273. wavelength += str( band.getCentralWaveLength()*1000 ) + ', '
  2274. fwhm += str( band.getBandWidth()*1000 ) + ', '
  2275. # write ENVI header file
  2276. if (len(args['OutputDirectory']) == 0):
  2277. args['OutputDirectory'] = '%s/%s/' % (DART.SDIR, args['di_simName'])
  2278. fname = '%s/%s%s.hdr' % (args['OutputDirectory'], args['OutputPrefix'], args['di_outfname'])
  2279. VLAB.logger.info('writing output hdr %s' % (fname))
  2280. fout = open( fname, 'w')
  2281. fout.writelines( 'ENVI ' + '\n' )
  2282. fout.writelines( 'description = { ' + args['hi_desc'] + ' }' + '\n' )
  2283. fout.writelines( 'samples = ' + str( samples ) + '\n' )
  2284. fout.writelines( 'lines = ' + str( lines ) + '\n' )
  2285. fout.writelines( 'bands = ' + str( bands ) + '\n' )
  2286. fout.writelines( 'header offset = ' + str( headerOffset ) + '\n' )
  2287. fout.writelines( 'file type = ' + fileType + '\n' )
  2288. fout.writelines( 'data type = ' + str( dataType ) + '\n' )
  2289. fout.writelines( 'interleave = ' + interleave + '\n' )
  2290. fout.writelines( 'sensor type = ' + args['hi_sensor'] + '\n' )
  2291. fout.writelines( 'byte order = ' + str( byteOrder ) + '\n' )
  2292. fout.writelines( 'x start = ' + str( xStart ) + '\n' )
  2293. fout.writelines( 'y start = ' + str( yStart ) + '\n' )
  2294. fout.writelines( 'map info = {' + args['hi_projName'] + ', ' + str( args['hi_xRefPixl'] ) + ', ' + str( args['hi_yRefPixl'] ) + ', ' + str( args['hi_xRefCoord'] ) + ', ' + str( args['hi_yRefCoord'] ) + ', ' + str( args['hi_xPixSize'] ) + ', ' + str( args['hi_yPixSize'] ) + ', ' + args['hi_pixUnits'] + ' }' + '\n' )
  2295. fout.writelines( 'default bands = ' + defaultBands + '\n' )
  2296. fout.writelines( 'wavelength units = ' + wavelengthUnits + '\n' )
  2297. fout.writelines( 'wavelength = { ' + wavelength[:-2] + ' }' + '\n' )
  2298. fout.writelines( 'fwhm = { ' + fwhm[:-2] + ' }' + '\n' )
  2299. fout.close()
  2300. #==============================================================================
  2301. #title :writeDataCube.py
  2302. #description :This script writes a *.bsq binary file and a corresponding ENVI header *.hdr from DART output images
  2303. #required scripts :Dart_DartImages.py + Dart_DARTDao.py
  2304. #author :Fabian Schneider
  2305. #date :20130328
  2306. #version :1.0
  2307. #usage :python writeDataCube.py
  2308. #==============================================================================
  2309. #
  2310. # End of Dart_* integration routines
  2311. #
  2312. class DART:
  2313. if VLAB.osName().startswith('Windows'):
  2314. SDIR=VLAB.expandEnv('%HOMEDRIVE%%HOMEPATH%/.beam/beam-vlab/auxdata/dart_local/simulations')
  2315. else:
  2316. SDIR=VLAB.expandEnv('$HOME/.beam/beam-vlab/auxdata/dart_local/simulations')
  2317. """Integration glue for calling external DART programs"""
  2318. def __init__(self):
  2319. me=self.__class__.__name__ +'::'+VLAB.me()
  2320. VLAB.logger.info('%s: constructor completed...' % me)
  2321. def dartSZA2libradtranSZA(self, sz, sa):
  2322. """ DART uses theta value from 0 to 180 for zenith angle (half a circle)
  2323. and 0 to 360 for azimuth angle (full circle).
  2324. In the upper sphere the zenith range is from 0 to 90.
  2325. It is necessary to convert to libradtran zenith and azimuth range
  2326. (-90 to 90 for zenith and 0-180 for azimuth).
  2327. """
  2328. if sa > 180.0:
  2329. sz = -sz
  2330. sa = sa - 180.0
  2331. return sz, sa
  2332. def _writeSeqFile(self, args):
  2333. """ Write DART sequence file
  2334. """
  2335. sstr = """<?xml version="1.0" encoding="UTF-8"?>
  2336. <DartFile version="1.0">
  2337. <DartSequencerDescriptor sequenceName="sequence;;%s">
  2338. <DartSequencerDescriptorEntries>
  2339. <DartSequencerDescriptorGroup groupName="group_%s">%s
  2340. </DartSequencerDescriptorGroup>
  2341. </DartSequencerDescriptorEntries>
  2342. <DartSequencerPreferences dartLaunched="true"
  2343. demGeneratorLaunched="false" directionLaunched="true"
  2344. displayEnabled="true" hapkeLaunched="false"
  2345. maketLaunched="true" numberParallelThreads="1"
  2346. phaseLaunched="false" prospectLaunched="false"
  2347. triangleFileProcessorLaunched="false"
  2348. vegetationLaunched="false" zippedResults="false"/>
  2349. <DartLutPreferences addedDirection="false" coupl="true"
  2350. generateLUT="false" iterx="true" luminance="true"
  2351. ordre="true" otherIter="true" phiMax="" phiMin=""
  2352. reflectance="true" sensor="true" storeIndirect="false"
  2353. thetaMax="" thetaMin="" toa="true"/>
  2354. </DartSequencerDescriptor>
  2355. </DartFile>
  2356. """
  2357. dstr = """
  2358. <DartSequencerDescriptorEntry args="%s"
  2359. propertyName="%s" type="enumerate"/>"""
  2360. groupstr = ""
  2361. for ent in args['entries']:
  2362. (dargs, prop) = ent
  2363. groupstr += (dstr % (dargs, prop))
  2364. paramfilename = '%s/%s/%s' % (DART.SDIR, args['simulation'], args['fileName'])
  2365. VLAB.logger.info('writing sequence paramfile "%s"' % paramfilename)
  2366. fp = open(paramfilename, 'w')
  2367. fp.write(sstr % (args['fileName'].rstrip(".xml"), args['fileName'].rstrip('.xml'), groupstr))
  2368. fp.close()
  2369. def doProcessing(self, pm, args):
  2370. """do processing for DART processor"""
  2371. me=self.__class__.__name__ +'::'+VLAB.me()
  2372. if (pm != None):
  2373. pm.beginTask("Computing BRF...", 10)
  2374. # ensure at least 1 second to ensure progress popup feedback
  2375. time.sleep(1)
  2376. q = {
  2377. 'rpvfile' : 'angles.rpv.2.dat',
  2378. 'simulation' : 'Unknown'
  2379. }
  2380. # overwrite defaults
  2381. for a in args:
  2382. if a == VLAB.P_3dScene:
  2383. if args[a] == VLAB.K_RAMI:
  2384. q['simulation'] = 'HET01_DIS_UNI_NIR_20'
  2385. elif args[a] == VLAB.K_LAEGERN:
  2386. q['simulation'] = 'Laegern'
  2387. elif args[a] == VLAB.K_THARANDT:
  2388. q['simulation'] = "Tharandt"
  2389. elif a == VLAB.P_ViewingAzimuth:
  2390. q['va'] = args[a]
  2391. elif a == VLAB.P_ViewingZenith:
  2392. q['vz'] = args[a]
  2393. elif a == VLAB.P_IlluminationAzimuth:
  2394. q['sa'] = args[a]
  2395. elif a == VLAB.P_IlluminationZenith:
  2396. q['sz'] = args[a]
  2397. elif a == VLAB.P_Bands:
  2398. q['bands'] = args[a]
  2399. elif a == VLAB.P_ScenePixel:
  2400. q['pixelSize'] = args[a]
  2401. else:
  2402. q[a] = args[a]
  2403. # 1. Create the DART scene
  2404. # 1. a. Copy DART original input file to a new folder
  2405. q['simulationName'] = q['simulation'] + "_run"
  2406. VLAB.copyDir(VLAB.path.join(DART.SDIR, q['simulation']), VLAB.path.join(DART.SDIR, q['simulationName']))
  2407. # 1. b. Update the DART input files with parameters from GUI
  2408. # In maket change the pixel size
  2409. maket = VLAB.path.join(DART.SDIR, q['simulationName'], "input", "maket.xml")
  2410. VLAB.XMLEditNode(maket, "CellDimensions", ["x", "z"], [q['pixelSize']]*2)
  2411. # In direction change the Sun viewving angle
  2412. direction = VLAB.path.join(DART.SDIR, q['simulationName'], "input", "directions.xml")
  2413. VLAB.XMLEditNode(direction, "SunViewingAngles",
  2414. ["sunViewingAzimuthAngle", "sunViewingZenithAngle"],
  2415. [q['sa'], q['sz']])
  2416. # In direction set ifCosWeighted and numberOfPropagationDirections attributes
  2417. VLAB.XMLEditNode(direction, "Directions",
  2418. ["ifCosWeighted", "numberOfPropagationDirections"],
  2419. ["1", "100"])
  2420. # In direction set viewing direction
  2421. VLAB.XMLAddNode(direction, "Directions",
  2422. ["AddedDirections", "ZenithAzimuth", "Square", "DefineOmega"],
  2423. {"AddedDirections": {"attribute":
  2424. ["directionType", "ifSquareShape", "imageDirection"],
  2425. "value": ["0", "1", "1"],
  2426. "parent":"Directions"},
  2427. "ZenithAzimuth": {"attribute":
  2428. ["directionAzimuthalAngle", "directionZenithalAngle"],
  2429. "value": [q['va'], q['vz']],
  2430. "parent":"AddedDirections"},
  2431. "Square": {"attribute": ["widthDefinition"], "value": ["0"],
  2432. "parent":"AddedDirections"},
  2433. "DefineOmega": {"attribute": ["omega"], "value": ["0.001"], "parent":"Square"}
  2434. }
  2435. )
  2436. # In phase force the radiance to be stored (could be not selected)
  2437. phase = VLAB.path.join(DART.SDIR, q['simulationName'], "input", "phase.xml")
  2438. VLAB.XMLEditNode(phase, "BrfProductsProperties", "luminanceProducts", "1")
  2439. # In phase change the spectral bands
  2440. if not q['simulationName'].startswith("HET01_DIS_UNI_NIR_20"):
  2441. # TODO: You should addapt the getBandsFromGUI function to be consistent whith what you want
  2442. bands = VLAB.getBandsFromGUI(q['bands'])
  2443. VLAB.XMLReplaceNodeContent(phase, "SpectralIntervals", "SpectralIntervalsProperties",
  2444. ["deltaLambda", "meanLambda"],
  2445. bands, spectralBands=True)
  2446. # In coeff_diff change multiplicativeFactorForLUT to allways be equal to "0"
  2447. coeffDiff = VLAB.path.join(DART.SDIR, q['simulationName'], "input", "coeff_diff.xml")
  2448. VLAB.XMLEditNode(coeffDiff, "LambertianMulti", "useMultiplicativeFactorForLUT", "0", multiple=False)
  2449. else:
  2450. bands = [None]
  2451. VLAB.logger.info("*********************************************************************************")
  2452. VLAB.logger.info("* WARNING: RAMI scene cannot be multiband according to the RAMI scene definition. *")
  2453. VLAB.logger.info("*********************************************************************************")
  2454. # 2. a. Run DART direction module
  2455. cmd = {
  2456. 'linux' : {
  2457. 'cwd' : '$HOME/.beam/beam-vlab/auxdata/dart_lin64/tools/linux',
  2458. 'exe' : '/bin/bash',
  2459. 'cmdline' : ['$HOME/.beam/beam-vlab/auxdata/dart_lin64/tools/linux/dart-directions.sh', q['simulationName']],
  2460. 'stdin' : None,
  2461. 'stdout' : None,
  2462. 'stderr' : None,
  2463. 'env' : None,
  2464. },
  2465. 'windows' : {
  2466. 'cwd' : '%HOMEDRIVE%%HOMEPATH%/.beam/beam-vlab/auxdata/dart_win32/tools/windows',
  2467. 'exe' : 'cmd.exe',
  2468. 'cmdline' : ['/c', '%HOMEDRIVE%%HOMEPATH%/.beam/beam-vlab/auxdata/dart_win32/tools/windows/dart-directions.bat', q['simulationName']],
  2469. 'stdin' : None,
  2470. 'stdout' : None,
  2471. 'stderr' : None,
  2472. 'env' : None,
  2473. }
  2474. }
  2475. VLAB.logger.info('command: %s' % cmd)
  2476. VLAB.doExec(cmd)
  2477. # 2. b. Get the first two cols (sz, sa) where sz < 70 deg - use as sequence
  2478. zlist = []; alist = []
  2479. for row in VLAB.valuesfromfile('%s/%s/output/directions.txt' % (DART.SDIR, q['simulationName'])):
  2480. (sz, sa, _, _) = row
  2481. if (sz < 70.0):
  2482. zlist.append(sz); alist.append(sa)
  2483. zparam = ";".join('%.2f' % x for x in zlist)
  2484. aparam = ";".join('%.2f' % x for x in alist)
  2485. # 2. c. Edit simulation directions.xml file to set the number of direcions to 200
  2486. VLAB.XMLEditNode(direction, "Directions", "numberOfPropagationDirections", "200")
  2487. # 2. d. Write sequence file
  2488. seqparams = {'fileName' : 'SunDirections.xml',
  2489. 'simulation' : q['simulationName'],
  2490. 'entries' : [[aparam, 'Directions.SunViewingAngles.sunViewingAzimuthAngle'],
  2491. [zparam, 'Directions.SunViewingAngles.sunViewingZenithAngle']
  2492. ]
  2493. }
  2494. self._writeSeqFile(seqparams)
  2495. # 3. a. Run DART to pregenerate phase, maket, (3D obj..) before the sequence
  2496. cmd = {
  2497. 'linux' : {
  2498. 'cwd' : '$HOME/.beam/beam-vlab/auxdata/dart_lin64/tools/linux',
  2499. 'exe' : '/bin/bash',
  2500. 'cmdline' : ['$HOME/.beam/beam-vlab/auxdata/dart_lin64/tools/linux/dart-full.sh', q['simulationName']],
  2501. 'stdin' : None,
  2502. 'stdout' : None,
  2503. 'stderr' : None,
  2504. 'env' : None,
  2505. },
  2506. 'windows' : {
  2507. 'cwd' : '%HOMEDRIVE%%HOMEPATH%/.beam/beam-vlab/auxdata/dart_win32/tools/windows',
  2508. 'exe' : 'cmd.exe',
  2509. 'cmdline' : ['/c', '%HOMEDRIVE%%HOMEPATH%/.beam/beam-vlab/auxdata/dart_win32/tools/windows/dart-full.bat', q['simulationName']],
  2510. 'stdin' : None,
  2511. 'stdout' : None,
  2512. 'stderr' : None,
  2513. 'env' : None,
  2514. }
  2515. }
  2516. VLAB.logger.info('command: %s' % cmd)
  2517. VLAB.doExec(cmd)
  2518. # 3. b. Run the sun directions sequence with number of directions=200
  2519. cmd = {
  2520. 'linux' : {
  2521. 'cwd' : '$HOME/.beam/beam-vlab/auxdata/dart_lin64/tools/linux',
  2522. 'exe' : '/bin/bash',
  2523. 'cmdline' : ['$HOME/.beam/beam-vlab/auxdata/dart_lin64/tools/linux/dart-sequence.sh', q['simulationName'], seqparams['fileName']],
  2524. 'stdin' : None,
  2525. 'stdout' : None,
  2526. 'stderr' : None,
  2527. 'env' : None,
  2528. },
  2529. 'windows' : {
  2530. 'cwd' : '%HOMEDRIVE%%HOMEPATH%/.beam/beam-vlab/auxdata/dart_win32/tools/windows',
  2531. 'exe' : 'cmd.exe',
  2532. 'cmdline' : ['/c', '%HOMEDRIVE%%HOMEPATH%/.beam/beam-vlab/auxdata/dart_win32/tools/windows/dart-sequence.bat', q['simulationName'], seqparams['fileName']],
  2533. 'stdin' : None,
  2534. 'stdout' : None,
  2535. 'stderr' : None,
  2536. 'env' : None,
  2537. }
  2538. }
  2539. VLAB.logger.info('command: %s' % cmd)
  2540. VLAB.doExec(cmd)
  2541. # 4.a. Select the values of sz < 70 to get BANDX.angles.rpv.2.dat
  2542. # for each spectral band in the DART simulation
  2543. rpvlist = None
  2544. rpvFiles = []
  2545. seqDir = VLAB.path.join(DART.SDIR, q['simulationName'], "sequence")
  2546. for bandNumber in xrange(len(bands)):
  2547. rpvlist = []
  2548. for seqSubDir in VLAB.listdir(seqDir):
  2549. dartBRF = VLAB.path.join(Dart_DARTSimulation(seqSubDir, seqDir).getIterMaxPath('BAND' + str(bandNumber)), "brf")
  2550. dirFile = VLAB.path.join(seqDir, seqSubDir, "input", "directions.xml")
  2551. sa = float(VLAB.XMLGetNodeAttributeValue(dirFile, "SunViewingAngles", "sunViewingAzimuthAngle"))
  2552. sz = float(VLAB.XMLGetNodeAttributeValue(dirFile, "SunViewingAngles", "sunViewingZenithAngle"))
  2553. for row in VLAB.valuesfromfile(dartBRF):
  2554. (vz, va, brf) = row
  2555. if (vz < 70.0):
  2556. # Convert DART output to librattran input
  2557. vz, va = self.dartSZA2libradtranSZA(vz, va)
  2558. rpvlist.append('%.2f\t%.2f\t%2f\t%2f\t%2f' % (sz, sa, vz, va, brf))
  2559. # write the libradtran input file
  2560. fname = VLAB.path.join(DART.SDIR,
  2561. q['simulationName'],
  2562. "BAND" + str(bandNumber) + "." + q['rpvfile'])
  2563. rpvFiles.append(fname)
  2564. fp = open(fname, "w")
  2565. fp.write("\n".join(rpvlist))
  2566. fp.close()
  2567. q['rpvFiles'] = rpvFiles
  2568. # 4.b. Run libradtran
  2569. # FIXME: this needs to eventually use the same routine that librat uses
  2570. dolibradtran = Dart_dolibradtran()
  2571. dolibradtran.main(q)
  2572. #
  2573. # collect result into a consolidated data cube
  2574. #
  2575. dargs = {
  2576. 'di_simName' : q['simulationName'],
  2577. 'di_isSeq' : False,
  2578. 'di_sequence' : 'sequence_apex',
  2579. 'di_outfname' : 'DartOutput',
  2580. 'ii_iLevel' : Dart_DataLevel.BOA,
  2581. 'ii_isUsrDir' : False,
  2582. 'ii_dirNum' : 0,
  2583. 'ii_dType' : Dart_DataUnit.RADIANCE,
  2584. 'ii_iter' : 'last',
  2585. 'ii_projPlane' : Dart_ProjectionPlane.SENSOR_PLANE,
  2586. 'hi_desc' : 'some text',
  2587. 'hi_sensor' : 'APEX',
  2588. 'hi_projName' : 'Arbitrary',
  2589. 'hi_xRefPixl' : 1,
  2590. 'hi_yRefPixl' : 1,
  2591. 'hi_xRefCoord' : '2669660.0000',
  2592. 'hi_yRefCoord' : '1259210.0000',
  2593. 'hi_xPixSize' : 1,
  2594. 'hi_yPixSize' : 1,
  2595. 'hi_pixUnits' : 'units=Meters'
  2596. }
  2597. # merge in data cube arguments
  2598. for d in dargs:
  2599. args[d] = dargs[d]
  2600. VLAB.logger.info('args is %s' % args)
  2601. Dart_DartImages().writeDataCube( args )
  2602. VLAB.logger.info('%s: done...' % me)
  2603. #### DART end ################################################################
  2604. #### LIBRAT start ############################################################
  2605. #
  2606. # Librat_ integration routines contributed by Mat Disney and Philip Lewis
  2607. # adapted for BEAM-embedded jython by Cyrill Schenkel and Jason Brazile
  2608. #
  2609. ################
  2610. class Librat_dobrdf:
  2611. def _writeCamFile(self, camFile, args):
  2612. # defaults
  2613. q = {
  2614. 'cam_camera' : 'simple camera',
  2615. 'perspective' : False,
  2616. 'result_image' : 'result.image',
  2617. 'integral_mode' : 'scattering order',
  2618. 'integral' : 'result',
  2619. 'vz' : 0,
  2620. 'va' : 0,
  2621. 'twist' : 0,
  2622. 'look' : (0., 0., 0.),
  2623. 'ideal' : (100., 100.),
  2624. 'boom' : 1000.,
  2625. 'npixels' : 100000,
  2626. 'rpp' : 1,
  2627. 'fov' : 180
  2628. }
  2629. # overwrite defaults
  2630. for a in args:
  2631. q[a] = args[a]
  2632. cdata = ' camera { \n' \
  2633. + ' %s = "%s";\n' %('camera.name', q['cam_camera']) \
  2634. + ' %s = %s;\n' %('geometry.zenith', q['vz']) \
  2635. + ' %s = %s;\n' %('geometry.azimuth', q['va']) \
  2636. + ' %s = "%s";\n' %('result.image', q['result_image']) \
  2637. + ' %s = "%s";\n' %('result.integral.mode', q['integral_mode']) \
  2638. + ' %s = "%s";\n' %('result.integral', q['integral']) \
  2639. + ' %s = %s;\n' %('samplingCharacteristics.nPixels', q['npixels']) \
  2640. + ' %s = %s;\n' %('samplingCharacteristics.rpp', q['rpp']) \
  2641. + ' %s = %s;\n' %('geometry.idealArea', ', '.join(map(str,map('%.1f'.__mod__, q['ideal'])))) \
  2642. + ' %s = %s;\n' %('geometry.lookat', ', '.join(map(str,map('%.1f'.__mod__,q['look_xyz'])))) \
  2643. + ' %s = %s;\n' %('geometry.boomlength', q['boom'])
  2644. if q['perspective']:
  2645. cdata += ' %s = %s;\n' %('geometry.perspective', q['perspective'])
  2646. if q['twist']:
  2647. cdata += ' %s = %s;\n' %('geometry.twist', q['twist'])
  2648. if q['fov']:
  2649. cdata += ' %s = %s;\n' %('geometry.fieldOfView', q['fov'])
  2650. if 'lidar' in q:
  2651. if q['lidar']:
  2652. cdata += ' %s = %s;\n' %('lidar.binStep', q['binStep']) \
  2653. + ' %s = %s;\n' %('lidar.binStart', q['binStart']) \
  2654. + ' %s = %s;\n' %('lidar.nBins', q['nBins'])
  2655. cdata += '}'
  2656. if q['fov'] and q['ideal']:
  2657. raise Exception("camera: setting both 'ideal area' and 'fov' is not allowed")
  2658. fp = open(camFile, 'w')
  2659. try:
  2660. fp.write(cdata)
  2661. finally:
  2662. fp.close()
  2663. def _writeLightFile(self, lightFile, args):
  2664. # defaults
  2665. q = {
  2666. 'light_camera' : 'simple illumination',
  2667. 'sz' : 0.,
  2668. 'sa' : 0.,
  2669. 'twist' : 0.,
  2670. }
  2671. # overwrite detaults
  2672. for a in args:
  2673. q[a] = args[a]
  2674. ldata = ' camera { \n' \
  2675. + ' %s = "%s";\n' %('camera.name', q['light_camera']) \
  2676. + ' %s = "%.1f";\n' %('geometry.zenith', float(q['sz'])) \
  2677. + ' %s = "%.1f";\n' %('geometry.azimuth', float(q['sa'])) \
  2678. + ' %s = "%.1f";\n' %('geometry.twist', float(q['twist']))
  2679. key = "sideal"
  2680. if key in q: ldata += '%s = %s\n' %('geometry.idealArea', ', '.join(map(str, map('%.1f'.__mod__, q[key]))))
  2681. key = "slook_xyz"
  2682. if key in q: ldata += '%s = %s\n' %('geometry.lookat', ', '.join(map(str, map('%.1f'.__mod__, q[key]))))
  2683. key = "sboom"
  2684. if key in q: ldata += '%s = %s\n' %('geometry.boom', q[key])
  2685. key = "sperspective"
  2686. if key in q: ldata += '%s = %s\n' %('geometry.perspecitive', q[key])
  2687. key = "sfov"
  2688. if key in q: ldata += '%s = %s\n' %('geometry.fov', q[key])
  2689. ldata += '}'
  2690. fp = open(lightFile, 'w')
  2691. try:
  2692. fp.write(ldata)
  2693. finally:
  2694. fp.close()
  2695. def _writeInputFile(self, inpFile, lightFile, camFile):
  2696. idata = '14' \
  2697. + ' ' \
  2698. + VLAB.getFullPath(camFile) \
  2699. + ' ' \
  2700. + VLAB.getFullPath(lightFile)
  2701. fp = open(inpFile, 'w')
  2702. try:
  2703. fp.write(idata)
  2704. finally:
  2705. fp.close()
  2706. def _writeGrabFile(self, grabFile, args):
  2707. gFilePath = VLAB.getFullPath(grabFile)
  2708. if VLAB.osName().startswith('Windows'):
  2709. gFilePath = gFilePath.replace("\\", "\\\\")
  2710. # 'cwd' : '$HOME/.beam/beam-vlab/auxdata/librat_scenes',
  2711. gdata = """cmd = {
  2712. 'linux' : {
  2713. 'cwd' : '$HOME/.beam/beam-vlab/auxdata/librat_scenes',
  2714. 'exe' : '$HOME/.beam/beam-vlab/auxdata/librat_lin64/src/start/start',
  2715. 'cmdline' : ['-RATv', '-m', '%s', '-RATsensor_wavebands', '$HOME/.beam/beam-vlab/auxdata/librat_scenes/%s', '$HOME/.beam/beam-vlab/auxdata/librat_scenes/%s' ],
  2716. 'stdin' : '%s',
  2717. 'stdout' : '%s',
  2718. 'stderr' : '%s',
  2719. 'env' : {
  2720. 'BPMS' : '$HOME/.beam/beam-vlab/auxdata/librat_lin64/',
  2721. 'LD_LIBRARY_PATH' : '$HOME/.beam/beam-vlab/auxdata/librat_lin64/src/lib',
  2722. }},
  2723. 'windows' : {
  2724. 'cwd' : '%HOMEDRIVE%%HOMEPATH%/.beam/beam-vlab/auxdata/librat_scenes',
  2725. 'exe' : '%HOMEDRIVE%%HOMEPATH%/.beam/beam-vlab/auxdata/librat_win32/src/start/ratstart.exe',
  2726. 'cmdline' : ['-RATv', '-m', '%s', '-RATsensor_wavebands', '%HOMEDRIVE%%HOMEPATH%/.beam/beam-vlab/auxdata/librat_scenes/%s', '%HOMEDRIVE%%HOMEPATH%/.beam/beam-vlab/auxdata/librat_scenes/%s' ],
  2727. 'stdin' : '%s',
  2728. 'stdout' : '%s',
  2729. 'stderr' : '%s',
  2730. 'env' : {
  2731. 'BPMS' : '%HOMEDRIVE%%HOMEPATH%/.beam/beam-vlab/auxdata/librat_win32'
  2732. }}
  2733. }
  2734. """
  2735. # hack to allow replacing only %s
  2736. escaped = gdata.replace("%%","\x81\x81").replace("%H","\x81H").replace("%/","\x81/")
  2737. replaced = escaped % \
  2738. (args['sorder'], args['wbfile'], args['objfile'], gFilePath+'.inp', gFilePath+'.out.log', gFilePath+'.err.log', \
  2739. args['sorder'], args['wbfile'], args['objfile'], gFilePath+'.inp', gFilePath+'.out.log', gFilePath+'.err.log')
  2740. gdata = replaced.replace("\x81", "%")
  2741. gdata += 'VLAB.doExec(cmd)\n'
  2742. try:
  2743. fp = open(gFilePath, 'w')
  2744. fp.write(gdata)
  2745. finally:
  2746. fp.close()
  2747. def main(self, args):
  2748. me=self.__class__.__name__ +'::'+VLAB.me()
  2749. VLAB.logger.info('======> %s' % me)
  2750. for a in args:
  2751. VLAB.logger.info("%s -> %s" % (a, args[a]))
  2752. # set up defaults
  2753. q = {
  2754. 'INFINITY' : 1000000,
  2755. 'lightfile' : 'light.dat',
  2756. 'camfile' : 'camera.dat',
  2757. 'wbfile' : 'wb.test.dat',
  2758. 'anglefile' : 'angles.dat',
  2759. 'objfile' : 'veglab_test.obj',
  2760. 'blacksky' : '',
  2761. 'npixels' : 1000000,
  2762. 'image' : 1,
  2763. 'rpp' : 1,
  2764. 'fov' : False,
  2765. 'sorder' : 100,
  2766. 'nice' : None,
  2767. 'boom' : 100000,
  2768. 'ideal' : False,
  2769. 'samplingPattern' : False,
  2770. 'mode' : 'scattering order',
  2771. 'opdir' : 'brdf',
  2772. 'result_root' : 'result',
  2773. 'camera_root' : 'camera',
  2774. 'light_root' : 'light',
  2775. 'grabme_root' : 'grabme',
  2776. 'look_xyz' : (150, 150, 35),
  2777. 'location' : False,
  2778. 'vz' : -1,
  2779. 'va' : -1,
  2780. 'sz' : -1,
  2781. 'sa' : -1,
  2782. }
  2783. for a in args:
  2784. if a == 'look':
  2785. q['look_xyz'] = args[a]
  2786. elif a == 'result':
  2787. q['result_root'] = args[a]
  2788. elif a == 'camera':
  2789. q['camera_root'] = args[a]
  2790. elif a == 'light':
  2791. q['light_root'] = args[a]
  2792. elif a == 'grabme':
  2793. q['grabme_root'] = args[a]
  2794. elif a == 'wb':
  2795. q['wbfile'] = args[a]
  2796. elif a == 'angles':
  2797. q['anglefile'] = args[a]
  2798. elif a == 'obj':
  2799. q['objfile'] = args[a]
  2800. else:
  2801. q[a] = args[a]
  2802. VLAB.mkDirPath('%s/%s' %(LIBRAT.SDIR, q['opdir']))
  2803. angfp = VLAB.checkFile('%s/%s' % (LIBRAT.SDIR, q['anglefile']))
  2804. wbfp = VLAB.checkFile('%s/%s' % (LIBRAT.SDIR, q['wbfile']))
  2805. objfp = VLAB.checkFile('%s/%s' % (LIBRAT.SDIR, q['objfile']))
  2806. # vz va sz sa
  2807. ang = VLAB.valuesfromfile('%s/%s' % (LIBRAT.SDIR, q['anglefile']))
  2808. if 'lookFile' in q:
  2809. lookfp = VLAB.checkFile('%s/%s' % (LIBRAT.SDIR, q['lookFile']))
  2810. q['look_xyz'] = VLAB.valuesfromfile('%s/%s' % (LIBRAT.SDIR, q['lookFile']))
  2811. if len(q['look_xyz']) == 3:
  2812. q['look_xyz'] = ((q['look_xyz']),)
  2813. if len(ang) < 4 or (len(ang) > 4 and len(ang[0]) != 4):
  2814. sys.stderr.write("%s: wrong number of fields (%i) in %s - should be 4\n"%(me, len(ang[1]), q['anglefile']))
  2815. raise Exception()
  2816. if len(ang) == 4:
  2817. ang = ((ang),)
  2818. for n, a in enumerate(ang):
  2819. q['vz'] = a[0]
  2820. q['va'] = a[1]
  2821. q['sz'] = a[2]
  2822. q['sa'] = a[3]
  2823. for ll, look in enumerate(q['look_xyz']):
  2824. lightfile = VLAB.fPath('%s/%s' % (LIBRAT.SDIR, q['opdir']), q['light_root'] + '_sz_' + str(q['sz']) + '_sa_' + str(q['sa']) + '_dat')
  2825. ligfp = VLAB.openFileIfNotExists(lightfile)
  2826. if ligfp != None:
  2827. nq = {
  2828. 'sz' : q['sz'],
  2829. 'sa' : q['sa'],
  2830. }
  2831. self._writeLightFile(lightfile, nq)
  2832. rooty = q['objfile'] + '_vz_' + str(q['vz']) + '_va_' + str(q['va']) + '_sz_' + str(q['sz']) + '_sa_' + str(q['sa']) + '_xyz_' + str(look[0]) + '_' + str(look[1]) + '_' + str(look[2]) + '_wb_' + q['wbfile']
  2833. grabme = VLAB.fPath('%s/%s' % (LIBRAT.SDIR, q['opdir']), q['grabme_root'] + '.' + rooty)
  2834. if 'dhp' in q:
  2835. location = list(look)
  2836. look[2] = q['INFINITY']
  2837. sampling = 'circular'
  2838. if not VLAB.fileExists(grabme):
  2839. grabfp = VLAB.openFileIfNotExists(grabme)
  2840. q['grabme_log'] = grabme + '.log'
  2841. q['camfile'] = VLAB.fPath('%s/%s' % (LIBRAT.SDIR, q['opdir']), q['camera_root'] + '.' + rooty)
  2842. q['oproot'] = VLAB.fPath('%s/%s' % (LIBRAT.SDIR, q['opdir']), q['result_root'] + '.' + rooty)
  2843. nq = {
  2844. 'name' : 'simple camera',
  2845. 'vz' : q['vz'],
  2846. 'va' : q['va'],
  2847. 'integral' : q['oproot'],
  2848. 'integral_mode' : q['mode'],
  2849. 'npixels' : q['npixels'],
  2850. 'rpp' : q['rpp'],
  2851. 'boom' : q['boom'],
  2852. 'ideal' : q['ideal'],
  2853. 'look_xyz' : look,
  2854. 'location' : q['location'],
  2855. 'fov' : q['fov'],
  2856. 'samplingPattern' : q['samplingPattern'],
  2857. 'file' : q['camfile'],
  2858. 'grabme_log' : q['grabme_log'],
  2859. 'camfile' : q['camfile']
  2860. }
  2861. if 'image' in q:
  2862. if 'hips' in q:
  2863. nq['imfile'] = q['oproot'] + '.hips'
  2864. else:
  2865. nq['imfile'] = q['oproot'] + '.bim'
  2866. else:
  2867. nq['imfile'] = 'image'
  2868. self._writeCamFile(nq['camfile'], nq)
  2869. self._writeInputFile(grabme + '.inp', lightfile, nq['camfile'])
  2870. nq = {
  2871. 'blacksky' : q['blacksky'],
  2872. 'sorder' : q['sorder'],
  2873. 'objfile' : q['objfile'],
  2874. 'wbfile' : q['wbfile']
  2875. }
  2876. self._writeGrabFile(grabme, nq)
  2877. execfile(grabme)
  2878. VLAB.logger.info('done')
  2879. #############################################################################
  2880. class Librat_dolibradtran:
  2881. def main(self, q):
  2882. # initial arguments for doLibradtran
  2883. r = {
  2884. 'CO2' : q[VLAB.P_AtmosphereCO2],
  2885. 'H2O' : q[VLAB.P_AtmosphereWater],
  2886. 'O3' : q[VLAB.P_AtmosphereOzone],
  2887. 'scene' : q['obj'],
  2888. 'aerosol' : q[VLAB.P_AtmosphereAerosol],
  2889. 'sensor' : q['sensor'],
  2890. 'rpv_file' : VLAB.path.join(LIBRAT.SDIR, q['rpv'])
  2891. }
  2892. VLAB.mkDirPath('%s/%s' % (LIBRAT.SDIR, q['opdir']))
  2893. angfp = VLAB.checkFile('%s/%s' % (LIBRAT.SDIR, q['angfile']))
  2894. wbfp = VLAB.checkFile('%s/%s' % (LIBRAT.SDIR, q['wbfile']))
  2895. rpvfp = VLAB.checkFile(r['rpv_file'])
  2896. rpv = VLAB.valuesfromfile(r['rpv_file'])
  2897. if len(rpv[0]) != 4: # length of index 1 because index 0 is heading
  2898. sys.stderr.write("%s: rpv file %s wrong no. of cols (should be 4: lambda (nm), rho0, k, theta\n" % (sys.argv[0], rpv_file))
  2899. raise Exception()
  2900. angt = VLAB.valuesfromfile('%s/%s' % (LIBRAT.SDIR, q['angfile']))
  2901. wb = [i[1] for i in VLAB.valuesfromfile('%s/%s' % (LIBRAT.SDIR, q['wbfile']))]
  2902. nbands = len(wb)
  2903. wbstep = 1
  2904. if q['v']:
  2905. sys.stderr.write('%s: wbmin = %i, wbmax = %i, wbstep = %i\n'%(sys.argv[0],min(wb),max(wb),wbstep))
  2906. if q['v']:
  2907. # only do all angles if time not specified, if time specified use that to get sza and phi0
  2908. if q['lat'] and ['lon'] and ['time']:
  2909. sys.stderr.write("%s: doing lat lon time, not using sun angles in file %s\n" % (sys.argv[0], q['anglefile']))
  2910. # check for op file if required
  2911. if not VLAB.fileExists('%s/%s' % (LIBRAT.SDIR, q['plotfile'])):
  2912. VLAB.logger.info('%s/%s' % (LIBRAT.SDIR, q['plotfile']))
  2913. plotfilefp = VLAB.openFileIfNotExists('%s/%s' % (LIBRAT.SDIR, q['plotfile']))
  2914. else:
  2915. sys.stderr.write('%s: plotfile %s already exists - move/delete and re-run\n'%(sys.argv[0],q['plotfile']))
  2916. raise Exception('%s: plotfile %s already exists - move/delete and re-run\n'%(sys.argv[0],q['plotfile']))
  2917. # loop over angles and do all wb at once for each angle
  2918. for a, aa in enumerate(angt):
  2919. # need special case for 1 angle only, in which case angt = 4
  2920. if len(angt) == 1:
  2921. vzz = angt[0][0]
  2922. vaa = angt[0][1]
  2923. szz = angt[0][2]
  2924. saa = angt[0][3]
  2925. else:
  2926. # sz, saz generated by user-specified dates and times, lat, lon if that option given
  2927. # AND: need to check angles that we are absolute i.e. no -ves
  2928. vzz = angt[a][0]
  2929. vaa = angt[a][1]
  2930. szz = angt[a][2]
  2931. saa = angt[a][3]
  2932. VLAB.logger.info(str(vzz))
  2933. umu = math.cos(vzz)
  2934. angstr = str(vzz) + '_' + str(vaa) + '_' + str(szz) + '_' + str(saa)
  2935. libradtran_ip = VLAB.fPath(LIBRAT.SDIR, 'ip.' + q['root'] + '.' + q['wbfile'] + '_' + angstr)
  2936. libradtran_op = VLAB.fPath(LIBRAT.SDIR, 'op.' + q['root'] + '.' + q['wbfile'] + '_' + angstr)
  2937. if q['v']:
  2938. sys.stderr.write('%s: doing ip file %s\n'%(sys.argv[0],libradtran_ip))
  2939. #sort out zen/azimuth angles i.e. if vz is -ve
  2940. if vzz < 0:
  2941. # doesn't matter as we use umu from above anyway but ...
  2942. vzz *= -1.
  2943. if vaa < 0:
  2944. vaa = 180. - vaa
  2945. if szz < 0:
  2946. szz *= -1.
  2947. if saa < 0:
  2948. saa = 180. - saa
  2949. # add view angles
  2950. def valueorlisttostring(val):
  2951. try:
  2952. return ' '.join(map(str, val))
  2953. except TypeError:
  2954. return str(val)
  2955. r['umu'] = valueorlisttostring(umu)
  2956. r['phi'] = valueorlisttostring(vaa)
  2957. # add sz angles
  2958. if q['lat'] and q['lon'] and q['time']:
  2959. r['latitude'] = q['lat']
  2960. r['longitude'] = q['lon']
  2961. r['time'] = q['time']
  2962. else:
  2963. # print out sun angles
  2964. r['sza'] = valueorlisttostring(szz)
  2965. r['phi0'] = valueorlisttostring(saa)
  2966. # write out wavelengths i.e. min and max. Step is determined by step in solar file i.e. 1nm default
  2967. r['wavelength'] = str(int(min(wb))) + ' ' + str(int(max(wb)))
  2968. # run the libradtran command
  2969. r['infile'] = libradtran_ip
  2970. r['outfile'] = libradtran_op
  2971. for k,v in r.items():
  2972. VLAB.logger.info(" [%s] => %s" % (k, v))
  2973. VLAB.doLibradtran(r)
  2974. # now check if a single angle (i.e. angt.size == 4 ) and if so, break out of loop
  2975. if 4 == len(angt) * len(angt[0]) or (q['lat'] and q['lon'] and q['time']): break
  2976. # finish angle loop & srt out collating results into LUT file at end if required
  2977. # write header line i.e. vz va sz sa wb_min -> wb_max
  2978. plotfilefp.write('# vz va sz sa %e %e %e\n' % (min(wb), max(wb), wbstep))
  2979. # plotfilefp.flush()
  2980. for f in [f for f in VLAB.listdir('%s/%s' % (LIBRAT.SDIR, q['opdir'])) if f.startswith('op.')]:
  2981. vzz = f.split('_')[-4]
  2982. vaa = f.split('_')[-3]
  2983. szz = f.split('_')[-2]
  2984. saa = f.split('_')[-1]
  2985. d = VLAB.valuesfromfile('%s/%s' % (LIBRAT.SDIR, f),transpose=True)
  2986. plotfilefp.write('%s %s %s %s ' % (vzz,vaa,szz,saa))
  2987. plotfilefp.write(' '.join(map(str, d[1])) + '\n')
  2988. plotfilefp.flush()
  2989. plotfilefp.close()
  2990. #############################################################################
  2991. class Librat_drivers:
  2992. """ setup the scene"""
  2993. def main(self, args):
  2994. me=self.__class__.__name__ +'::'+VLAB.me()
  2995. # initialize with defaults
  2996. # sun angles for eg UK (lat 51' 0" 0' 0") 1 Jun 2013 10:30 am
  2997. # sun_position -lat 51 -lon 0 -date 01:05:2013 -t 10:30:00
  2998. # va, sz, sa = 0, 34, 141
  2999. q = {
  3000. 'vz' : 0,
  3001. 'va' : 0,
  3002. 'sz' : 34,
  3003. 'sa' : 141,
  3004. 'nsamples' : 1000,
  3005. 'xdims' : (0, 300, 30),
  3006. 'ydims' : (0, 300, 30),
  3007. 'z' : 0,
  3008. 'angFile' : 'angles.dat',
  3009. 'lookFile' : 'look.dat',
  3010. }
  3011. # fill in: lookFile, angFile, xdums, ydims, z, sz, sa, nsamples...
  3012. for a in args:
  3013. if a == 'angles':
  3014. q['angFile'] = args[a]
  3015. elif a == 'look':
  3016. q['lookFile'] = args[a]
  3017. elif a == 'n':
  3018. q['nsamples'] = args[a]
  3019. else:
  3020. q[a] = args[a]
  3021. if 'msi' in q:
  3022. # across whole swath
  3023. # zmin, vzmax, vzstep = -22, 54, 4
  3024. q['angles'] = (0, 0, 0, 0)
  3025. q['angles'] = (q['vz'], q['va'], q['sz'], q['sa'])
  3026. elif 'olci' in q:
  3027. q['vzmin'], q['vzmax'], q['vzstep'] = -22, 54, 4
  3028. q['vzz'] = VLAB.frange(q['vzmin'], q['vzmax']+q['vzstep'], q['vzstep'])
  3029. q['angles'] = [[0. for col in range(4)] for row in range(len(q['vzz']))]
  3030. q['angles'][:,0] = q['vzz']
  3031. q['angles'][:,1] = q['vz']
  3032. q['angles'][:,2] = q['sz']
  3033. q['angles'][:,3] = q['sa']
  3034. elif 'around' in q:
  3035. q['vamin'], q['vamax'], q['vastep'] = 0, 360, 10
  3036. q['vaa'] = VLAB.frange(q['vamin'], q['vamax']+q['vastep'], q['vastep'])
  3037. q['vz'], q['sz'], q['sa'] = 70., 30, 90
  3038. q['angles'] = [[0. for col in range(4)] for row in range(len(q['vaa']))]
  3039. q['angles'][:,0] = q['vz']
  3040. q['angles'][:,1] = q['vaa']
  3041. q['angles'][:,2] = q['sz']
  3042. q['angles'][:,3] = q['sa']
  3043. elif 'multiple' in q:
  3044. # this one for multiple vz, va angles
  3045. q['vzmin'], q['vzmax'], q['vzstep'] = -70, 70, 10
  3046. q['vamin'], q['vamax'], q['vastep'] = 0, 340, 20
  3047. q['vzz'] = VLAB.frange(q['vzmin'], q['vzmax']+q['vzstep'], q['vzstep'])
  3048. q['vaa'] = VLAB.frange(q['vamin'], q['vamax']+q['vastep'], q['vastep'])
  3049. q['angles'] = [[0. for col in range(4)] for row in range(len(q['vzz'])*len(q['vzz']))]
  3050. for n, va in enumerate(q['vaa']):
  3051. q['angles'][n*len(q['vzz']):(n+1)*len(q['vzz']),0] = q['vzz']
  3052. q['angles'][n*len(q['vzz']):(n+1)*len(q['vzz']),1] = q['vz']
  3053. q['angles'][n*len(q['vzz']):(n+1)*len(q['vzz']),2] = q['sz']
  3054. q['angles'][n*len(q['vzz']):(n+1)*len(q['vzz']),3] = q['sa']
  3055. elif 'random' in q:
  3056. # random n samples of COSINE-WEIGHTED view and illum angles
  3057. # In order that we get the required number, nsamples, AND can disregard all those with
  3058. # vz > 70 and vz < -70 (not valid for RPV) do twice as many as you need, discard
  3059. # all those outside the angle range and then take the first n.
  3060. nn = q['nsamples']*2
  3061. if VLAB.CONF_RND_REPRODUCE:
  3062. rState = VLAB.rndInit(17)
  3063. else:
  3064. rState = VLAB.rndInit()
  3065. # view angles first
  3066. u1 = [VLAB.rndNextFloat(rState) for i in range(nn)]
  3067. r = [math.sqrt(i) for x in u1]
  3068. theta = [2.*math.pi*x for x in [VLAB.rndNextFloat(rState) for i in range(nn)]]
  3069. x = [r[i] * math.cos(theta[i]) for i in range(nn)]
  3070. y = [r[i] * math.sin(theta[i]) for i in range(nn)]
  3071. z = [math.sqrt(1 - u1[i]) for i in range(nn)]
  3072. q['vz'] = [math.acos(z[i]) for i in range(nn)]
  3073. q['va'] = [math.atan(y[i]/x[i]) for i in range(nn)]
  3074. # if x -ve then vz -ve
  3075. for i in range(nn):
  3076. if (x[i]<0):
  3077. q['vz'][i] = q['vz'][i] * -1.
  3078. # sun angles
  3079. u1 = [VLAB.rndNextFloat(rState) for i in range(nn)]
  3080. r = [math.sqrt(i) for x in u1]
  3081. theta = [2.*math.pi*x for x in [VLAB.rndNextFloat(rState) for i in range(nn)]]
  3082. x = [r[i] * math.cos(theta[i]) for i in range(nn)]
  3083. y = [r[i] * math.sin(theta[i]) for i in range(nn)]
  3084. z = [math.sqrt(1 - u1[i]) for i in range(nn)]
  3085. #np.savetxt('rpv.angles.test.plot',np.transpose([x,y,z]),fmt='%.6f')
  3086. q['sz'] = [math.acos(z[i]) for i in range(nn)]
  3087. q['sa'] = [math.atan(y[i]/x[i]) for i in range(nn)]
  3088. # if x -ve then sz -ve
  3089. for i in range(nn):
  3090. if (x[i]<0):
  3091. q['sz'][i] = q['sz'][i] * -1.
  3092. vzdeg = [VLAB.r2d(q['vz'][i]) for i in range(nn)]
  3093. vadeg = [VLAB.r2d(q['va'][i]) for i in range(nn)]
  3094. szdeg = [VLAB.r2d(q['sz'][i]) for i in range(nn)]
  3095. sadeg = [VLAB.r2d(q['sa'][i]) for i in range(nn)]
  3096. # zip does a transpose
  3097. angles = zip(vzdeg, vadeg, szdeg, sadeg)
  3098. angles2 = list()
  3099. for row in angles:
  3100. if (row[0] > -70.) and (row[0] <= 70.) and (row[2] > -70.) and (row[2] <= 70.):
  3101. angles2.append(row)
  3102. # now take the first n
  3103. q['angles'] = angles2[0:q['nsamples']]
  3104. # x = np.sin(np.deg2rad(angles[:,0])) * np.cos(np.deg2rad(angles[:,1]))
  3105. # y = np.sin(np.deg2rad(angles[:,0])) * np.sin(np.deg2rad(angles[:,1]))
  3106. # z = np.cos(np.deg2rad(angles[:,0]))
  3107. #np.savetxt('rpv.angles.test',angles,fmt='%.6f')
  3108. #np.savetxt('rpv.angles.test.plot',np.transpose([x,y,z]),fmt='%.6f')
  3109. else:
  3110. # default
  3111. q['vzmin'], q['vzmax'], q['vzstep'] = -70, 70, 5
  3112. q['vzz'] = VLAB.frange(q['vzmin'],q['vzmax']+q['vzstep'],q['vzstep'])
  3113. q['angles'] = [[0. for col in range(4)] for row in range(len(q['vzz']))]
  3114. q['angles'][:,0] = q['vzz']
  3115. q['angles'][:,1] = q['va']
  3116. q['angles'][:,2] = q['sz']
  3117. q['angles'][:,3] = q['sa']
  3118. VLAB.savetxt(q['angFile'], q['angles'], fmt='%.1f')
  3119. if 'lookFile' in q:
  3120. x = VLAB.frange(q['xdims'][0],q['xdims'][1],q['xdims'][2])
  3121. y = VLAB.frange(q['ydims'][0],q['ydims'][1],q['ydims'][2])
  3122. looktrans = [[0. for col in range(len(x)*len(y))] for row in range(3)]
  3123. for n, yy in enumerate(y):
  3124. looktrans[0][n*len(x):(n+1)*len(x)] = x
  3125. looktrans[1][n*len(x):(n+1)*len(x)] = [yy for i in range(len(y))]
  3126. looktrans[2][n*len(x):(n+1)*len(x)] = [0. for i in range(len(x))]
  3127. # zip does a transpose
  3128. look = zip(*looktrans)
  3129. VLAB.savetxt(q['lookFile'],look,fmt='%.1f')
  3130. #############################################################################
  3131. class Librat_plot:
  3132. """plot results"""
  3133. def main(self, args):
  3134. me=self.__class__.__name__ +'::'+VLAB.me()
  3135. VLAB.logger.info('======> %s' % me )
  3136. for a in args:
  3137. VLAB.logger.info("%s -> %s" % (a, args[a]))
  3138. q = {
  3139. 'spec' : 'SPECTRAL_TEST/result.laegeren.obj_vz_0.0_va_0.0_sz_34.0_sa_141.0_xyz_150.0_150.0_700.0_wb_wb.full_spectrum.dat.direct',
  3140. 'wbfile' : 'wb.full_spectrum.dat',
  3141. 'root' : 'OLCI_brdf.scene/result.laegeren.obj',
  3142. 'spec' : False,
  3143. 'brdf' : True
  3144. }
  3145. for a in args:
  3146. if a == 'angles':
  3147. q['angfile'] = args[a]
  3148. else:
  3149. q[a] = args[a]
  3150. if q['spec']:
  3151. self.spec_plot(q['spec'], q['wbfile'])
  3152. if q['brdf']:
  3153. self.brdf_plot(q['root'], q['angfile'], q['wbfile'])
  3154. def spec_plot(self,spec,wbspec):
  3155. wbspec_contents = VLAB.valuesfromfile('%s/%s' % (LIBRAT.SDIR, wbspec), transpose=True)
  3156. wb = wbspec_contents[1];
  3157. op1 = spec + '.plot.png'
  3158. data = wbspec_contents
  3159. refl = data[1:,].sum(axis=1)
  3160. # TODO Implement rest of function
  3161. raise Exception("spec_plot()")
  3162. def brdf_plot(self,root,angfile,wbfile):
  3163. opdat = LIBRAT.SDIR + '/' + root + '.brdf.dat'
  3164. opplot = LIBRAT.SDIR + '/' + root + '.brdf.png'
  3165. ang = VLAB.valuesfromfile('%s/%s' % (LIBRAT.SDIR, angfile), transpose=True)
  3166. wb = VLAB.valuesfromfile('%s/%s' % (LIBRAT.SDIR, wbfile), transpose=True)[1]
  3167. result = [[0. for i in range(len(wb))] for i in range(len(ang[0]))]
  3168. ff = [root.split('/')[0] + '/' + f for f in VLAB.listdir(root.split('/')[0])
  3169. if f.endswith('.direct') and f.startswith(root.split('/')[1])]
  3170. for f in ff:
  3171. fsplit = f.split('_')
  3172. vz = f.split('_')[fsplit.index('vz') + 1]
  3173. va = f.split('_')[fsplit.index('va') + 1]
  3174. sz = f.split('_')[fsplit.index('sz') + 1]
  3175. sa = f.split('_')[fsplit.index('sa') + 1]
  3176. data = VLAB.valuesfromfile('%s/%s' % (LIBRAT.SDIR, f), transpose=True)
  3177. refl = [reduce(lambda x, y : x + y, i) for i in data[1:]]
  3178. result[zip(*VLAB.awhere(
  3179. VLAB.treemap(lambda x : x == float(vz), ang)))[1][0]] = refl
  3180. # TODO test and cleanup (brdf_plot)
  3181. # coords = VLAB.treemap(lambda x : x == float(vz), ang[0])
  3182. # coords = map(lambda x, y : x & y, coords,
  3183. # VLAB.treemap(lambda x : x == float(va), ang[1]))
  3184. # coords = map(lambda x, y : x & y, coords,
  3185. # VLAB.treemap(lambda x : x == float(sz), ang[2]))
  3186. # coords = map(lambda x, y : x & y, coords,
  3187. # VLAB.treemap(lambda x : x == float(sa), ang[3]))
  3188. coords = VLAB.makemaskeq(ang[0], float(vz))
  3189. coords = VLAB.maskand(coords, VLAB.makemaskeq(ang[1], float(va)))
  3190. coords = VLAB.maskand(coords, VLAB.makemaskeq(ang[2], float(sz)))
  3191. coords = VLAB.maskand(coords, VLAB.makemaskeq(ang[3], float(sa)))
  3192. coords = VLAB.awhere(coords)
  3193. result[coords[0][0]] = refl
  3194. dataset = VLAB.make_dataset()
  3195. for b in [3, 7]:
  3196. VLAB.plot(dataset, ang[0], [i[b] for i in result],
  3197. "waveband: %.1f" % wb [b])
  3198. chart = VLAB.make_chart("plot.py out", "view zenith angle (deg.)",
  3199. u"\u03A1", dataset)
  3200. sys.stderr.write('%s: plotting brdf to: %s\n'%(sys.argv[0], opplot))
  3201. sys.stderr.write('%s: saving brdf data to: %s\n'%(sys.argv[0], opdat))
  3202. outdata = [[0. for i in xrange(len(result[0]) + len(ang))]
  3203. for j in xrange(len(result))]
  3204. VLAB.replacerectinarray(outdata, zip(*ang), 0, 0, len(result), len(ang))
  3205. # FIXME: assign result instead of zip(*ang) (see plot.py:88)
  3206. VLAB.replacerectinarray(outdata, result, 0, len(ang), len(result), len(result[0]) + len(ang))
  3207. VLAB.savetxt(opdat, outdata, fmt='%.4f')
  3208. VLAB.save_chart(chart, opplot)
  3209. class Librat_rpv_invert:
  3210. """rpv inversion for integration with libmodtran"""
  3211. def main(self, args):
  3212. me=self.__class__.__name__ +'::'+VLAB.me()
  3213. VLAB.logger.info('======> %s' % me)
  3214. for a in args:
  3215. VLAB.logger.info("%s -> %s" % (a, args[a]))
  3216. # defaults
  3217. q = {
  3218. 'dataf' : 'rpv.rami.2/result.HET01_DIS_UNI_NIR_20.obj.brdf.dat',
  3219. 'wbfile' : 'wb.MSI.dat',
  3220. 'wbNum' : 3, # 665 nm in this case
  3221. 'verbose' : 1,
  3222. 'plot' : 1,
  3223. 'show' : 0
  3224. }
  3225. for a in args:
  3226. if a == 'wb':
  3227. q['wbfile'] = args[a]
  3228. else:
  3229. q[a] = args[a]
  3230. wb = VLAB.valuesfromfile('%s/%s' % (LIBRAT.SDIR, q['wbfile']), transpose=True)[1]
  3231. data = VLAB.valuesfromfile('%s/%s' % (LIBRAT.SDIR, q['dataf']), transpose=True)
  3232. # check shape of 2 data files i.e. that there are same no. of wbs on each line of datafile ( + 4 angles)
  3233. if len(wb) != len(data) - 4:
  3234. sys.stderr.write('%s: no of wavebands different in brdf file %s and wb file %s\n'%(sys.argv[0],q['dataf'],q['wbfile']))
  3235. raise Exception('%s: no of wavebands different in brdf file %s and wb file %s\n'%(sys.argv[0],q['dataf'],q['wbfile']))
  3236. rho0, k, bigtet, rhoc = 0.03, 1.2, 0.1, 0.2
  3237. if q['three']:
  3238. params = [rho0, k, bigtet]
  3239. else:
  3240. params = [rho0, k, bigtet, rhoc]
  3241. if args['paramfile']:
  3242. opdat = args['paramfile']
  3243. else:
  3244. opdat = q['dataf'] + '.params.dat'
  3245. if q['verbose']: sys.stderr.write('%s: saving params to %s\n'%(sys.argv[0], opdat))
  3246. # create the file if it doesn't exist
  3247. dfp = VLAB.openFileIfNotExists('%s/%s' % (LIBRAT.SDIR, opdat))
  3248. if dfp != None:
  3249. dfp.close()
  3250. # open the previously created file
  3251. opfp = open('%s/%s' % (LIBRAT.SDIR, opdat), 'w')
  3252. if q['three']:
  3253. opfp.write('# wb rho0 k bigtet\n')
  3254. else:
  3255. opfp.write('# wb rho0 k bigtet rhoc\n')
  3256. ymin, ymax = (0, 0.25)
  3257. xmin, xmax = (-75., 75)
  3258. for wbNum, band in enumerate(wb):
  3259. if q['verbose']: sys.stderr.write('%s: doing band %i (%f)\n'%(sys.argv[0], wbNum, band))
  3260. invdata = [[0. for i in xrange(len(data))] for i in xrange(5)]
  3261. invdata[0:4] = data[0:4]
  3262. invdata[4] = data[4 + q['wbNum']]
  3263. # invdata = [[0. for i in xrange(15)] for i in xrange(5)]
  3264. # invdata[0:4] = [i[0:15] for i in data[0:4]]
  3265. # invdata[4] = data[4 + q['wbNum']][0:15]
  3266. porig = params
  3267. p_est = params
  3268. p_est = VLAB.Minimize_minimize(self.obj, params, args=(invdata,))[0]
  3269. if q['three']:
  3270. p_est = VLAB.min_l_bfgs_b(self.obj, p_est, args=(invdata,), bounds=((0., None), (0., None), (None, None)))
  3271. else:
  3272. p_est = VLAB.min_l_bfgs_b(self.obj, p_est, args=(invdata,), bounds=((0., None), (0., None),(None, None), (None, None)))
  3273. r = self.rpv(p_est, invdata)
  3274. rmse = math.sqrt(reduce(lambda x, y : x + y, map(lambda x : x ** 2, VLAB.suba(r, invdata[4]))))
  3275. if q['three']:
  3276. opfp.write('%.1f %.8f %.8f %.8f\n' % (band, p_est[0], p_est[1], p_est[2]))
  3277. else:
  3278. opfp.write('%.1f %.8f %.8f %.8f %.8f\n' % (band, p_est[0], p_est[1], p_est[2], p_est[3]))
  3279. if q['plot']:
  3280. if q['plotfile']:
  3281. opplot = VLAB.path.join(LIBRAT.SDIR, q['plotfile'] + '.inv.wb.' + str(wbNum) + '.png')
  3282. else:
  3283. opplot = VLAB.path.join(LIBRAT.SDIR, q['dataf'] + '.inv.wb.' + str(wbNum) + '.png')
  3284. if q['verbose']: sys.stderr.write('%s: plotting to %s\n' % (sys.argv[0], opplot))
  3285. dataset = VLAB.make_dataset()
  3286. VLAB.plot(dataset, invdata[0], invdata[4], "original")
  3287. VLAB.plot(dataset, invdata[0], r, "inverted")
  3288. chart = VLAB.make_chart("", "vza (deg)", u"\u03A1", dataset)
  3289. dataset = None
  3290. VLAB.save_chart(chart, opplot)
  3291. chart = None
  3292. # TODO test plot code
  3293. opfp.close()
  3294. def obj(self, p, x):
  3295. fwd = self.rpv(p, x)
  3296. obs = x[4]
  3297. sse = reduce(lambda x, y : x + y,
  3298. map(lambda x : x ** 2,
  3299. VLAB.suba(obs, fwd)))
  3300. return sse
  3301. def rpv(self, params, data):
  3302. if len(params) == 4:
  3303. rho0, k, bigtet, rhoc = params
  3304. else:
  3305. rhoc = 1
  3306. rho0, k, bigtet = params
  3307. cosv = VLAB.cosa(data[0])
  3308. coss = VLAB.fabsa(VLAB.cosa(data[2]))
  3309. cosv = VLAB.replaceinarray(cosv, lambda x : x == 0, 1e-20)
  3310. coss = VLAB.replaceinarray(coss, lambda x : x == 0, 1e-20)
  3311. sins = VLAB.sqrta(map(lambda x : 1. - x ** 2, coss))
  3312. sinv = VLAB.sqrta(map(lambda x : 1. - x ** 2, cosv))
  3313. relphi = VLAB.suba(map(VLAB.d2r, data[1]),
  3314. map(VLAB.d2r, data[3]))
  3315. relphi = map(lambda x : {True : 2 * math.pi - x, False : x}
  3316. [x > math.pi], relphi)
  3317. cosp = map(lambda x : -1. * x, VLAB.cosa(relphi))
  3318. tans = VLAB.diva(sins, coss)
  3319. tanv = VLAB.diva(sinv, cosv)
  3320. csmllg = VLAB.adda(VLAB.mula(coss, cosv),
  3321. VLAB.mula(VLAB.mula(sins, sinv), cosp))
  3322. bigg = VLAB.sqrta(
  3323. VLAB.suba(
  3324. VLAB.adda(map(lambda x : x ** 2, tans), map(lambda x : x ** 2, tanv)),
  3325. VLAB.mula(VLAB.mula(map(lambda x : x * 2.0, tans), tanv), cosp)))
  3326. bgthsq = bigtet ** 2
  3327. expon = k - 1.0
  3328. if expon != 0.0:
  3329. f1 = VLAB.mula(VLAB.powa(VLAB.mula(coss, cosv), expon),
  3330. VLAB.powa(VLAB.adda(coss, cosv), expon))
  3331. else:
  3332. fi = [1. for i in coss]
  3333. denom = VLAB.powa(map(lambda x : 1. + bgthsq + 2. * bigtet * x, csmllg),
  3334. 1.5)
  3335. f2 = list(denom)
  3336. f2 = map(lambda x : {True : (lambda : (1.0 - bgthsq) * 1e20),
  3337. False : (lambda : (1.0 - bgthsq) / x)}[x == 0.](), relphi)
  3338. f3 = map(lambda x : 1.0 + (1 - rhoc) / (1. + x), bigg)
  3339. return map(lambda x : rho0 * x, VLAB.mula(VLAB.mula(f1, f2), f3))
  3340. #############################################################################
  3341. class LIBRAT:
  3342. if VLAB.osName().startswith('Windows'):
  3343. SDIR=VLAB.expandEnv('%HOMEDRIVE%%HOMEPATH%/.beam/beam-vlab/auxdata/librat_scenes')
  3344. else:
  3345. SDIR=VLAB.expandEnv('$HOME/.beam/beam-vlab/auxdata/librat_scenes')
  3346. """Integration glue for calling external LIBRAT programs"""
  3347. def __init__(self):
  3348. me=self.__class__.__name__ +'::'+VLAB.me()
  3349. VLAB.logger.info('%s: constructor completed...' % me)
  3350. def doProcessingTests(self, pm, args):
  3351. """do processing tests for LIBRAT processor"""
  3352. me=self.__class__.__name__ +'::'+VLAB.me()
  3353. if (pm != None):
  3354. pm.beginTask("Computing...", 10)
  3355. # ensure at least 1 second to ensure progress popup feedback
  3356. time.sleep(1)
  3357. cmd = {
  3358. 'linux' : {
  3359. 'cwd' : '$HOME/.beam/beam-vlab/auxdata/librat_lin64/src/start',
  3360. 'exe' : '$HOME/.beam/beam-vlab/auxdata/librat_lin64/src/start/start',
  3361. 'cmdline' : [
  3362. '-sensor_wavebands', 'wavebands.dat', '-m', '100',
  3363. '-sun_position', '0', '0', '10', 'test.obj'],
  3364. 'stdin' : '$HOME/.beam/beam-vlab/auxdata/librat_lin64/src/start/starttest.ip',
  3365. 'stdout' : None,
  3366. 'stderr' : None,
  3367. 'env' : {
  3368. 'LD_LIBRARY_PATH' : '$HOME/.beam/beam-vlab/auxdata/librat_lin64/src/lib/',
  3369. 'BPMS' : '$HOME/.beam/beam-vlab/auxdata/librat_lin64/'
  3370. }},
  3371. 'windows' : {
  3372. 'cwd' : '%HOMEDRIVE%%HOMEPATH%/.beam/beam-vlab/auxdata/librat_windows/src/start',
  3373. 'exe' : '%HOMEDRIVE%%HOMEPATH%/.beam/beam-vlab/auxdata/librat_windows/src/start/ratstart.exe',
  3374. 'cmdline' : [
  3375. '-sensor_wavebands', 'wavebands.dat', '-m', '100',
  3376. '-sun_position', '0', '0', '10', 'test.obj'],
  3377. 'stdin' : '%HOMEDRIVE%%HOMEPATH%/.beam/beam-vlab/auxdata/librat_windows/src/start/starttest.ip',
  3378. 'stdout' : None,
  3379. 'stderr' : None,
  3380. 'env' : {
  3381. 'BPMS' : '%HOMEDRIVE%%HOMEPATH%/.beam/beam-vlab/auxdata/librat_windows'
  3382. }}
  3383. }
  3384. VLAB.doExec(cmd)
  3385. #
  3386. # see https://github.com/netceteragroup/esa-beam/blob/master/beam-3dveglab-vlab/src/main/scenes/librat_scenes/libradtran.README
  3387. #
  3388. drivers = Librat_drivers()
  3389. dobrdf = Librat_dobrdf()
  3390. plot = Librat_plot()
  3391. rpv_invert = Librat_rpv_invert()
  3392. dolibradtran = Librat_dolibradtran()
  3393. args = {
  3394. 'random' : True,
  3395. 'n' : 1000,
  3396. 'angles' : 'angles.rpv.2.dat',
  3397. }
  3398. # drivers.main(args)
  3399. # RAMI test case
  3400. args = {
  3401. 'v' : True,
  3402. 'nice' : 19,
  3403. 'obj' : 'HET01_DIS_UNI_NIR_20.obj',
  3404. 'hips' : True,
  3405. 'wb' : 'wb.MSI.dat',
  3406. 'ideal' : (300., 300.),
  3407. 'look' : (150., 150., 710.),
  3408. 'rpp' : 4,
  3409. 'npixels' : 10000,
  3410. 'boom' : 786000,
  3411. 'angles' : 'angles.rpv.2.dat',
  3412. 'opdir' : 'rpv.rami'
  3413. }
  3414. # dobrdf.main(args)
  3415. # LAEGEREN test case
  3416. args = {
  3417. 'v' : True,
  3418. 'nice' : 19,
  3419. 'obj' : 'laegeren.obj.lai.1',
  3420. 'hips' : True,
  3421. 'wb' : 'wb.MSI.dat',
  3422. 'ideal' : (300., 300.),
  3423. 'look' : (150., 150., 710.),
  3424. 'rpp' : 4,
  3425. 'npixels' : 10000,
  3426. 'boom' : 786000 ,
  3427. 'angles' : 'angles.rpv.2.dat',
  3428. 'opdir' : 'rpv.laegeren'
  3429. }
  3430. # dobrdf.main(args)
  3431. # FULL SPECTRUM RAMI test case
  3432. args = {
  3433. 'v' : True,
  3434. 'nice' : 19,
  3435. 'obj' : 'HET01_DIS_UNI_NIR_20.obj',
  3436. 'wb' : 'wb.full_spectrum.1nm.dat',
  3437. 'ideal' : (80., 80.),
  3438. 'look' : (0., 0., 0.),
  3439. 'rpp' : 4,
  3440. 'npixels' : 10000,
  3441. 'boom' : 786000,
  3442. 'angles' : 'angle.rpv.cosDOM.dat',
  3443. 'opdir' : 'dart.rpv.rami'
  3444. }
  3445. # dobrdf.main(args)
  3446. # FULL SPECTRUM LAEGEREN test case
  3447. args = {
  3448. 'v' : True,
  3449. 'nice' : 19,
  3450. 'obj' : 'laegeren.obj.lai.1',
  3451. 'wb' : 'wb.full_spectrum.1nm.dat',
  3452. 'ideal' : (300., 300),
  3453. 'look' : (150., 150., 710),
  3454. 'rpp' : 4,
  3455. 'npixels' : 10000,
  3456. 'boom' : 786000,
  3457. 'angles' : 'angle.rpv.cosDOM.dat',
  3458. 'opdir' : 'dart.rpv.laegeren'
  3459. }
  3460. # dobrdf.main(args)
  3461. args = {
  3462. 'brdf' : True,
  3463. 'angles' : 'angles.rpv.2.dat',
  3464. 'wbfile' : 'wb.MSI.dat',
  3465. 'bands' : (4, 7),
  3466. 'root' : 'rpv.rami/result.HET01_DIS_UNI_NIR_20.obj'
  3467. }
  3468. # plot.main(args)
  3469. # RAMI
  3470. args = {
  3471. 'brdf' : True,
  3472. 'angles' : 'angles.rpv.2.dat',
  3473. 'wbfile' : 'wb.MSI.dat',
  3474. 'root' : 'rpv.rami.2/result.HET01_DIS_UNI_NIR_20.obj',
  3475. 'bands' : (4, 7),
  3476. 'v' : True
  3477. }
  3478. # plot.main(args)
  3479. # LAEGEREN
  3480. args = {
  3481. 'brdf' : True,
  3482. 'angles' : 'angles.rpv.2.dat',
  3483. 'wbfile' : 'wb.MSI.dat',
  3484. 'root' : 'rpv.laegeren/result.laegeren.obj.lai.1',
  3485. 'bands' : (4, 7),
  3486. 'v' : True
  3487. }
  3488. # plot.main(args)
  3489. # RAMI
  3490. args = {
  3491. 'brdf' : True,
  3492. 'wbfile' : 'wb.full_spectrum.1nm.dat',
  3493. 'angles' : 'angle.rpv.cosDOM.dat',
  3494. 'root' : 'dart.rpv.rami/result.HET01_DIS_UNI_NIR_20.obj',
  3495. 'bands' : (250, 450),
  3496. 'v' : True
  3497. }
  3498. # plot.main(args)
  3499. # RAMI
  3500. args = {
  3501. 'three' : True,
  3502. 'v' : True,
  3503. 'plot' : True,
  3504. 'dataf' : 'rpv.rami.2/result.HET01_DIS_UNI_NIR_20.obj.brdf.dat',
  3505. 'paramfile' : 'rpv.rami.2/result.HET01_DIS_UNI_NIR_20.obj.brdf.dat.3params.dat',
  3506. 'plotfile' : 'rpv.rami.2/result.HET01_DIS_UNI_NIR_20.obj.brdf.3params',
  3507. }
  3508. # rpv_invert.main(args)
  3509. # LAEGEREN
  3510. args = {
  3511. 'three' : True,
  3512. 'v' : True,
  3513. 'plot' : True,
  3514. 'dataf' : 'rpv.laegeren/result.laegeren.obj.lai.1.brdf.dat',
  3515. 'paramfile' : 'rpv.laegeren/result.laegeren.obj.lai.1.brdf.dat.3params.dat',
  3516. 'plotfile' : 'rpv.laegeren/result.laegeren.obj.lai.1.brdf.3params'
  3517. }
  3518. # rpv_invert.main(args)
  3519. args = {
  3520. 'three' : True,
  3521. 'v' : True,
  3522. 'plot' : True,
  3523. 'dataf' : 'dart.rpv.rami/result.HET01_DIS_UNI_NIR_20.obj.brdf.dat',
  3524. 'paramfile' : 'dart.rpv.rami/result.HET01_DIS_UNI_NIR_20.obj.brdf.dat.3params.dat',
  3525. 'plotfile' : 'dart.rpv.rami/result.HET01_DIS_UNI_NIR_20.obj.brdf.3params',
  3526. }
  3527. # rpv_invert.main(args)
  3528. args = {
  3529. 'three': True,
  3530. 'v' : True,
  3531. 'plot' : True,
  3532. 'dataf' : 'dart.rpv.laegeren/result.laegeren.obj.lai.1.brdf.dat',
  3533. 'paramfile' : 'dart.rpv.laegeren/result.laegeren.obj.lai.1.brdf.dat.3params.dat',
  3534. 'plotfile' : 'dart.rpv.laegeren/result.laegeren.obj.lai.1.brdf.3params'
  3535. }
  3536. # rpv_invert.main(args)
  3537. args = {
  3538. 'v' : True,
  3539. 'opdir' : 'rami.TOA',
  3540. 'angles' : 'angles.MSI.dat',
  3541. 'wbfile' : 'wb.MSI.dat',
  3542. 'rpv' : 'rpv.rami.2/result.HET01_DIS_UNI_NIR_20.obj.brdf.dat.3params.dat' ,
  3543. 'plot' : 'rami.TOA/rpv.rami.libradtran.dat.all'
  3544. }
  3545. # dolibradtran.main(args)
  3546. args = {
  3547. 'v' : True,
  3548. 'opdir' : 'laegeren.TOA',
  3549. 'angles' : 'angles.MSI.dat',
  3550. 'wbfile' : 'wb.MSI.dat',
  3551. 'rpv' : 'rpv.laegeren/result.laegeren.obj.lai.1.brdf.dat.3params.dat',
  3552. 'plot' : 'laegeren.TOA/rpv.laegeren.libradtran.dat.all'
  3553. }
  3554. # dolibradtran.main(args)
  3555. args = {
  3556. 'v' : True,
  3557. 'angles' : 'angle.rpv.cosDOM.dat',
  3558. 'wbfile' : 'wb.full_spectrum.1nm.dat',
  3559. 'opdir' : 'dart.rami.TOA',
  3560. 'rpv' : 'dart.rpv.rami/result.HET01_DIS_UNI_NIR_20.obj.brdf.dat.3params.dat',
  3561. 'plot' : 'dart.rami.TOA/rpv.rami.libradtran.dat.all'
  3562. }
  3563. # dolibradtran.main(args)
  3564. args = {
  3565. 'v': True,
  3566. 'angles' : 'angle.rpv.cosDOM.dat',
  3567. 'wbfile' : 'wb.full_spectrum.1nm.dat',
  3568. 'opdir' : 'dart.laegeren.TOA',
  3569. 'rpv' : 'dart.rpv.laegeren/result.laegeren.obj.lai.1.brdf.dat.3params.dat',
  3570. 'plot' : 'dart.laegeren.TOA/rpv.laegeren.libradtran.dat.all'
  3571. }
  3572. # dolibradtran.main(args)
  3573. args = {
  3574. 'v' : True,
  3575. 'opdir' : 'rami.TOA',
  3576. 'rpv' : 'rpv.laegeren/result.laegeren.obj.lai.1.brdf.dat.3params.dat',
  3577. 'plot' : 'rami.TOA/rpv.rami.libradtran.dat.all',
  3578. 'lat' : 50,
  3579. 'lon' : 0,
  3580. 'time' : '2013 0601 12 00 00'
  3581. }
  3582. # dolibradtran.main(args)
  3583. args = {
  3584. 'v': True,
  3585. 'opdir' : 'laegeren.TOA.date',
  3586. 'rpv' : 'rpv.laegeren/result.laegeren.obj.lai.1.brdf.dat.3params.dat',
  3587. 'plot' : 'laegeren.TOA.date/rpv.laegeren.libradtran.dat.all',
  3588. 'lat' : 50,
  3589. 'lon' : 0,
  3590. 'time' : '2013 06 01 12 00 00'
  3591. }
  3592. # dolibradtran.main(args)
  3593. # DHP Simulation
  3594. args = {
  3595. 'v' : True,
  3596. 'nice' : 19,
  3597. 'obj' : 'laegeren.obj.lai.1',
  3598. 'hips' : True,
  3599. 'wb' : 'wb.image.dat',
  3600. 'dhp' : True,
  3601. 'samplingPattern' : 'circular',
  3602. 'lookFile' : 'dhp.locations.ondem.dat',
  3603. 'angles' : 'angles.dhp.dat',
  3604. 'fov' : False,
  3605. 'rpp' : 8,
  3606. 'npixels' : 4000000,
  3607. 'opdir' : 'DHP_TEST'
  3608. }
  3609. # dobrdf.main(args)
  3610. VLAB.logger.info('%s: Done...' % me)
  3611. def doProcessing(self, pm, args):
  3612. """do processing for LIBRAT processor"""
  3613. me=self.__class__.__name__ +'::'+VLAB.me()
  3614. VLAB.logger.info('%s: doProcessing()' % (me))
  3615. # defaults
  3616. q = {
  3617. 'angles' : 'angle.rpv.cosDOM.dat',
  3618. 'bands' : (250, 450),
  3619. 'boom' : 786000,
  3620. 'brdf' : True,
  3621. 'dataf' : 'dart.rpv.laegeren/result.laegeren.obj.lai.1.brdf.dat',
  3622. 'dhp' : True,
  3623. 'fov' : False,
  3624. 'hips' : False,
  3625. 'image' : True,
  3626. 'ideal' : (300., 300.),
  3627. 'lat' : 50,
  3628. 'lon' : 0,
  3629. 'look' : (150., 150., 710.),
  3630. 'lookFile' : 'dhp.locations.ondem.dat',
  3631. 'n' : 1000,
  3632. 'nice' : 19,
  3633. 'npixels' : 10000,
  3634. 'obj' : 'DEFAULT_OBJ',
  3635. 'opdir' : 'DEFAULT_DIR',
  3636. 'paramfile' : 'dart.rpv.rami/result.HET01_DIS_UNI_NIR_20.obj.brdf.dat.3params.dat',
  3637. 'plot' : 'dart.rami.TOA/rpv.rami.libradtran.dat.all',
  3638. 'plotfile' : 'rpv.rami.2/result.HET01_DIS_UNI_NIR_20.obj.brdf.3params',
  3639. 'plot' : 'rami.TOA/rpv.rami.libradtran.dat.all',
  3640. 'random' : True,
  3641. 'root' : 'rpv.rami/result.HET01_DIS_UNI_NIR_20.obj',
  3642. 'rpp' : 1,
  3643. 'rpv' : 'dart.rpv.rami/result.HET01_DIS_UNI_NIR_20.obj.brdf.dat.3params.dat',
  3644. 'rpv' : 'rpv.rami.2/result.HET01_DIS_UNI_NIR_20.obj.brdf.dat.3params.dat' ,
  3645. 'samplingPattern' : 'circular',
  3646. 'three' : True,
  3647. 'time' : '2013 06 01 12 00 00',
  3648. 'v' : True,
  3649. 'wbfile' : 'wb.full_spectrum.1nm.dat',
  3650. 'wb' : 'wb.full_spectrum.1nm.dat'
  3651. }
  3652. VLAB.logger.info('%s: overwriting defaults' % (me))
  3653. # overwrite defaults
  3654. for a in args:
  3655. if a == 'Sensor':
  3656. q['sensor'] = args[a]
  3657. if args[a] == VLAB.K_SENTINEL2:
  3658. q['wb'] = 'wb.MSI.dat'
  3659. q['wbfile'] = 'wb.MSI.dat'
  3660. q['angfile'] = 'angles.MSI.dat'
  3661. elif args[a] == VLAB.K_SENTINEL3:
  3662. q['wb'] = 'wb.OLCI.dat'
  3663. q['wbfile'] = 'wb.OLCI.dat'
  3664. q['angfile'] = 'angles.OLCI.dat'
  3665. elif args[a] == VLAB.K_MODIS:
  3666. q['wb'] = 'wb.MODIS.dat'
  3667. q['wbfile'] = 'wb.MODIS.dat'
  3668. q['angfile'] = 'angles.MODIS.dat'
  3669. elif args[a] == VLAB.K_MERIS:
  3670. q['wb'] = 'wb.MERIS.dat'
  3671. q['wbfile'] = 'wb.MERIS.dat'
  3672. q['angfile'] = 'angles.MERIS.dat'
  3673. elif args[a] == VLAB.K_LANDSAT_OLI:
  3674. q['wb'] = 'wb.LANDSAT.OLI.dat'
  3675. q['wbfile'] = 'wb.LANDSAT.OLI.dat'
  3676. q['angfile'] = 'angles.LANDSAT.dat'
  3677. elif args[a] == VLAB.K_LANDSAT_ETM:
  3678. q['wb'] = 'wb.LANDSAT.ETM.dat'
  3679. q['wbfile'] = 'wb.LANDSAT.ETM.dat'
  3680. q['angfile'] = 'angles.LANDSAT.dat'
  3681. else:
  3682. q['wb'] = 'wb.full_spectrum.1nm.dat'
  3683. q['wbfile'] = 'wb.full_spectrum.1nm.dat'
  3684. q['angfile'] = 'angles.rami.dat'
  3685. elif a == 'OutputDirectory':
  3686. q['opdir'] = args[a]
  3687. elif a == '3dScene':
  3688. if args[a] == VLAB.K_RAMI:
  3689. q['obj'] = 'HET01_DIS_UNI_NIR_20.obj'
  3690. q['lat'] = 0
  3691. q['lon'] = 0
  3692. elif args[a] == VLAB.K_LAEGERN:
  3693. q['obj'] = 'laegeren.obj'
  3694. q['lat'] = '47.4817'
  3695. q['lon'] = '-8.3947'
  3696. elif args[a] == VLAB.K_THARANDT:
  3697. q['obj'] = 'HET01_DIS_UNI_NIR_20.obj' # FIXME: define when file is available
  3698. q['lat'] = '50.9833'
  3699. q['lon'] = '-13.5808'
  3700. elif args[a] == VLAB.K_USER_DEFINED:
  3701. q['obj'] = 'UserDefined.obj'
  3702. # What about q['lat'] and q['lon']?
  3703. elif a == 'Bands':
  3704. q['bands'] = [int(i) for i in tuple(args[a].split(", "))]
  3705. elif a == 'DHP_ImageFile':
  3706. q['dhp'] = args[a] == 'Yes'
  3707. elif a == 'ImageFile':
  3708. q['image'] = args[a] == 'Yes'
  3709. elif a == 'AsciiFile':
  3710. q['ascii'] = args[a] == 'Yes'
  3711. elif a == 'ViewingAzimuth':
  3712. q['va'] = args[a]
  3713. elif a == 'ViewingZenith':
  3714. q['vz'] = args[a]
  3715. elif a == 'DHP_Zenith':
  3716. q['dhp_vz'] = args[a]
  3717. elif a == 'DHP_Azimuth':
  3718. q['dhp_va'] = args[a]
  3719. elif a == 'IlluminationAzimuth':
  3720. q['sz'] = args[a]
  3721. elif a == 'IlluminationZenith':
  3722. q['sa'] = args[a]
  3723. else:
  3724. q[a] = args[a]
  3725. q['dataf'] = '%s/result.%s.brdf.dat' %(q['opdir'], q['obj'])
  3726. q['paramfile'] = '%s/result.%s.brdf.dat.3params.dat' %(q['opdir'], q['obj'])
  3727. q['plot'] = '%s/rpv.%s.dat.all' %(q['opdir'],q['obj'])
  3728. q['plotfile'] = '%s/result.%s.brdf.3params' %(q['opdir'],q['obj'])
  3729. q['root'] = '%s/result.%s' %(q['opdir'],q['obj'])
  3730. q['rpv'] = '%s/result.%s.brdf.dat.3params.dat' %(q['opdir'],q['obj'])
  3731. if 'dhp' in q:
  3732. q['vz'] = q['dhp_vz']
  3733. q['va'] = q['dhp_va']
  3734. for a in ['dataf', 'paramfile','plot','plotfile','root', 'rpv']:
  3735. VLAB.logger.info ('%s: q["%s"] is %s' % (me, a, q[a]))
  3736. if VLAB.osName().startswith('Windows'):
  3737. fullobjpath = '%s/%s' % (VLAB.expandEnv('%HOMEDRIVE%%HOMEPATH%/.beam/beam-vlab/auxdata/librat_scenes'), args['OutputDirectory'])
  3738. else:
  3739. fullobjpath = '%s/%s' % (VLAB.expandEnv('$HOME/.beam/beam-vlab/auxdata/librat_scenes'), args['OutputDirectory'])
  3740. VLAB.logger.info ('%s: ensuring "%s" exists' %(me, fullobjpath))
  3741. if not VLAB.path.exists(fullobjpath):
  3742. VLAB.mkDirPath(fullobjpath)
  3743. VLAB.logger.info('%s: instantiating objects' % (me))
  3744. drivers = Librat_drivers()
  3745. dobrdf = Librat_dobrdf()
  3746. plot = Librat_plot()
  3747. rpv_invert = Librat_rpv_invert()
  3748. dolibradtran = Librat_dolibradtran()
  3749. if (pm != None):
  3750. pm.beginTask("Computing BRF...", 10)
  3751. # ensure at least 1 second to ensure progress popup feedback
  3752. time.sleep(1)
  3753. # not needed because we are using the dart angles
  3754. # drivers.main()
  3755. VLAB.logger.info('%s: calling dobrdf.main()' % (me))
  3756. dobrdf.main(q)
  3757. VLAB.logger.info('%s: calling plot.main()' % (me))
  3758. plot.main(q)
  3759. VLAB.logger.info('%s: calling rpv.main()' % (me))
  3760. rpv_invert.main(q)
  3761. VLAB.logger.info('%s: calling dolibradtran.main()' % (me))
  3762. dolibradtran.main(q)
  3763. VLAB.logger.info('%s: Done...' % me)
  3764. #### LIBRAT end ##############################################################
  3765. #### MAIN DISPATCH ####################################################
  3766. if not sys.platform.startswith('java'):
  3767. VLAB.logger.info('%s: Mode: not jython and not BEAM' % VLAB.me)
  3768. vlab = VLAB()
  3769. vlab.selftests()
  3770. else:
  3771. from java.lang import System
  3772. beamVer = System.getProperty('beam.version')
  3773. if beamVer == None:
  3774. if System.getProperty('vlab.fakebeam') != None:
  3775. VLAB.logger.info('%s: Mode: jython and fake BEAM' % VLAB.me)
  3776. vlab = VLAB()
  3777. vlab.fakebeam()
  3778. else:
  3779. VLAB.logger.info('%s: Mode: jython and not BEAM' % VLAB.me)
  3780. vlab = VLAB()
  3781. vlab.selftests()
  3782. else:
  3783. VLAB.logger.info('%s: Mode: jython and BEAM v%s' % (VLAB.me, beamVer))
  3784. ### BEAM-only code ####################################################
  3785. #
  3786. # BEAM-specific code from here to end of file...
  3787. #
  3788. from java import awt
  3789. from java import io
  3790. from java import lang
  3791. from java.io import BufferedReader
  3792. from java.io import BufferedWriter
  3793. from java.io import File
  3794. from java.io import FileInputStream
  3795. from java.io import FileOutputStream
  3796. from java.io import FileReader
  3797. from java.io import FileWriter
  3798. from java.io import InputStreamReader
  3799. from java.io import IOException
  3800. from java.io import OutputStreamWriter
  3801. from java.lang import IllegalArgumentException
  3802. from java.lang import Integer
  3803. from java.lang import ProcessBuilder
  3804. from java.lang import System
  3805. from java.lang import Thread
  3806. from java.util import ArrayList
  3807. from java.util import Arrays
  3808. from java.util import HashMap
  3809. from java.util import Map
  3810. from java.util import Vector
  3811. from javax import swing
  3812. from com.bc.ceres.core import ProgressMonitor
  3813. from com.netcetera.vlab import IVLabProcessor
  3814. from com.netcetera.vlab import IVLabProcessorUi
  3815. from com.netcetera.vlab import VLabProcessor
  3816. from com.netcetera.vlab import VLabUi
  3817. from org.esa.beam.dataio.dimap import DimapProductConstants;
  3818. from org.esa.beam.framework.dataio import ProductSubsetDef
  3819. from org.esa.beam.framework.dataio import ProductWriter
  3820. from org.esa.beam.framework.datamodel import PixelPos
  3821. from org.esa.beam.framework.datamodel import Product
  3822. from org.esa.beam.framework.datamodel import RasterDataNode
  3823. from org.esa.beam.framework.dataop.dem import ElevationModelDescriptor
  3824. from org.esa.beam.framework.dataop.dem import ElevationModelRegistry
  3825. from org.esa.beam.framework.dataop.maptransf import MapInfo
  3826. from org.esa.beam.framework.dataop.resamp import ResamplingFactory
  3827. from org.esa.beam.framework.param import Parameter
  3828. from org.esa.beam.framework.param import ParamProperties
  3829. from org.esa.beam.framework.param import ParamValidateException
  3830. from org.esa.beam.framework.param.validators import NumberValidator
  3831. from org.esa.beam.framework.processor import DefaultRequestElementFactory
  3832. from org.esa.beam.framework.processor import Processor
  3833. from org.esa.beam.framework.processor import ProcessorConstants
  3834. from org.esa.beam.framework.processor import ProcessorException
  3835. from org.esa.beam.framework.processor import ProcessorUtils
  3836. from org.esa.beam.framework.processor import ProductRef
  3837. from org.esa.beam.framework.processor import Request
  3838. from org.esa.beam.framework.processor import RequestElementFactory
  3839. from org.esa.beam.framework.processor import RequestElementFactoryException
  3840. from org.esa.beam.framework.processor.ui import ProcessorUI
  3841. from org.esa.beam.framework.ui import GridBagUtils
  3842. from org.esa.beam.framework.ui import UIUtils
  3843. from org.esa.beam.util import Guardian
  3844. ##
  3845. ## BEAM-defined Processor implementation
  3846. ##
  3847. class VLabImpl(IVLabProcessor):
  3848. """Implements the BEAM Processor interface"""
  3849. def __init__(self):
  3850. me=self.__class__.__name__ +'::'+VLAB.me()
  3851. VLAB.logger.info('%s: constructor completed...' % me)
  3852. def getName(self):
  3853. return VLAB.PROCESSOR_NAME
  3854. def getSymbolicName(self):
  3855. return VLAB.PROCESSOR_SNAME
  3856. def getVersion(self):
  3857. return VLAB.VERSION_STRING
  3858. def getCopyrightInformation(self):
  3859. return VLAB.COPYRIGHT_INFO
  3860. def getUITitle(self):
  3861. return VLAB.UI_TITLE
  3862. def _getP(self, r, k):
  3863. me=self.__class__.__name__ +'::'+VLAB.me()
  3864. return r.getParameter(k).getValueAsText()
  3865. def process(self, pm, req):
  3866. VLAB.logger.info('inside process...')
  3867. me=self.__class__.__name__ +'::'+VLAB.me()
  3868. ProcessorUtils.setProcessorLoggingHandler(VLAB.DEFAULT_LOG_PREFIX,
  3869. req, self.getName(), self.getVersion(), self.getCopyrightInformation())
  3870. #VLAB.log("Parameter list:")
  3871. #for i in range(req.getNumParameters()):
  3872. # VLAB.log(req.getParameterAt(i).getName() + " = " + req.getParameterAt(i).getValueAsText())
  3873. VLAB.logger.info('%s: %s' % (me, ProcessorConstants.LOG_MSG_START_REQUEST))
  3874. pm.beginTask('Running %s...' % VLAB.PROCESSOR_NAME, 10)
  3875. VLAB.logger.info('%s: after pm.beginTask' % me)
  3876. # ensure at least 1 second to ensure progress popup feedback
  3877. time.sleep(1)
  3878. VLAB.logger.info('%s: after sleep' % me)
  3879. processor = self._getP(req, VLAB.P_RTProcessor)
  3880. VLAB.logger.info('%s: processor is <%s>' % (me, processor))
  3881. if processor == VLAB.K_DART:
  3882. rtProcessor = DART()
  3883. elif processor == VLAB.K_LIBRAT:
  3884. rtProcessor = LIBRAT()
  3885. elif processor == VLAB.K_DUMMY:
  3886. rtProcessor = DUMMY()
  3887. else:
  3888. raise RuntimeError('unknown processor: <%s>' % processor)
  3889. pm.beginTask("Computing top of canopy BRF...", 10)
  3890. params = {}
  3891. for i in VLAB.plst:
  3892. val = self._getP(req, i)
  3893. VLAB.logger.info('%s: val for %s is %s' % (me, i, val))
  3894. params[i] = val
  3895. VLAB.logger.info('%s: calling doProcessing' % me)
  3896. rtProcessor.doProcessing(pm, params)
  3897. VLAB.logger.info('%s : %s' % (me, ProcessorConstants.LOG_MSG_FINISHED_REQUEST))
  3898. pm.done()
  3899. ##
  3900. ## BEAM-defined UI Implementation
  3901. ##
  3902. class VLabUiImpl(IVLabProcessorUi):
  3903. """Implements the BEAM ProcessorUI interface"""
  3904. def __init__(self):
  3905. self._reqElemFac = VLabRequestElementFactory()
  3906. self._defaultFactory = DefaultRequestElementFactory.getInstance()
  3907. self._requestFile = File('')
  3908. self.pmap = {}
  3909. me=self.__class__.__name__ +'::'+VLAB.me()
  3910. VLAB.logger.info('%s: constructor completed...' % me)
  3911. def getGuiComponent(self):
  3912. self._paramOutputProduct = self._reqElemFac.createDefaultOutputProductParameter()
  3913. v = 2; h = 2;
  3914. guiComponent = swing.JPanel(awt.BorderLayout())
  3915. tabbedPane = swing.JTabbedPane()
  3916. for tabGroups in VLAB.model:
  3917. for tabName in tabGroups:
  3918. tab = swing.JPanel()
  3919. tab.layout = swing.BoxLayout(tab, swing.BoxLayout.PAGE_AXIS)
  3920. tabbedPane.addTab(tabName, tab)
  3921. for group in tabGroups[tabName]:
  3922. tab.add(swing.JLabel(''))
  3923. p = swing.JPanel()
  3924. p.layout = awt.GridLayout(0, 4)
  3925. p.layout.vgap = v; p.layout.hgap = h
  3926. for groupName in group:
  3927. p.border = swing.BorderFactory.createTitledBorder(groupName)
  3928. for groupTuple in group[groupName]:
  3929. if len(groupTuple) == 4:
  3930. (lbl, nm, typ, vals) = groupTuple
  3931. if type(vals) == tuple:
  3932. dflt = vals[0]
  3933. else:
  3934. dflt = vals
  3935. props = self._defaultFactory.createStringParamProperties()
  3936. props.setLabel(lbl)
  3937. props.setDefaultValue(dflt)
  3938. self._reqElemFac.pMap[nm] = props
  3939. if type(vals) == tuple:
  3940. self.pmap[nm] = Parameter(nm, dflt)
  3941. (self.pmap[nm]).getProperties().setValueSet(vals)
  3942. (self.pmap[nm]).getProperties().setValueSetBound(True)
  3943. (self.pmap[nm]).getProperties().setDefaultValue(dflt)
  3944. (self.pmap[nm]).getProperties().setLabel(lbl)
  3945. else:
  3946. self.pmap[nm] = self._reqElemFac.createParameter(nm, dflt)
  3947. if type(typ) == tuple:
  3948. self.pmap[nm].getEditor().setEnabled(typ[1])
  3949. #p.add((self.pmap[nm]).getEditor().getLabelComponent())
  3950. p.add(swing.JLabel(lbl+':', swing.SwingConstants.RIGHT))
  3951. p.add((self.pmap[nm]).getEditor().getComponent())
  3952. else:
  3953. p.add(swing.JLabel(''))
  3954. p.add(swing.JLabel(''))
  3955. tab.add(p)
  3956. # hack
  3957. for i in range(50):
  3958. tab.add(swing.Box.createVerticalGlue())
  3959. guiComponent.add(tabbedPane, awt.BorderLayout.NORTH)
  3960. guiComponent.add(swing.JLabel(''), awt.BorderLayout.CENTER)
  3961. VLabUi.setWindowSize(800, 800)
  3962. return guiComponent
  3963. def setRequests(self, requests):
  3964. if (not requests.isEmpty()):
  3965. for i in range(requests.size()):
  3966. request = requests.elementAt(i)
  3967. if (request == None):
  3968. continue;
  3969. if (str(VLAB.REQUEST_TYPE) == request.getType()):
  3970. self._requestFile = request.getFile()
  3971. outputProductAt = request.getOutputProductAt(0)
  3972. if (outputProductAt != None):
  3973. self._paramOutputProduct.setValueAsText(outputProductAt.getFilePath(), None)
  3974. # update parameters
  3975. for nm in VLAB.plst:
  3976. (self.pmap[nm]).setValue(request.getParameter(nm).getValue())
  3977. # prefixParam = request.getParameter(ProcessorConstants.LOG_PREFIX_PARAM_NAME)
  3978. # if (prefixParam != None):
  3979. # self._logPrefixParameter.setValue(prefixParam.getValue(), None)
  3980. # logOutputParam = request.getParameter(ProcessorConstants.LOG_TO_OUTPUT_PARAM_NAME)
  3981. # if (logOutputParam != None):
  3982. # self._logToOutputParameter.setValue(logOutputParam.getValue(), None)
  3983. break;
  3984. else:
  3985. self.setDefaultRequests()
  3986. def setDefaultRequests(self):
  3987. self.setDefaultRequest()
  3988. def getRequests(self):
  3989. requests = Vector()
  3990. request = Request()
  3991. request.setFile(self._requestFile)
  3992. request.setType(VLAB.REQUEST_TYPE)
  3993. outputFile = self._paramOutputProduct.getValueAsText()
  3994. request.addOutputProduct(ProcessorUtils.createProductRef(outputFile, DimapProductConstants.DIMAP_FORMAT_NAME));
  3995. for nm in VLAB.plst:
  3996. request.addParameter(self._reqElemFac.createParameter(nm, (self.pmap[nm]).getValueAsText()))
  3997. requests.add(request)
  3998. return requests
  3999. def setDefaultRequest(self):
  4000. self._requestFile = None
  4001. outputProductFile = self._paramOutputProduct.getValue()
  4002. if (outputProductFile != None and outputProductFile.getParentFile() != None):
  4003. parentFile = outputProductFile.getParentFile()
  4004. self._paramOutputProduct.setValue(File(parentFile, VLAB.D_PRODNAME), None)
  4005. else:
  4006. self._paramOutputProduct.setDefaultValue()
  4007. (self.pmap[VLAB.P_3dScene]).setDefaultValue()
  4008. ##
  4009. ## BEAM-defined mangement of processing parameters (aka request element)
  4010. ##
  4011. class VLabRequestElementFactory(RequestElementFactory):
  4012. """Implements the BEAM RequestElementFactory interface"""
  4013. def __init__(self):
  4014. self._defaultFactory = DefaultRequestElementFactory.getInstance()
  4015. self.pMap = {}
  4016. me=self.__class__.__name__ +'::'+VLAB.me()
  4017. VLAB.logger.info('%s : constructor completed...' % me)
  4018. def getInstance(self):
  4019. return VLabRequestElementFactory()
  4020. def createParameter(self, name, value):
  4021. Guardian.assertNotNullOrEmpty("name", name)
  4022. try:
  4023. param = self.createParamWithDefaultValueSet(name)
  4024. if (value != None):
  4025. param.setValueAsText(value, None)
  4026. except IllegalArgumentException, e:
  4027. VLAB.logger.info(e.getMessage)
  4028. raise RequestElementFactoryException(e.getMessage())
  4029. return param
  4030. def createDefaultInputProductParameter(self):
  4031. return self._defaultFactory.createDefaultInputProductParameter()
  4032. def createDefaultLogPatternParameter(self, prefix):
  4033. return self._defaultFactory.createDefaultLogPatternParameter(prefix)
  4034. def createDefaultOutputProductParameter(self):
  4035. defaultOutputProductParameter = self._defaultFactory.createDefaultOutputProductParameter()
  4036. properties = defaultOutputProductParameter.getProperties()
  4037. defaultValue = properties.getDefaultValue()
  4038. if (isinstance(defaultValue, File)):
  4039. properties.setDefaultValue(File(defaultValue, VLAB.D_PRODNAME))
  4040. defaultOutputProductParameter.setDefaultValue()
  4041. return defaultOutputProductParameter
  4042. def createInputProductRef(self, fileN, fileFmt, typeId):
  4043. try:
  4044. return self._defaultFactory.createInputProductRef(fileN, fileFmt, typeId)
  4045. except RequestElementFactoryException, e:
  4046. raise RequestElementFactoryException(e.getMessage())
  4047. def createLogToOutputParameter(self, value):
  4048. try:
  4049. return self._defaultFactory.createLogToOutputParameter(value)
  4050. except ParamValidateException, e:
  4051. raise ParamValidateException(e.getMessage())
  4052. def createOutputProductRef(self, fileN, fileFmt, typeId):
  4053. try:
  4054. return self._defaultFactory.createOutputProductRef(fileN, fileFmt, typeId)
  4055. except RequestElementFactoryException, e:
  4056. raise RequestElementFactoryException(e.getMessage())
  4057. def createParamWithDefaultValueSet(self, paramName):
  4058. paramProps = self.getParamInfo(paramName)
  4059. param = Parameter(paramName, paramProps.createCopy())
  4060. param.setDefaultValue()
  4061. return param
  4062. def getParamInfo(self, parameterName):
  4063. paramProps = self.pMap[parameterName]
  4064. if (paramProps == None):
  4065. if (parameterName.endsWith(VLAB.P_EXPRESSION)):
  4066. VLAB.lof('to be implemented!!!')
  4067. elif (parameterName.endsWith(VLAB.P_CONDITION)):
  4068. VLAB.lof('to be implemented!!!')
  4069. elif (parameterName.endsWith(VLAB.P_OUTPUT)):
  4070. VLAB.lof('to be implemented!!!')
  4071. if (paramProps == None):
  4072. raise IllegalArgumentException("Invalid parameter name '" + parameterName + "'.")
  4073. return paramProps
  4074. def createStringParamProperties(self):
  4075. return self._defaultFactory.createStringParamProperties()