PageRenderTime 65ms CodeModel.GetById 23ms RepoModel.GetById 1ms app.codeStats 0ms

/beam-3dveglab-vlab/src/main/scenes/librat_scenes/librat.py

https://github.com/anarisris/esa-beam
Python | 2520 lines | 2453 code | 24 blank | 43 comment | 23 complexity | 1b211bf0312cb1ecbdfd99440f3a3f04 MD5 | raw file

Large files files are truncated, but you can click here to view the full 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. ##############################################################################
  19. # Two ways to run it:
  20. #
  21. # 1. standalone tests - headless (either jython or python)
  22. #
  23. # jython -Dpython.path=jcommon-1.0.16.jar:jfreechart-1.0.13.jar librat.py
  24. # python librat.py
  25. #
  26. # 2. standalone with a 'fake' swing-based gui
  27. #
  28. # jython -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 librat.py
  29. #
  30. # Those BEAM-supplied jars can also be obtained like this:
  31. # wget -U "Mozilla/5.0" http://repo1.maven.org/maven2/jfree/jfreechart/1.0.13/jfreechart-1.0.13.jar
  32. # wget -U "Mozilla/5.0" http://repo1.maven.org/maven2/jfree/jcommon/1.0.16/jcommon-1.0.16.jar
  33. #
  34. #
  35. import sys, math, operator, array, time, struct
  36. from array import array
  37. class VLAB:
  38. """VLAB contains conf. constants, static utility methods, and test methods"""
  39. COPYRIGHT_INFO = 'Copyright (C) 2010-2014 Netcetera Switzerland (info@netcetera.com)'
  40. PROCESSOR_NAME = 'BEAM VLab Processor'
  41. PROCESSOR_SNAME = 'beam-vlab'
  42. REQUEST_TYPE = 'VLAB'
  43. UI_TITLE = 'VLab - Processor'
  44. VERSION_STRING = '1.0 (29 Oct 2013)'
  45. DEFAULT_LOG_PREFIX = 'vlab'
  46. LOGGER_NAME = 'beam.processor.vlab'
  47. D_PRODNAME = 'vlab_out.dim'
  48. P_CONDITION = '.condition'
  49. P_EXPRESSION = '.expression'
  50. P_OUTPUT = '.output'
  51. JCB = 'JComboBox'
  52. JTF = 'JTextField'
  53. K_LIBRAT = 'librat'
  54. K_DART = 'dart'
  55. K_DUMMY = 'dummy'
  56. K_LAEGEREN = 'Laegeren'
  57. K_RAMI = 'Default RAMI'
  58. K_YES = 'Yes'
  59. K_NO = 'No'
  60. K_SENTINEL2 = 'MSI (Sentinel 2)'
  61. K_SENTINEL3 = 'OLCI (Sentinel 3)'
  62. K_MODIS = 'MODIS'
  63. K_MERIS = 'MERIS'
  64. K_LANDSAT = 'Landsat'
  65. K_RURAL = 'Rural'
  66. K_MARITIME = 'Maritime'
  67. K_URBAN = 'Urban'
  68. K_TROPOSPHERIC = 'Tropospheric'
  69. DBG = 'debug'
  70. INF = 'info'
  71. ERR = 'error'
  72. plst = []
  73. if sys.platform.startswith('java'):
  74. from java.util.logging import Logger
  75. logger = Logger.getLogger(LOGGER_NAME)
  76. else:
  77. import logging
  78. logger = logging.getLogger(LOGGER_NAME)
  79. logger.setLevel(logging.DEBUG)
  80. logch = logging.StreamHandler()
  81. logch.setLevel(logging.DEBUG)
  82. logger.addHandler(logch)
  83. #logfh = logging.FileHandler('%s.log' % LOGGER_NAME)
  84. #logfh.setLevel(logging.DEBUG)
  85. #logger.addHander(logfh)
  86. model = (
  87. {'Forward Modeling': (
  88. {'Model Selection': (
  89. ('3D Scene', '3dScene', JCB, (K_RAMI, K_LAEGEREN)),
  90. ('RT Processor', 'RTProcessor', JCB, (K_DUMMY, K_LIBRAT, K_DART)))},
  91. {'Spectral Characteristics': (
  92. ('Sensor', 'Sensor', JCB, (K_SENTINEL2, K_SENTINEL3, K_MODIS, K_MERIS, K_LANDSAT)),
  93. ('Bands', 'Bands', JTF, '1, 2, 3, 4, 5, 6, 7, 8, 9, 10'))},
  94. {'Viewing Characteristics': (
  95. ('Zenith', 'ViewingZenith', JTF, '20.0'),
  96. ('Azimuth', 'ViewingAzimuth', JTF, '0.0'))},
  97. {'Illumination Characteristics':(
  98. ('Zenith', 'IlluminationZenith', JTF, '20.0'),
  99. ('Azimuth', 'IlluminationAzimuth', JTF, '0.0'))},
  100. {'Scene Parameters': (
  101. ('Pixel Size', 'ScenePixel', JTF, '8'),
  102. ('(Alt A) Filename', 'SceneLocFile', JTF, ''),
  103. ('(Alt B) XC', 'SceneXC', JTF, '-50'),
  104. ('(Alt B) XW', 'SceneXW', JTF, '50'),
  105. ('(Alt B) YC', 'SceneYC', JTF, '100'),
  106. ('(Alt B) YW', 'SceneYW', JTF, '100'))},
  107. {'Atmospheric Parameters': (
  108. ('Day of Year', 'AtmosphereDay', JTF, '214'),
  109. (),
  110. ('Lat', 'AtmosphereLat', JTF, '47.4781'),
  111. ('Long', 'AtmosphereLong', JTF, '8.3650'),
  112. ('CO2 Mixing Ratio', 'AtmosphereCO2', JTF, '1.6'),
  113. ('Aerosol Profile', 'AtmosphereAerosol', JCB, (K_RURAL, K_MARITIME, K_URBAN, K_TROPOSPHERIC)),
  114. ('Water Vapor', 'AtmosphereWater', JTF, '0.0'),
  115. ('Ozone Column', 'AtmosphereOzone', JTF, '300'))},
  116. {'Output Parameters': (
  117. ('Result file prefix','OutputPrefix', JTF, 'RAMI_'),
  118. ('Result Directory', 'OutputDirectory', JTF, ''),
  119. ('Image file', 'ImageFile', JCB, (K_YES, K_NO)),
  120. ('Ascii file', 'AsciiFile', JCB, (K_YES, K_NO)))}
  121. )},
  122. {'DHP Simulation': (
  123. {'Model Selection': (
  124. ('3D Scene', 'DHP_3dScene', JCB, (K_RAMI, K_LAEGEREN)),
  125. (),
  126. ('RT Processor', 'DHP_RTProcessor', JCB, (K_LIBRAT, K_DART, K_DUMMY)),
  127. (),
  128. ('Resolution', 'DHP_Resolution', JTF, '100x100'),
  129. ())},
  130. {'DHP Location': (
  131. ('X', 'DHP_X', JTF, '0'),
  132. ('Y', 'DHP_Y', JTF, '0'))},
  133. {'DHP Properties': (
  134. ('Zenith', 'DHP_Zenith', JTF, '20.0'),
  135. ('Azimuth', 'DHP_Azimuth', JTF, '0.0'))},
  136. {'DHP Imaging Plane': (
  137. ('Orientation', 'DHP_Orientation', JTF, '0'),
  138. ('Height(z)', 'DHP_Height', JTF, '0'))},
  139. {'Output Parameters': (
  140. ('Result file prefix','DHP_OutputPrefix', JTF, 'RAMI00_'),
  141. ('Result Directory', 'DHP_OutputDirectory', JTF, ''),
  142. ('Image file', 'DHP_ImageFile', JCB, (K_YES, K_NO)),
  143. ('Ascii file', 'DHP_AsciiFile', JCB, (K_YES, K_NO)))}
  144. )},
  145. )
  146. # set parameter names
  147. for tabGroups in model:
  148. for tabName in tabGroups:
  149. for group in tabGroups[tabName]:
  150. for groupName in group:
  151. for groupTuple in group[groupName]:
  152. if len(groupTuple) == 4:
  153. (lbl, nm, typ, vals) = groupTuple
  154. exec('P_' + nm + ' = nm')
  155. exec('L_' + nm + ' = lbl')
  156. plst.append(nm)
  157. def __init__(self):
  158. self.cmap = {}
  159. self.vmap = {}
  160. def me():
  161. """Returns name of currently executing method"""
  162. nm = ''
  163. try:
  164. raise ZeroDivisionError
  165. except ZeroDivisionError:
  166. nm = sys.exc_info()[2].tb_frame.f_back.f_code.co_name
  167. return nm+'()'
  168. me = staticmethod(me)
  169. def listdir(path):
  170. """list files in the directory given by path"""
  171. if sys.platform.startswith('java'):
  172. from java.io import File
  173. return File(path).list()
  174. else:
  175. import os
  176. return os.listdir(path)
  177. listdir = staticmethod(listdir)
  178. def getenv(key, default=None):
  179. if sys.platform.startswith('java'):
  180. from java.lang.System import getenv
  181. return getenv(key)
  182. else:
  183. import os
  184. return os.getenv(key)
  185. getenv = staticmethod(getenv)
  186. def checkFile(fname):
  187. """open a file if it exists, otherwise die"""
  188. try:
  189. fp = open(fname, 'rw')
  190. return fp
  191. except IOError, e:
  192. raise RuntimeError(e)
  193. checkFile = staticmethod(checkFile)
  194. def fileExists(fname):
  195. """check if fname exists as a file"""
  196. if sys.platform.startswith('java'):
  197. from java.io import File
  198. return File(fname).exists()
  199. else:
  200. import os
  201. return os.path.exists(fname)
  202. fileExists = staticmethod(fileExists)
  203. def getFullPath(fname):
  204. """return canonical/absolute path of given fname"""
  205. if sys.platform.startswith('java'):
  206. from java.io import File
  207. return File(fname).getCanonicalPath()
  208. else:
  209. import os
  210. return os.path.abspath(fname)
  211. getFullPath = staticmethod(getFullPath)
  212. class path:
  213. def exists(path):
  214. if sys.platform.startswith('java'):
  215. from java.io import File
  216. return File(path).exists()
  217. else:
  218. import os
  219. return os.path.exists(path)
  220. exists = staticmethod(exists)
  221. def isabs(path):
  222. if sys.platform.startswith('java'):
  223. from java.io import File
  224. return File(path).isAbsolute()
  225. else:
  226. import os
  227. return os.path.isabs(path)
  228. isabs = staticmethod(isabs)
  229. def isdir(path):
  230. if sys.platform.startswith('java'):
  231. from java.io import File
  232. return File(path).isDirectory()
  233. else:
  234. import os
  235. return os.path.isdir(path)
  236. isdir = staticmethod(isdir)
  237. def join(path, *args):
  238. if sys.platform.startswith('java'):
  239. from java.io import File
  240. f = File(path)
  241. for a in args:
  242. g = File(a)
  243. if g.isAbsolute() or len(f.getPath()) == 0:
  244. f = g
  245. else:
  246. f = File(f, a)
  247. return f.getPath()
  248. else:
  249. import os
  250. return os.path.join(path, *args)
  251. join = staticmethod(join)
  252. def isfile(path):
  253. if sys.platform.startswith('java'):
  254. from java.io import File
  255. return File(path).isfile()
  256. else:
  257. import os
  258. return os.path.isfile(path)
  259. isfile = staticmethod(isfile)
  260. def normcase(path):
  261. if sys.platform.startswith('java'):
  262. from java.io import File
  263. return File(path).getPath()
  264. else:
  265. import os
  266. return os.path.normcase(path)
  267. normcase = staticmethod(normcase)
  268. def normpath(path):
  269. if sys.platform.startswith('java'):
  270. from java.io import File
  271. return File(path).getCanonicalPath()
  272. else:
  273. import os
  274. return os.path.normpath(path)
  275. normpath = staticmethod(normpath)
  276. def split(path):
  277. if sys.platform.startswith('java'):
  278. from java.io import File
  279. f=File(path)
  280. d=f.getParent()
  281. if not d:
  282. if f.isAbsolute():
  283. d = path
  284. else:
  285. d = ""
  286. return (d, f.getName())
  287. else:
  288. import os
  289. return os.path.split(path)
  290. split = staticmethod(split)
  291. def frange(end, start=0, inc=0):
  292. """a jython-compatible range function with float increments"""
  293. import math
  294. if not start:
  295. start = end + 0.0
  296. end = 0.0
  297. else: end += 0.0
  298. if not inc:
  299. inc = 1.0
  300. count = int(math.ceil((start - end) / inc))
  301. L = [None] * count
  302. L[0] = end
  303. for i in (xrange(1,count)):
  304. L[i] = L[i-1] + inc
  305. return L
  306. frange = staticmethod(frange)
  307. def openFileIfNotExists(filename):
  308. """open file exclusively"""
  309. if sys.platform.startswith('java'):
  310. from java.io import File
  311. if File(filename).createNewFile():
  312. return open(filename)
  313. else:
  314. return None
  315. else:
  316. import os
  317. try:
  318. # os.O_EXCL => open exclusive => acquire a lock on the file
  319. fd = os.open(filename, os.O_CREAT|os.O_EXCL|os.O_WRONLY|os.O_TRUNC)
  320. except:
  321. return None
  322. fobj = os.fdopen(fd,'w')
  323. return fobj
  324. openFileIfNotExists = staticmethod(openFileIfNotExists)
  325. def rndInit(seed = None):
  326. """initialize the randon number generator"""
  327. if sys.platform.startswith('java'):
  328. from java.util import Random
  329. if seed == None:
  330. return Random()
  331. else:
  332. return Random(seed)
  333. else:
  334. import random
  335. random.seed(seed)
  336. return None
  337. rndInit = staticmethod(rndInit)
  338. def rndNextFloat(randState):
  339. """return the next pseudo-random floating point number in the sequence"""
  340. if sys.platform.startswith('java'):
  341. from java.util import Random
  342. return randState.nextFloat()
  343. else:
  344. import random
  345. return random.random()
  346. rndNextFloat = staticmethod(rndNextFloat)
  347. def r2d(v):
  348. """jython-compatible conversion of radians to degrees"""
  349. if sys.platform.startswith('java'):
  350. from java.lang import Math
  351. return Math.toDegrees(v)
  352. else:
  353. return math.degrees(v)
  354. r2d = staticmethod(r2d)
  355. def d2r(v):
  356. """jython-compatible conversion of degrees to radians"""
  357. if sys.platform.startswith('java'):
  358. from java.lang import Math
  359. return Math.toRadians(float(v))
  360. else:
  361. return math.radians(v)
  362. d2r = staticmethod(d2r)
  363. def mkDirPath(path):
  364. """create directory (including non-existing parents) for the given path"""
  365. if sys.platform.startswith('java'):
  366. from java.io import File
  367. if not File(path).isDirectory():
  368. if not File(path).mkdirs():
  369. raise RuntimeError('failed to mkdir %s' % path)
  370. else:
  371. import os
  372. try:
  373. os.stat(path)
  374. except:
  375. os.makedirs(path)
  376. mkDirPath = staticmethod(mkDirPath)
  377. def fPath(d,n):
  378. """get file path of the file defined by directory d and file name n"""
  379. if sys.platform.startswith('java'):
  380. from java.io import File
  381. return File(d, n).getPath()
  382. else:
  383. import os
  384. return os.path.join(d, n)
  385. fPath = staticmethod(fPath)
  386. def savetxt(a, b, fmt=False):
  387. """save text b in a text file named a"""
  388. fh = open(a, 'w')
  389. if not fmt:
  390. fmt = '%s'
  391. for row in b:
  392. for element in row:
  393. fh.write(fmt % element + ' ')
  394. fh.write('\n')
  395. fh.close()
  396. savetxt = staticmethod(savetxt)
  397. def osName():
  398. """return which OS we are currently running on"""
  399. if sys.platform.startswith('java'):
  400. from java.lang import System
  401. oname = System.getProperty('os.name')
  402. else:
  403. import os
  404. oname = os.name
  405. if not oname.endswith('x'): oname = 'Windows'
  406. return oname
  407. osName = staticmethod(osName)
  408. def expandEnv(instr):
  409. """potentially expand environment variables in the given string"""
  410. outstr = instr
  411. m = {'$HOME':'HOME','%HOMEDRIVE%':'HOMEDRIVE','%HOMEPATH%':'HOMEPATH'}
  412. for e in m:
  413. if outstr.find(e) != -1:
  414. if sys.platform.startswith('java'):
  415. from java.lang import System
  416. repl = System.getenv(m[e])
  417. else:
  418. import os
  419. repl = os.getenv(m[e])
  420. if repl != None:
  421. outstr = outstr.replace(e, repl)
  422. return outstr
  423. expandEnv = staticmethod(expandEnv)
  424. if sys.platform.startswith('java'):
  425. from java.lang import Runnable
  426. class Helper(Runnable):
  427. def __init__(self, nm, strm, fName):
  428. self.nm=nm; self.strm=strm; self.fp=None
  429. if fName != None:
  430. self.fp = open(fName, 'w')
  431. def run(self):
  432. """helper class for slurping up child streams"""
  433. from java.io import BufferedReader
  434. from java.io import InputStreamReader
  435. from java.lang import System
  436. line = None; br = BufferedReader(InputStreamReader(self.strm))
  437. line = br.readLine()
  438. while (line != None):
  439. if self.fp != None:
  440. self.fp.write(line + System.lineSeparator())
  441. self.fp.flush()
  442. VLAB.logger.info('%s %s' %(self.nm, line.rstrip()))
  443. line = br.readLine()
  444. br.close()
  445. if self.fp != None:
  446. self.fp.close()
  447. else:
  448. def helper(nm, strm):
  449. """helper method for slurping up child streams"""
  450. for line in strm: VLAB.logger.info('%s %s' %(nm, line.rstrip()))
  451. if not strm.closed: strm.close()
  452. helper = staticmethod(helper)
  453. def doExec(cmdrec):
  454. """run the specified external program under windows or unix"""
  455. cmdLine = []
  456. osName = VLAB.osName()
  457. if osName.startswith('Windows'):
  458. cmd=cmdrec['windows']
  459. cmdLine = ['cmd', '/c']
  460. else:
  461. cmd=cmdrec['linux']
  462. exe = VLAB.expandEnv(cmd['exe'])
  463. if not VLAB.fileExists(exe):
  464. raise RuntimeError('Cannot find exe "%s"' % exe)
  465. cmdLine.append(exe)
  466. for i in cmd['cmdline']:
  467. cmdLine.append(VLAB.expandEnv(i))
  468. VLAB.logger.info('cmdLine is [%s]' % cmdLine)
  469. if sys.platform.startswith('java'):
  470. from java.lang import ProcessBuilder
  471. from java.lang import Thread
  472. from java.io import BufferedWriter
  473. from java.io import OutputStreamWriter
  474. from java.io import File
  475. pb = ProcessBuilder(cmdLine)
  476. if 'cwd' in cmd and cmd['cwd'] != None:
  477. pb.directory(File(VLAB.expandEnv(cmd['cwd'])))
  478. if 'env' in cmd and cmd['env'] != None:
  479. env = pb.environment()
  480. cmdenv = cmd['env']
  481. for e in cmdenv:
  482. env[e] = VLAB.expandEnv(cmdenv[e])
  483. proc = pb.start()
  484. stdoutfName = None
  485. if 'stdout' in cmd and cmd['stdout'] != None:
  486. stdoutfName = VLAB.expandEnv(cmd['stdout'])
  487. stderrfName = None
  488. if 'stderr' in cmd and cmd['stderr'] != None:
  489. stderrfName = VLAB.expandEnv(cmd['stderr'])
  490. outs = Thread(VLAB.Helper('out', proc.getInputStream(), stdoutfName))
  491. errs = Thread(VLAB.Helper('err', proc.getErrorStream(), stderrfName))
  492. outs.start(); errs.start()
  493. bw = BufferedWriter(OutputStreamWriter(proc.getOutputStream()))
  494. if 'stdin' in cmd and cmd['stdin'] != None:
  495. inFile = VLAB.expandEnv(cmd['stdin'])
  496. if 'cwd' in cmd and cmd['cwd'] != None:
  497. if not VLAB.fileExists(inFile):
  498. # try pre-pending the cwd
  499. inFile = VLAB.fPath(VLAB.expandEnv(cmd['cwd']), inFile)
  500. if not VLAB.fileExists(inFile):
  501. raise RuntimeError('Cannot find stdin "%s"' % cmd['cwd'])
  502. fp = open(inFile, 'r')
  503. for line in fp:
  504. bw.write(line)
  505. bw.close()
  506. fp.close()
  507. exitCode = proc.waitFor()
  508. outs.join(); errs.join()
  509. else:
  510. import threading, subprocess, os
  511. if 'cwd' in cmd and cmd['cwd'] != None:
  512. os.chdir(VLAB.expandEnv(cmd['cwd']))
  513. if 'env' in cmd and cmd['env'] != None:
  514. cmdenv = cmd['env']
  515. for e in cmdenv:
  516. os.putenv(e, VLAB.expandEnv(cmdenv[e]))
  517. if 'stdin' in cmd and cmd['stdin'] != None:
  518. proc = subprocess.Popen(cmdLine, stdin=open(VLAB.expandEnv(cmd['stdin']),'r'),stdout=subprocess.PIPE, stderr=subprocess.PIPE)
  519. else:
  520. proc = subprocess.Popen(cmdLine, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
  521. t1 = threading.Thread(target=VLAB.helper, args=('out', proc.stdout))
  522. t2 = threading.Thread(target=VLAB.helper, args=('err', proc.stderr))
  523. t1.start(); t2.start()
  524. exitCode = proc.wait()
  525. t1.join(); t2.join()
  526. VLAB.logger.info('exitCode=%d' % exitCode)
  527. doExec = staticmethod(doExec)
  528. def valuesfromfile(path, transpose=False):
  529. """Returns a 2D array with the values of the csv file at 'path'.
  530. Keyword arguments:
  531. transpose -- transpose the matrix with the values
  532. """
  533. fp = open(path)
  534. values = [line.strip().split() for line in fp
  535. if not line.startswith('#')]
  536. fp.close()
  537. values = [[float(value) for value in row] for row in values]
  538. if transpose:
  539. values = zip(*values)
  540. return values
  541. valuesfromfile = staticmethod(valuesfromfile)
  542. def fabsa(x):
  543. """Return the element-wise abs() of the given array."""
  544. return map(lambda x : math.fabs(x), x)
  545. fabsa = staticmethod(fabsa)
  546. def cosa(arcs):
  547. """Return the element-wise cos() of 'arcs' array given in degrees."""
  548. return map(lambda x : math.cos(VLAB.d2r(x)), arcs)
  549. cosa = staticmethod(cosa)
  550. def replacerectinarray(array, replacement, xul, yul, xlr, ylr):
  551. """Replace the array with the specified rectangle substituted with
  552. replacement.
  553. (array[xul:xlr,yul:ylr])
  554. +---------------+
  555. |(xul, yul) |
  556. | |
  557. | (xlr, ylr)|
  558. +---------------+
  559. """
  560. ri = 0
  561. for x in xrange(xul, xlr):
  562. array[x][yul:ylr] = replacement[ri]
  563. ri += 1
  564. return array
  565. replacerectinarray = staticmethod(replacerectinarray)
  566. def replaceinarray(haystack, predicate, replacement):
  567. """Return 'haystack' with 'predicate' matches replaced by 'replacement'"""
  568. return map(lambda item : {True: replacement, False: item}[predicate(item)],
  569. haystack)
  570. replaceinarray = staticmethod(replaceinarray)
  571. def sqrta(values):
  572. """Return the element-wise sqrt() of the given array."""
  573. return map(math.sqrt, values)
  574. sqrta = staticmethod(sqrta)
  575. def suba(lista, listb):
  576. """Subtract the values of a list from the values of another list."""
  577. if len(lista) != len(listb):
  578. raise ValueError("Arguments have to be of same length.")
  579. return map(operator.sub, lista, listb)
  580. suba = staticmethod(suba)
  581. def adda(lista, listb):
  582. """Add the values of a list to the values of another list."""
  583. if len(lista) != len(listb):
  584. raise ValueError("Arguments have to be of same length.")
  585. return map(operator.add, lista, listb)
  586. adda = staticmethod(adda)
  587. def diva(lista, listb):
  588. """Return the element-wise division of 'lista' by 'listb'."""
  589. if len(lista) != len(listb):
  590. raise ValueError("Arguments have to be of same length.")
  591. return map(operator.div, lista, listb)
  592. diva = staticmethod(diva)
  593. def mula(lista, listb):
  594. """Return the element-wise multiplication of 'lista' with 'listb'."""
  595. if len(lista) != len(listb):
  596. raise ValueError("Arguments have to be of same length.")
  597. return map(operator.mul, lista, listb)
  598. mula = staticmethod(mula)
  599. def powa(values, exponent):
  600. """Returns the element-wise exp('exponent') of the given array."""
  601. if isinstance(exponent, (list, tuple)):
  602. return map(lambda x, y : x ** y, values, exponent)
  603. return map(lambda x : x ** exponent, values)
  604. powa = staticmethod(powa)
  605. def treemap(fn, tree):
  606. """Applies `fn' to every value in `tree' which isn't a list and
  607. returns a list with the same shape as tree and the value of `fn'
  608. applied to the values in their place.
  609. """
  610. result = []
  611. for node in tree:
  612. if isinstance(node, (list, tuple)):
  613. result += [VLAB.treemap(fn, node)]
  614. else:
  615. result += [fn(node)]
  616. return result
  617. treemap = staticmethod(treemap)
  618. def makemaskeq(array, value):
  619. return VLAB.treemap(lambda x : x == value, array)
  620. makemaskeq = staticmethod(makemaskeq)
  621. def awhere(mask):
  622. """Returns the coordinates of the cells which evaluate true."""
  623. result = []
  624. if isinstance(mask, (list, tuple)):
  625. for i, cell in enumerate(mask):
  626. result += [[i] + sub for sub in VLAB.awhere(cell)
  627. if isinstance(sub, (list, tuple))]
  628. return result
  629. else:
  630. if mask:
  631. return [[]]
  632. else:
  633. return []
  634. awhere = staticmethod(awhere)
  635. def aclone(tree):
  636. """Make a deep copy of `tree'."""
  637. if isinstance(tree, (list, tuple)):
  638. return list(map(VLAB.aclone, tree))
  639. return tree
  640. aclone = staticmethod(aclone)
  641. def make_chart(title, x_label, y_label, dataset):
  642. """Helper for creating Charts"""
  643. if sys.platform.startswith('java'):
  644. from org.jfree.chart import ChartFactory, ChartFrame, ChartUtilities
  645. from org.jfree.chart.axis import NumberTickUnit
  646. from org.jfree.chart.plot import PlotOrientation
  647. from org.jfree.data.xy import XYSeries, XYSeriesCollection
  648. chart = ChartFactory.createScatterPlot(title, x_label, y_label, dataset,
  649. PlotOrientation.VERTICAL, True,
  650. True, False)
  651. plot = chart.getPlot()
  652. domain_axis = plot.getDomainAxis()
  653. domain_axis.setRange(-70, 70)
  654. range_axis = plot.getRangeAxis()
  655. range_axis.setRange(0.0, 0.4)
  656. range_axis.setTickUnit(NumberTickUnit(0.05))
  657. return chart
  658. else:
  659. # TODO: re-merge original python implementation
  660. raise Exception("original make_chart()")
  661. return None
  662. make_chart = staticmethod(make_chart)
  663. def make_dataset():
  664. """Dataset helper for supporting chart creation"""
  665. if sys.platform.startswith('java'):
  666. from org.jfree.data.xy import XYSeriesCollection
  667. return XYSeriesCollection()
  668. else:
  669. # TODO: re-merge original python implementation
  670. raise Exception("original make_dataset()")
  671. return None
  672. make_dataset = staticmethod(make_dataset)
  673. def plot(dataset, x, y, label):
  674. """plot dataset with x and y values and the given label"""
  675. if sys.platform.startswith('java'):
  676. from org.jfree.data.xy import XYSeries
  677. series = XYSeries(label)
  678. for next_x, next_y in zip(x, y):
  679. series.add(float(next_x), float(next_y))
  680. dataset.addSeries(series)
  681. else:
  682. # TODO: re-merge original python implementation
  683. raise Exception("original plot()")
  684. return None
  685. plot = staticmethod(plot)
  686. def save_chart(chart, filename):
  687. """save the generated chart in the given filename"""
  688. if sys.platform.startswith('java'):
  689. from java.io import File
  690. from org.jfree.chart import ChartUtilities
  691. ChartUtilities.saveChartAsPNG(File(filename), chart, 800, 600)
  692. else:
  693. # TODO: re-merge original python implementation
  694. raise Exception("save_chart")
  695. pass
  696. save_chart = staticmethod(save_chart)
  697. def maskand(array, mask):
  698. return map(lambda a, b : a & b, array, mask)
  699. maskand = staticmethod(maskand)
  700. def unique(array):
  701. """return unique values in the given input array"""
  702. sortedarray = list(array)
  703. sortedarray.sort()
  704. result = []
  705. def addifunique(x, y):
  706. if x != y:
  707. result.append(x)
  708. return y
  709. result.append(reduce(addifunique, sortedarray))
  710. return result
  711. unique = staticmethod(unique)
  712. def ravel(a):
  713. def add(a, i):
  714. if not(isinstance(a, (list, tuple))):
  715. a = [a]
  716. if isinstance(i, (list, tuple)):
  717. return a + ravel(i)
  718. else:
  719. return a + [i]
  720. return reduce(add, a)
  721. ravel = staticmethod(ravel)
  722. def min_l_bfgs_b(f, initial_guess, args=(), bounds=None, epsilon=1e-8):
  723. """The `approx_grad' is not yet implemented, because it's not yet
  724. used."""
  725. if sys.platform.startswith('java'):
  726. from lbfgsb import DifferentiableFunction, FunctionValues, Bound, Minimizer
  727. class function(DifferentiableFunction):
  728. def __init__(self, function, args=()):
  729. self.function = function
  730. self.args = args
  731. def getValues(self, x):
  732. f = self.function(x, *self.args)
  733. g = VLAB.approx_fprime(x, self.function, epsilon, *self.args)
  734. return FunctionValues(f, g)
  735. min = Minimizer()
  736. min.setBounds([Bound(bound[0], bound[1]) for bound in bounds])
  737. result = min.run(function(f, args), VLAB.ravel(initial_guess))
  738. return result.point
  739. min_l_bfgs_b = staticmethod(min_l_bfgs_b)
  740. def approx_fprime(xk, f, epsilon, *args):
  741. f0 = f(xk, *args)
  742. grad = [0. for i in xrange(len(xk))]
  743. ei = [0. for i in xrange(len(xk))]
  744. for k in xrange(len(xk)):
  745. ei[k] = 1.0
  746. d = map(lambda i : i * epsilon, ei)
  747. grad[k] = (f(VLAB.adda(xk, d), *args) - f0) / d[k]
  748. ei[k] = 0.0
  749. return grad
  750. approx_fprime = staticmethod(approx_fprime)
  751. ###########################################################################
  752. #
  753. # Minimize_* functions...
  754. #
  755. # Nelder-Mead simplex minimization of a nonlinear (multivariate) function.
  756. #
  757. # The programming interface is via the minimize() function; see below.
  758. #
  759. # This code has been adapted from the C-coded nelmin.c which was
  760. # adapted from the Fortran-coded nelmin.f which was, in turn, adapted
  761. # from the papers
  762. #
  763. # J.A. Nelder and R. Mead (1965)
  764. # A simplex method for function minimization.
  765. # Computer Journal, Volume 7, pp 308-313.
  766. #
  767. # R. O'Neill (1971)
  768. # Algorithm AS47. Function minimization using a simplex algorithm.
  769. # Applied Statistics, Volume 20, pp 338-345.
  770. #
  771. # and some examples are in
  772. #
  773. # D.M. Olsson and L.S. Nelson (1975)
  774. # The Nelder-Mead Simplex procedure for function minimization.
  775. # Technometrics, Volume 17 No. 1, pp 45-51.
  776. #
  777. # For a fairly recent and popular incarnation of this minimizer,
  778. # see the amoeba function in the famous "Numerical Recipes" text.
  779. #
  780. # P. Jacobs
  781. # School of Engineering, The University of Queensland
  782. # 07-Jan-04
  783. #
  784. # Modifications by C. Schenkel
  785. # Netcetera
  786. # 31-Oct-13
  787. #
  788. ###########################################################################
  789. def Minimize_create_new_point(c1, p1, c2, p2):
  790. """
  791. Create a new N-dimensional point as a weighting of points p1 and p2.
  792. """
  793. p_new = []
  794. for j in range(len(p1)):
  795. p_new.append(c1 * p1[j] + c2 * p2[j])
  796. return p_new
  797. Minimize_create_new_point = staticmethod(Minimize_create_new_point)
  798. def Minimize_take_a_step(smplx, Kreflect, Kextend, Kcontract):
  799. """
  800. Try to move away from the worst point in the simplex.
  801. The new point will be inserted into the simplex (in place).
  802. """
  803. i_low = smplx.lowest()
  804. i_high = smplx.highest()
  805. x_high = smplx.vertex_list[i_high]
  806. f_high = smplx.f_list[i_high]
  807. # Centroid of simplex excluding worst point.
  808. x_mid = smplx.centroid(i_high)
  809. f_mid = smplx.f(x_mid)
  810. smplx.nfe += 1
  811. # First, try moving away from worst point by
  812. # reflection through centroid
  813. x_refl = VLAB.Minimize_create_new_point(1.0+Kreflect, x_mid, -Kreflect, x_high)
  814. f_refl = smplx.f(x_refl)
  815. smplx.nfe += 1
  816. if f_refl < f_mid:
  817. # The reflection through the centroid is good,
  818. # try to extend in the same direction.
  819. x_ext = VLAB.Minimize_create_new_point(Kextend, x_refl, 1.0-Kextend, x_mid)
  820. f_ext = smplx.f(x_ext)
  821. smplx.nfe += 1
  822. if f_ext < f_refl:
  823. # Keep the extension because it's best.
  824. smplx.replace_vertex(i_high, x_ext, f_ext)
  825. else:
  826. # Settle for the original reflection.
  827. smplx.replace_vertex(i_high, x_refl, f_refl)
  828. else:
  829. # The reflection is not going in the right direction, it seems.
  830. # See how many vertices are better than the reflected point.
  831. count = 0
  832. for i in range(smplx.N+1):
  833. if smplx.f_list[i] > f_refl: count += 1
  834. if count <= 1:
  835. # Not too many points are higher than the original reflection.
  836. # Try a contraction on the reflection-side of the centroid.
  837. x_con = VLAB.Minimize_create_new_point(1.0-Kcontract, x_mid, Kcontract, x_high)
  838. f_con = smplx.f(x_con)
  839. smplx.nfe += 1
  840. if f_con < f_high:
  841. # At least we haven't gone uphill; accept.
  842. smplx.replace_vertex(i_high, x_con, f_con)
  843. else:
  844. # We have not been successful in taking a single step.
  845. # Contract the simplex about the current lowest point.
  846. smplx.contract_about_one_point(i_low)
  847. else:
  848. # Retain the original reflection because there are many
  849. # vertices with higher values of the objective function.
  850. smplx.replace_vertex(i_high, x_refl, f_refl)
  851. return
  852. Minimize_take_a_step = staticmethod(Minimize_take_a_step)
  853. def Minimize_minimize(f, x, dx=None, tol=1.0e-6,
  854. maxfe=300, n_check=20, delta=0.001,
  855. Kreflect=1.0, Kextend=2.0, Kcontract=0.5, args=()):
  856. """
  857. Locate a minimum of the objective function, f.
  858. Input:
  859. f : user-specified function f(x)
  860. x : list of N coordinates
  861. args : Extra arguments passed to f, i.e. ``f(x, *args)''.
  862. dx : list of N increments to apply to x when forming
  863. the initial simplex. Their magnitudes determine the size
  864. and shape of the initial simplex.
  865. tol : the terminating limit for the standard-deviation
  866. of the simplex function values.
  867. maxfe : maximum number of function evaluations that we will allow
  868. n_check : number of steps between convergence checks
  869. delta : magnitude of the perturbations for checking a local minimum
  870. and for the scale reduction when restarting
  871. Kreflect, Kextend, Kcontract: coefficients for locating the new vertex
  872. Output:
  873. Returns a tuple consisting of
  874. [0] a list of coordinates for the best x location,
  875. corresponding to min(f(x)),
  876. [1] the function value at that point,
  877. [2] a flag to indicate if convergence was achieved
  878. [3] the number of function evaluations and
  879. [4] the number of restarts (with scale reduction)
  880. """
  881. converged = 0
  882. N = len(x)
  883. if dx == None:
  884. dx = [0.1] * N
  885. smplx = Minimize_NMSimplex(x, dx, f, args)
  886. while (not converged) and (smplx.nfe < maxfe):
  887. # Take some steps and then check for convergence.
  888. for i in range(n_check):
  889. VLAB.Minimize_take_a_step(smplx, Kreflect, Kextend, Kcontract)
  890. # Pick out the current best vertex.
  891. i_best = smplx.lowest()
  892. x_best = list(smplx.get_vertex(i_best))
  893. f_best = smplx.f_list[i_best]
  894. # Check the scatter of vertex values to see if we are
  895. # close enough to call it quits.
  896. mean, stddev = smplx.f_statistics()
  897. if stddev < tol:
  898. # All of the points are close together but we need to
  899. # test more carefully.
  900. converged = smplx.test_for_minimum(i_best, delta)
  901. if not converged:
  902. # The function evaluations are all very close together
  903. # but we are not at a true minimum; rescale the simplex.
  904. smplx.rescale(delta)
  905. return x_best, f_best, converged, smplx.nfe, smplx.nrestarts
  906. Minimize_minimize = staticmethod(Minimize_minimize)
  907. #
  908. # from here to "VLAB end" is used only for testing
  909. #
  910. def fakebye(self, event):
  911. """fake beam callback for existing the program"""
  912. me=self.__class__.__name__ +'::'+VLAB.me()
  913. VLAB.logger.info('%s: exiting' % me)
  914. sys.exit()
  915. def fakeDoProcessing(self, params):
  916. """fake beam helper for driving processing in test mode"""
  917. me=self.__class__.__name__ +'::'+VLAB.me()
  918. VLAB.logger.info('%s: starting' % me)
  919. VLAB.logger.info('params: %s' % params)
  920. #if params[VLAB.P_RTProcessor] == VLAB.K_DART:
  921. # rtProcessor = DART()
  922. #elif params[VLAB.P_RTProcessor] == VLAB.K_LIBRAT:
  923. # rtProcessor = LIBRAT()
  924. #elif params[VLAB.P_RTProcessor] == VLAB.K_DUMMY:
  925. # rtProcessor = DUMMY()
  926. #else:
  927. # raise RuntimeError('unknown processor: <%s>' % params[VLAB.P_RTProcessor])
  928. rtProcessor = LIBRAT()
  929. rtProcessor.doProcessingTests(None, params)
  930. VLAB.logger.info('%s : %s' % (me, 'finished'))
  931. def fakerun(self, event):
  932. """fake beam callback for running a processor"""
  933. me=self.__class__.__name__ +'::'+VLAB.me()
  934. VLAB.logger.info('%s: starting' % me)
  935. params = {}
  936. for i in self.plst:
  937. if type(self.vmap[i]) == str:
  938. params[i] = self.cmap[i].text
  939. elif type(self.vmap[i]) == tuple:
  940. lst = self.vmap[i]
  941. params[i] = lst[self.cmap[i].selectedIndex]
  942. self.fakeDoProcessing(params)
  943. def fakebeam(self):
  944. """fake beam Swing GUI"""
  945. me=self.__class__.__name__ +'::'+VLAB.me()
  946. VLAB.logger.info('%s: starting' % me)
  947. from javax import swing
  948. from java import awt
  949. v = 5; h = 10; self.window = swing.JFrame(VLAB.PROCESSOR_NAME)
  950. self.window.windowClosing = self.fakebye
  951. self.window.contentPane.layout = awt.BorderLayout()
  952. tabbedPane = swing.JTabbedPane()
  953. self.window.contentPane.add("Center", tabbedPane)
  954. for tabGroups in VLAB.model:
  955. for tabName in tabGroups:
  956. tab = swing.JPanel()
  957. tab.layout = swing.BoxLayout(tab, swing.BoxLayout.PAGE_AXIS)
  958. tabbedPane.addTab(tabName, tab)
  959. for group in tabGroups[tabName]:
  960. tab.add(swing.JLabel(''))
  961. p = swing.JPanel()
  962. p.layout = awt.GridLayout(0, 4);
  963. p.layout.vgap = v;p.layout.hgap = h
  964. for groupName in group:
  965. p.border = swing.BorderFactory.createTitledBorder(groupName)
  966. for groupTuple in group[groupName]:
  967. if len(groupTuple) == 4:
  968. (lbl, nm, typ, vals) = groupTuple
  969. p.add(swing.JLabel(lbl+':', swing.SwingConstants.RIGHT))
  970. self.vmap[nm] = vals
  971. if type(vals) == tuple:
  972. self.cmap[nm] = swing.JComboBox(self.vmap[nm])
  973. else:
  974. exec('self.cmap[nm] = swing.'+typ+'(self.vmap[nm])')
  975. self.plst.append(nm)
  976. p.add(self.cmap[nm])
  977. else:
  978. p.add(swing.JLabel(""))
  979. p.add(swing.JLabel(""))
  980. tab.add(p)
  981. # hack
  982. for i in range(50):
  983. tab.add(swing.Box.createVerticalGlue())
  984. tab.add(swing.JLabel(''))
  985. p = swing.JPanel()
  986. p.layout = awt.GridLayout(0, 8)
  987. p.layout.hgap = 4
  988. for i in range(1,5):
  989. p.add(swing.JLabel(""))
  990. p.add(swing.JButton("Run", actionPerformed=self.fakerun))
  991. p.add(swing.JButton("Close", actionPerformed=self.fakebye))
  992. p.add(swing.JButton("Help"))
  993. tab.add(p)
  994. self.window.pack(); self.window.show()
  995. # TESTS
  996. def selftests(self):
  997. """run a pre-defined set of tests"""
  998. me=self.__class__.__name__ +'::'+VLAB.me()
  999. VLAB.logger.info('%s: starting' % me)
  1000. # scenario 1
  1001. params = {
  1002. VLAB.P_3dScene : 'Default RAMI',
  1003. VLAB.P_AtmosphereCO2 : '1.6',
  1004. VLAB.P_ViewingAzimuth : '0.0',
  1005. VLAB.P_AtmosphereWater : '0.0',
  1006. VLAB.P_OutputPrefix : 'RAMI_',
  1007. VLAB.P_ViewingZenith : '20.0',
  1008. VLAB.P_AtmosphereAerosol : 'Rural',
  1009. VLAB.P_DHP_Zenith : '20.0',
  1010. VLAB.P_SceneYW : '100',
  1011. VLAB.P_DHP_3dScene : 'Default RAMI',
  1012. VLAB.P_Bands : '1, 2, 3, 4, 5, 6, 7, 8, 9, 10',
  1013. VLAB.P_OutputDirectory : '',
  1014. VLAB.P_AtmosphereOzone : '300',
  1015. VLAB.P_AtmosphereDay : '214',
  1016. VLAB.P_SceneLocFile : '',
  1017. VLAB.P_SceneYC : '100',
  1018. VLAB.P_DHP_OutputDirectory : '',
  1019. VLAB.P_DHP_OutputPrefix : 'RAMI00_',
  1020. VLAB.P_AtmosphereLat : '47.4781',
  1021. VLAB.P_AtmosphereLong : '8.3650',
  1022. VLAB.P_RTProcessor : VLAB.K_LIBRAT,
  1023. VLAB.P_SceneXW : '50',
  1024. VLAB.P_IlluminationAzimuth : '0.0',
  1025. VLAB.P_Sensor : 'MSI (Sentinel 2)',
  1026. VLAB.P_AsciiFile : 'Yes',
  1027. VLAB.P_ImageFile : 'Yes',
  1028. VLAB.P_SceneXC : '-50',
  1029. VLAB.P_DHP_Y : '0',
  1030. VLAB.P_DHP_X : '0',
  1031. VLAB.P_DHP_ImageFile : 'Yes',
  1032. VLAB.P_DHP_AsciiFile : 'Yes',
  1033. VLAB.P_DHP_Resolution : '100x100',
  1034. VLAB.P_DHP_Azimuth : '0.0',
  1035. VLAB.P_IlluminationZenith : '20.0',
  1036. VLAB.P_DHP_RTProcessor : VLAB.K_DUMMY,
  1037. VLAB.P_DHP_Height : '0',
  1038. VLAB.P_DHP_Orientation : '0',
  1039. VLAB.P_ScenePixel : '8'
  1040. }
  1041. self.fakeDoProcessing(params)
  1042. #### VLAB end ################################################################
  1043. class Minimize_NMSimplex:
  1044. """
  1045. Stores the (nonlinear) simplex as a list of lists.
  1046. In an N-dimensional problem, each vertex is a list of N coordinates
  1047. and the simplex consists of N+1 vertices.
  1048. """
  1049. def __init__(self, x, dx, f, args):
  1050. """
  1051. Initialize the simplex.
  1052. Set up the vertices about the user-specified vertex, x,
  1053. and the set of step-sizes dx.
  1054. f is a user-specified objective function f(x).
  1055. """
  1056. self.N = len(x)
  1057. self.vertex_list = []
  1058. self.f_list = []
  1059. self.dx = list(dx)
  1060. self.f = lambda x : f(x, *args)
  1061. self.nfe = 0
  1062. self.nrestarts = 0
  1063. for i in range(self.N + 1):
  1064. p = list(x)
  1065. if i >= 1: p[i-1] += dx[i-1]
  1066. self.vertex_list.append(p)
  1067. self.f_list.append(f(p, *args))
  1068. self.nfe += 1
  1069. def rescale(self, ratio):
  1070. """
  1071. Pick out the current minimum and rebuild the simplex about that point.
  1072. """
  1073. i_min = self.lowest()
  1074. for i in range(self.N):
  1075. self.dx[i] *= ratio
  1076. x = self.get_vertex(i_min)
  1077. self.vertex_list = []
  1078. self.f_list = []
  1079. for i in range(self.N + 1):
  1080. p = list(x)
  1081. if i >= 1: p[i-1] += self.dx[i-1]
  1082. self.vertex_list.append(p)
  1083. self.f_list.append(self.f(p))
  1084. self.nfe += 1
  1085. self.nrestarts += 1
  1086. return
  1087. def get_vertex(self, i):
  1088. return list(self.vertex_list[i])
  1089. def replace_vertex(self, i, x, fvalue):
  1090. self.vertex_list[i] = list(x)
  1091. self.f_list[i] = fvalue
  1092. return
  1093. def lowest(self, exclude=-1):
  1094. """
  1095. Returns the index of the lowest vertex, excluding the one specified.
  1096. """
  1097. if exclude == 0:
  1098. indx = 1
  1099. else:
  1100. indx = 0
  1101. lowest_f_value = self.f_list[indx]
  1102. for i in range(self.N + 1):
  1103. if i == exclude: continue
  1104. if self.f_list[i] < lowest_f_value:
  1105. lowest_f_value = self.f_list[i]
  1106. indx = i
  1107. return indx
  1108. def highest(self, exclude=-1):
  1109. """
  1110. Returns the index of the highest vertex, excluding the one specified.
  1111. """
  1112. if exclude == 0:
  1113. indx = 1
  1114. else:
  1115. indx = 0
  1116. highest_f_value = self.f_list[indx]
  1117. for i in range(self.N + 1):
  1118. if i == exclude: continue
  1119. if self.f_list[i] > highest_f_value:
  1120. highest_f_value = self.f_list[i]
  1121. indx = i
  1122. return indx
  1123. def f_statistics(self):
  1124. """
  1125. Returns mean and standard deviation of the vertex fn values.
  1126. """
  1127. sum = 0.0
  1128. for i in range(self.N + 1):
  1129. sum += self.f_list[i]
  1130. mean = sum / (self.N + 1)
  1131. sum = 0.0
  1132. for i in range(self.N +1):
  1133. diff = self.f_list[i] - mean
  1134. sum += diff * diff
  1135. std_dev = sqrt(sum / self.N)
  1136. return mean, std_dev
  1137. def centroid(self, exclude=-1):
  1138. """
  1139. Returns the centroid of all vertices excluding the one specified.
  1140. """
  1141. xmid = [0.0]*self.N
  1142. for i in range(self.N + 1):
  1143. if i == exclude: continue
  1144. for j in range(self.N):
  1145. xmid[j] += self.vertex_list[i][j]
  1146. for j in range(self.N):
  1147. xmid[j] /= self.N
  1148. return xmid
  1149. def contract_about_one_point(self, i_con):
  1150. """
  1151. Contract the simplex about the vertex i_con.
  1152. """
  1153. p_con = self.vertex_list[i_con]
  1154. for i in range(self.N + 1):
  1155. if i == i_con: continue
  1156. p = self.vertex_list[i]
  1157. for j in range(self.N):
  1158. p[j] = 0.5 * (p[j] + p_con[j])
  1159. self.f_list[i] = self.f(p)
  1160. self.nfe += 1
  1161. return
  1162. def test_for_minimum(self, i_min, delta):
  1163. """
  1164. Perturb the minimum vertex and check that it is a local minimum.
  1165. """
  1166. is_minimum = 1 # Assume it is true and test for failure.
  1167. f_min = self.f_list[i_min]
  1168. for j in range(self.N):
  1169. # Check either side of the minimum, perturbing one
  1170. # coordinate at a time.
  1171. p = self.get_vertex(i_min)
  1172. p[j] += self.dx[j] * delta
  1173. f_p = self.f(p)
  1174. self.nfe += 1
  1175. if f_p < f_min:
  1176. is_minimum = 0
  1177. break
  1178. p[j] -= self.dx[j] * delta * 2
  1179. f_p = self.f(p)
  1180. self.nfe += 1
  1181. if f_p < f_min:
  1182. is_minimum = 0
  1183. break
  1184. return is_minimum
  1185. #
  1186. # end Minimize_NMSimplex
  1187. #
  1188. #### LIBRAT start ############################################################
  1189. #
  1190. # Librat_ integration routines contributed by Mat Disney and Philip Lewis
  1191. # adapted for BEAM-embedded jython by Cyrill Schenkel and Jason Brazile
  1192. #
  1193. ################
  1194. class Librat_dobrdf:
  1195. def _writeCamFile(self, camFile, args):
  1196. # defaults
  1197. q = {
  1198. 'cam_camera' : 'simple camera',
  1199. 'perspective' : False,
  1200. 'result_image' : 'result.hips',
  1201. 'integral_mode' : 'scattering order',
  1202. 'integral' : 'result',
  1203. 'vz' : 0,
  1204. 'va' : 0,
  1205. 'twist' : 0,
  1206. 'look' : (0., 0., 0.),
  1207. 'ideal' : (100., 100.),
  1208. 'boom' : 1000.,
  1209. 'npixels' : 100000,
  1210. 'rpp' : 1,
  1211. }
  1212. # overwrite defaults
  1213. for a in args:
  1214. q[a] = args[a]
  1215. cdata = ' camera { \n' \
  1216. + ' %s = "%s";\n' %('camera.name', q['cam_camera']) \
  1217. + ' %s = %s;\n' %('geometry.zenith', q['vz']) \
  1218. + ' %s = %s;\n' %('geometry.azimuth', q['va']) \
  1219. + ' %s = "%s";\n' %('result.image', q['result_image']) \
  1220. + ' %s = "%s";\n' %('result.integral.mode', q['integral_mode']) \
  1221. + ' %s = "%s";\n' %('result.integral', q['integral']) \
  1222. + ' %s = %s;\n' %('samplingCharacteristics.nPixels', q['npixels']) \
  1223. + ' %s = %s;\n' %('samplingCharacteristics.rpp', q['rpp']) \
  1224. + ' %s = %s;\n' %('geometry.idealArea', ', '.join(map(str,map('%.1f'.__mod__, q['ideal'])))) \
  1225. + ' %s = %s;\n' %('geometry.lookat', ', '.join(map(str,map('%.1f'.__mod__,q['look_xyz'])))) \
  1226. + ' %s = %s;\n' %('geometry.boomlength', q['boom'])
  1227. if q['perspective']:
  1228. cdata += ' %s = %s;\n' %('geometry.perspective', q['perspective'])
  1229. if q['twist']:
  1230. cdata += ' %s = %s;\n' %('geometry.twist', q['twist'])
  1231. if q['fov']:
  1232. cdata += ' %s = %s;\n' %('geometry.fov', q['fov'])
  1233. if 'lidar' in q:
  1234. if q['lidar']:
  1235. cdata += ' %s = %s;\n' %('lidar.binStep', q['binStep']) \
  1236. + ' %s = %s;\n' %('lidar.binStart', q['binStart']) \
  1237. + ' %s = %s;\n' %('lidar.nBins', q['nBins'])
  1238. cdata += '}'
  1239. fp = open(camFile, 'w')
  1240. try:
  1241. fp.write(cdata)
  1242. finally:
  1243. fp.close()
  1244. def _writeLightFile(self, lightFile, args):
  1245. # defaults
  1246. q = {
  1247. 'light_camera' : 'simple illumination',
  1248. 'sz' : 0.,
  1249. 'sa' : 0.,
  1250. 'twist' : 0.,
  1251. }
  1252. # overwrite detaults
  1253. for a in args:
  1254. q[a] = args[a]
  1255. ldata = ' camera { \n' \
  1256. + ' %s = "%s";\n' %('camera.name', q['light_camera']) \
  1257. + ' %s = "%.1f";\n' %('geometry.zenith', float(q['sz'])) \
  1258. + ' %s = "%.1f";\n' %('geometry.azimuth', float(q['sa'])) \
  1259. + ' %s = "%.1f";\n' %('geometry.twist', float(q['twist']))
  1260. key = "sideal"
  1261. if key in q: ldata += '%s = %s\n' %('geometry.ideal', ', '.join(map(str, map('%.1f'.__mod__, q[key]))))
  1262. key = "slook_xyz"
  1263. if key in q: ldata += '%s = %s\n' %('geometry.lookat', ', '.join(map(str, map('%.1f'.__mod__, q[key]))))
  1264. key = "sboom"
  1265. if key in q: ldata += '%s = %s\n' %('geometry.boom', q[key])
  1266. key = "sperspective"
  1267. if key in q: ldata += '%s = %s\n' %('geometry.perspecitive', q[key])
  1268. key = "sfov"
  1269. if key in q: ldata += '%s = %s\n' %('geometry.fov', q[key])
  1270. ldata += '}'
  1271. fp = open(lightFile, 'w')
  1272. try:
  1273. fp.write(ldata)
  1274. finally:
  1275. fp.close()
  1276. def _writeInputFile(self, inpFile, lightFile, camFile):
  1277. idata = '14' \
  1278. + ' ' \
  1279. + VLAB.getFullPath(camFile) \
  1280. + ' ' \
  1281. + VLAB.getFullPath(lightFile)
  1282. fp = open(inpFile, 'w')
  1283. try:
  1284. fp.write(idata)
  1285. finally:
  1286. fp.close()
  1287. def _writeGrabFile(self, grabFile, args):
  1288. gFilePath = VLAB.getFullPath(grabFile)
  1289. # 'cwd' : '$HOME/.beam/beam-vlab/auxdata/librat_scenes',
  1290. gdata = """cmd = {
  1291. 'linux' : {
  1292. 'cwd' : '$HOME/.beam/beam-vlab/auxdata/librat_scenes',
  1293. 'exe' : '$HOME/.beam/beam-vlab/auxdata/librat_lin64/src/start/start',
  1294. 'cmdline' : ['-RATv', '-m', '%s', '-RATsensor_wavebands', '$HOME/.beam/beam-vlab/auxdata/librat_scenes/%s', '$HOME/.beam/beam-vlab/auxdata/librat_scenes/%s' ],
  1295. 'stdin' : '%s',
  1296. 'stdout' : '%s',
  1297. 'stderr' : '%s',
  1298. 'env' : {
  1299. 'BPMS' : '$HOME/.beam/beam-vlab/auxdata/librat_lin64/',
  1300. 'LD_LIBRARY_PATH' : '$HOME/.beam/beam-vlab/auxdata/librat_lin64/src/lib',
  1301. }},
  1302. 'windows' : {
  1303. 'cwd' : '%HOMEDRIVE%%HOMEPATH%/.beam/beam-vlab/auxdata/librat_scenes',
  1304. 'exe' : '%HOMEDRIVE%%HOMEPATH%/.beam/beam-vlab/auxdata/librat_win32/src/start/ratstart.exe',
  1305. 'cmdline' : ['-RATv', '-m', '%s', '-RATsensor_wavebands', '%HOMEDRIVE%%HOMEPATH%/.beam/beam-vlab/auxdata/librat_scenes/%s', '%HOMEDRIVE%%HOMEPATH%/.beam/beam-vlab/auxdata/librat_scenes/%s' ],
  1306. 'stdin' : '%s',
  1307. 'stdout' : '%s',
  1308. 'stderr' : '%s',
  1309. 'env' : {
  1310. 'BPMS' : '%HOMEDRIVE%%HOMEPATH%/.beam/beam-vlab/auxdata/librat_win32'
  1311. }}
  1312. }
  1313. """
  1314. # hack to allow replacing only %s
  1315. escaped = gdata.replace("%%","\x81\x81").replace("%H","\x81H").replace("%/","\x81/")
  1316. replaced = escaped % \
  1317. (args['sorder'], args['wbfile'], args['objfile'], gFilePath+'.inp', gFilePath+'.out.log', gFilePath+'.err.log', \
  1318. args['sorder'], args['wbfile'], args['objfile'], gFilePath+'.inp', gFilePath+'.out.log', gFilePath+'.err.log')
  1319. gdata = replaced.replace("\x81", "%")
  1320. gdata += 'VLAB.doExec(cmd)\n'
  1321. try:
  1322. fp = open(gFilePath, 'w')
  1323. fp.write(gdata)
  1324. finally:
  1325. fp.close()
  1326. def main(self, args):
  1327. me=self.__class__.__name__ +'::'+VLAB.me()
  1328. VLAB.logger.info('======> %s' % me)
  1329. for a in args:
  1330. VLAB.logger.info("%s -> %s" % (a, args[a]))
  1331. # set up defaults
  1332. q = {
  1333. 'INFINITY' : 1000000,
  1334. 'lightfile' : 'light.dat',
  1335. 'camfile' : 'camera.dat',
  1336. 'wbfile' : 'wb.test.dat',
  1337. 'anglefile' : 'angles.dat',
  1338. 'objfile' : 'veglab_test.obj',
  1339. 'blacksky' : '',
  1340. 'npixels' : 1000000,
  1341. 'image' : 1,
  1342. 'rpp' : 1,
  1343. 'fov' : False,
  1344. 'sorder' : 100,
  1345. 'nice' : None,
  1346. 'boom' : 100000,
  1347. 'ideal' : False,
  1348. 'samplingPattern' : False,
  1349. 'mode' : 'scattering order',
  1350. 'opdir' : 'brdf',
  1351. 'result_root' : 'result',
  1352. 'camera_root' : 'camera',
  1353. 'light_root' : 'light',
  1354. 'grabme_root' : 'grabme',
  1355. 'look_xyz' : (150, 150, 35),
  1356. 'location' : False,
  1357. 'vz' : -1,
  1358. 'va' : -1,
  1359. 'sz' : -1,
  1360. 'sa' : -1,
  1361. }
  1362. for a in args:
  1363. if a == 'look':
  1364. q['look_xyz'] = args[a]
  1365. elif a == 'result':
  1366. q['result_root'] = args[a]
  1367. elif a == 'camera':
  1368. q['camera_root'] = args[a]
  1369. elif a == 'light':
  1370. q['light_root'] = args[a]
  1371. elif a == 'grabme':
  1372. q['grabme_r…

Large files files are truncated, but you can click here to view the full file