Python scripts for Radiance

It may or may not be worth to convert
them, and in some cases the Python version may actually become a
literal translation without any added structure.

OK, I suppose I would have to see an example of that, preferably
something that wasn't organized around a class. One of the things I
have always disliked about C++ is how you have to dig around in the
headers to figure out what the heck the code is doing. Python at
least keeps it together, but it's still a mess in the sense that the
code layout has little to do with control flow. It's an extra hurdle
to understanding I could do without.

This is the straight and complete Python translation of the original
rlux.csh (inheriting most of its usability and portability problems):

import os, sys
if len(sys.argv) < 2:
     print("Usage: $0 [rtrace args] octree")
os.system("rtrace -i+ -dv- -h- -x 1 %s | rcalc -e '$1=47.4*$1+120*$2+11.6*$3' -u" % ' '.join(sys.argv[1:]))

The boilerplate I added around that is simply there for user
friendlyness, and the use of direct process management for platform
independence. With any script as popular as rlux, we *should* add
those things.

There's still the issue of all the supporting libraries, their many
classes and associated methods.

I don't quite see why that is supposed to be a problem.

Actually, I think you've got this one exactly backwards.
Using modules from Python's standard library does not add
dependencies, it reduces them! Those modules are very well documented,
and anyone working with Python will be familiar with them.

I think this is a bit different with Perl, where many popular modules
come from third party sources, and may or may not be present in a
given installation.

You're not refusing to use something like <stdio.h> "because of its
many functions" either, are you?

This ease of maintenance is also one of the reasons why those things
should rather *not* be converted to C. There's simply no need to do that,
as long as we can delegate the number crunching to other tools.

However, I don't see how Python is less work
than Perl given the examples I've seen. Why not Ruby? Why not any of
the other myriad languages out there? You have your favorite; I have
none. I simply went with something that was familiar and supported,
and don't feel like changing canoes midstream as the expression goes.

Some years ago I would have argued solely with Pythons practical
merits, and its "batteries included" approach bringing such a complete
and useful standard library. It used to be my "secret weapon", giving
me a significant productivity advantage.

Today, another added benefit is the large pool of people who know how
to work with it (probably larger than Perl and Ruby together).
Ruby has many similarities with Python (not sure about its library), but
in comparison it's still a niche language. Without Ruby-on-rails it might
still be largely unknown.

  Your rlux.py ended
up being a bit more complex than its C-shell progenitor...
As for

That added "complexity" has little to do with the fact that it's
written in Python (apart from not really being very complex).

ugliness, I don't really see the differences you do. I have employed
languages like TCL, which I do consider write-only (to use Randoph's
term), but Perl is OK for me.

Very few people will be able to make that last claim. And if you
manage to avoid Perls many syntactical and semantical pitfalls, then
you are truly a rare exception. For most people, Perl is just an
accident waiting to happen.

I do find Perl easy to read compared to Python, mostly because I don't
have to jump around the class methods or read up on the add-on
libraries. There are plenty of functions in Perl, no doubt about
that, but they aren't such a growing concern.

You're mixing up choice of language with choice of design method here.

Perl also offers object oriented possibilities nowadays, even if by
far not as simple and elegant. Those features just don't seem to be as
popular with the target audience.

I don't own a Windows box, so it's difficult for me to produce test
cases. I only hear complaints from people about certain commands not
behaving with binary data on Windows, even when it doesn't go into an
intermediate file. In other words, piping the binary output of one
command into another still screws up. Does Windows create a temporary
file when it does this? Maybe if it's on a FAT filesystem (as
Randolph mentioned), this is the source of the problem. It would be
nice to track this down. Although I don't have a ready solution, it
would be good to at least determine the parameters of the problem.
(Radiance's binary files are immune: octrees, HDR pictures, triangle
meshes, even binary matrix data -- it's just the raw IEEE floats &
doubles that usually mess up.)

I've searched for similar complaints online. In the few instances I've
found, it usually was because a terminating null byte wasn't written
to the receiving buffer for some reason. The purportedly received
garbage data was then simply the previous random contents of that
buffer. That may or may not be the cause here as well.

If there really was an inherent problem with using pipes on Windows,
then I'm sure I would have found a lot more information about it.

Cheers
-schorsch

···

--
Georg Mischler -- simulations developer -- schorsch at schorsch com
+schorsch.com+ -- lighting design tools -- http://www.schorsch.com/

But one without the usability and portability problems is noticeably more
complex. On the other hand, it fixes those problems, and the problem of
file names and directories containing spaces as well.

If there really was an inherent problem with using pipes on Windows,

then I'm sure I would have found a lot more information about it.

I am not so sure. Windows documentation can be amazingly opaque, because
MS's technical writers are apparently forbidden from mentioning
limitations, and a casual search will get you scads of irrelevant results.

There absolutely was an issue here, on Windows, when attempting to apply the workflow documented in the 3-phase tutorial Andy wrote, updated with rfluxmtx. For the life of me I cannot recall the specific error, nor can I find my notes on this. But it was related to reading matrices that were output as floats. When using '-faa' (i.e. storing the matrices in ASCII) the problem went away. We punted on this and just standardized on ASCII i/o for all matrix operations, and it's now a real problem with real building models. Would much rather find a solution that allows us to use floats all the time rather than reimplementing an os sniffer to do floats in *nix and ASCII on Windows, for all kinds of reasons. That's about all I have to say on this at the moment but if I can find my notes on this I'll butt-in again.

···

On 3/24/16, 10:27 AM, "Randolph M. Fritz" <[email protected]<mailto:[email protected]>> wrote:

If there really was an inherent problem with using pipes on Windows,
then I'm sure I would have found a lot more information about it.
I am not so sure. Windows documentation can be amazingly opaque, because MS's technical writers are apparently forbidden from mentioning limitations, and a casual search will get you scads of irrelevant results.

Hi Schorsch,

Thanks for your responses. More inline...

From: Georg Mischler <[email protected]>
Subject: Re: [Radiance-dev] Python scripts for Radiance
Date: March 23, 2016 11:28:06 PM PDT

It may or may not be worth to convert
them, and in some cases the Python version may actually become a
literal translation without any added structure.

OK, I suppose I would have to see an example of that, preferably
something that wasn't organized around a class. One of the things I
have always disliked about C++ is how you have to dig around in the
headers to figure out what the heck the code is doing. Python at
least keeps it together, but it's still a mess in the sense that the
code layout has little to do with control flow. It's an extra hurdle
to understanding I could do without.

This is the straight and complete Python translation of the original
rlux.csh (inheriting most of its usability and portability problems):

import os, sys
if len(sys.argv) < 2:
   print("Usage: $0 [rtrace args] octree")
os.system("rtrace -i+ -dv- -h- -x 1 %s | rcalc -e '$1=47.4*$1+120*$2+11.6*$3' -u" % ' '.join(sys.argv[1:]))

The boilerplate I added around that is simply there for user
friendlyness, and the use of direct process management for platform
independence. With any script as popular as rlux, we *should* add
those things.

I wasn't aware that rlux was used by many people, as it only works with ximage and I never even bothered to write a man page for it. I do prefer the simpler solution above to the boilerplate one... (Perl lets us quote things in a way that doesn't introduce issues with spacey filenames.) Does rlux even work under Windows? I suppose it does, or you wouldn't bother. Also, where does this program exit? How does it return an error if it doesn't get at least two arguments? Shouldn't there be a call to os.exit(1) after the print call? Why isn't print() os.print() or sys.print()? These things seem mysterious to me in the land of the "language that doesn't get in they way." The mixture of straight function calls, method calls on class names, and calls on null objects like ''.doSomethingWithString() seems eccentric, or at the least, inconsistent.

There's still the issue of all the supporting libraries, their many
classes and associated methods.

I don't quite see why that is supposed to be a problem.

Actually, I think you've got this one exactly backwards.
Using modules from Python's standard library does not add
dependencies, it reduces them! Those modules are very well documented,
and anyone working with Python will be familiar with them.

I think this is a bit different with Perl, where many popular modules
come from third party sources, and may or may not be present in a
given installation.

You're not refusing to use something like <stdio.h> "because of its
many functions" either, are you?

My main concern is just the add-on nature of the libraries, and that there can be too many to choose from. Having basic facilities that everyone uses establishes conventions that make it easier to read other people's code. So long as everyone chooses the same library to make the same calls, and those calls don't change with new versions of the libraries or of Python, then I don't have a problem with it. It's not that I distrust libraries per se, just "extensionitis." Seeing things like:

import os
import sys
import math
import tempfile
import argparse
import subprocess

at the top of a module is a bit scary -- it means I need to be familiar with these classes to understand the code. It's just more work. I prefer to avoid unnecessary work. After all, I was choosing scripting over writing a C program to make my life simpler, not more fabulously complex. Scripting is also something I do less frequently than writing in C and C++, so I'm not getting keeping my memory as fresh.

... I don't see how Python is less work
than Perl given the examples I've seen. Why not Ruby? Why not any of
the other myriad languages out there? You have your favorite; I have
none. I simply went with something that was familiar and supported,
and don't feel like changing canoes midstream as the expression goes.

Some years ago I would have argued solely with Pythons practical
merits, and its "batteries included" approach bringing such a complete
and useful standard library. It used to be my "secret weapon", giving
me a significant productivity advantage.

Today, another added benefit is the large pool of people who know how
to work with it (probably larger than Perl and Ruby together).
Ruby has many similarities with Python (not sure about its library), but
in comparison it's still a niche language. Without Ruby-on-rails it might
still be largely unknown.

OK, well I haven't kept up with language popularity, and I have no idea who is working with what, how often, or what the poll numbers say. Again, I don't do scripting all that much, so the main issue for me is maintainability of rarely looked-at code. If others are contributing scripts, then I would like to be able to read and understand them. The closer a script is to a list of commands, the easier my job is.

Your rlux.py ended
up being a bit more complex than its C-shell progenitor...
As for

That added "complexity" has little to do with the fact that it's
written in Python (apart from not really being very complex).

ugliness, I don't really see the differences you do. I have employed
languages like TCL, which I do consider write-only (to use Randoph's
term), but Perl is OK for me.

Very few people will be able to make that last claim. And if you
manage to avoid Perls many syntactical and semantical pitfalls, then
you are truly a rare exception. For most people, Perl is just an
accident waiting to happen.

While it's true there are too many ways to write the same expression in Perl, I don't find it difficult to write correct code, or read the code I've written. I admit I haven't spent much time going through other people's Perl code, so I can't speak with much authority on language abuses. Axel Jacobs' Perl code is quite easy to follow.

I do find Perl easy to read compared to Python, mostly because I don't
have to jump around the class methods or read up on the add-on
libraries. There are plenty of functions in Perl, no doubt about
that, but they aren't such a growing concern.

You're mixing up choice of language with choice of design method here.

Perl also offers object oriented possibilities nowadays, even if by
far not as simple and elegant. Those features just don't seem to be as
popular with the target audience.

I suppose it's what you're used to. As I said earlier, the issue with libraries is mostly about vocabulary and what you need to know that isn't right before you. To me, writing a class to do something that should be straightforward doesn't make sense. I might even argue that writing a class where you only expect to create a single object in that class also doesn't make sense, unless you plan to share the class with other classes or modules.

I don't own a Windows box, so it's difficult for me to produce test
cases. I only hear complaints from people about certain commands not
behaving with binary data on Windows, even when it doesn't go into an
intermediate file. In other words, piping the binary output of one
command into another still screws up. Does Windows create a temporary
file when it does this? Maybe if it's on a FAT filesystem (as
Randolph mentioned), this is the source of the problem. It would be
nice to track this down. Although I don't have a ready solution, it
would be good to at least determine the parameters of the problem.
(Radiance's binary files are immune: octrees, HDR pictures, triangle
meshes, even binary matrix data -- it's just the raw IEEE floats &
doubles that usually mess up.)

I've searched for similar complaints online. In the few instances I've
found, it usually was because a terminating null byte wasn't written
to the receiving buffer for some reason. The purportedly received
garbage data was then simply the previous random contents of that
buffer. That may or may not be the cause here as well.

If there really was an inherent problem with using pipes on Windows,
then I'm sure I would have found a lot more information about it.

Well, in our case, it's not about null bytes not being sent -- it's about knowing exactly when we've reached end-of-data, which we expect the system to tell us in some cases. Radiance's binary formats for octrees, ambient files, pictures, etc., we know when we've reached EOD regardless because the file header tells us how much to expect. However, when we're sending binary streams of floats to rcalc, which is simply operating on them and counting on the OS to stop sending data when it's out of data, we run into trouble if the OS doesn't tell us exactly when the party is over.

I suppose a simple test would be something like:

  cnt 37 | rcalc -of -e '$1=recno' | total -if

This should give us a value of 703, or n*(n+1)/2 for any n (i.e., 37*(37+1)/2==703). We could try running the above on a Windows box with a FAT or ExFAT filesystem to determine if this is a problem or not. We should probably try it with some large numbers as well, being aware that we end on a 128-byte boundary when n is a multiple of 32.

We can also try it while writing with an intermediate file between rcalc and total, to see if that makes any difference.

Cheers,
-Greg

File under "my $0.02":

Today, another added benefit is the large pool of people who know how
to work with it (probably larger than Perl and Ruby together).
Ruby has many similarities with Python (not sure about its library), but
in comparison it's still a niche language. Without Ruby-on-rails it
Might still be largely unknown.

Agreed. The OpenStudio team is on Ruby because the whole project started
as a SketchUp plugin, and SketchUp's API is Ruby. I found it very easy to
slide over to Ruby from Python (and now prefer it), and Ruby's library
support is quite good. I agree it's less well-known, but *because* of
Rails it is indeed far from unknown. Be that as it may, I'm willing to bet
big money that this Radiance community has more Python expertise than it
does any other scripting-type language. Python also has a gem of a data
visualization library in 'matplotlib'.

···

On 3/24/16, 12:28 AM, "Georg Mischler" <[email protected]> wrote:

Hi Rob,

We should definitely try this again -- as I said, binary matrix files shouldn't be a problem anymore, so long as it has a header with the number of rows and columns in it, so the receiving program knows when to stop reading in data. You will still have issues with tools like rcalc working on header-less input, so those are the places to look out for in the workflow. In some cases, we may be able to reformulate things to use rmtxop or add an option to rcalc for number of i/o records.

-Greg

···

From: "Guglielmetti, Robert" <[email protected]>
Subject: Re: [Radiance-dev] Python scripts for Radiance
Date: March 24, 2016 9:44:43 AM PDT

There absolutely was an issue here, on Windows, when attempting to apply the workflow documented in the 3-phase tutorial Andy wrote, updated with rfluxmtx. For the life of me I cannot recall the specific error, nor can I find my notes on this. But it was related to reading matrices that were output as floats. When using '-faa' (i.e. storing the matrices in ASCII) the problem went away. We punted on this and just standardized on ASCII i/o for all matrix operations, and it's now a real problem with real building models. Would much rather find a solution that allows us to use floats all the time rather than reimplementing an os sniffer to do floats in *nix and ASCII on Windows, for all kinds of reasons. That's about all I have to say on this at the moment but if I can find my notes on this I'll butt-in again.

On 3/24/16, 10:27 AM, "Randolph M. Fritz" <[email protected]<mailto:[email protected]>> wrote:

If there really was an inherent problem with using pipes on Windows,
then I'm sure I would have found a lot more information about it.
I am not so sure. Windows documentation can be amazingly opaque, because MS's technical writers are apparently forbidden from mentioning limitations, and a casual search will get you scads of irrelevant results.

My impression is that Python has become something of a standard in the
research community, with tools like SciPy, NumPy, and SAGE widely used,
though Perl has a library comparable to NumPy in PDL, and there is a
SciRuby, There is nothing else like SAGE except for the commercial packages
Mathematica and MATLAB. There is also the granddaddy of them all, LISP, but
I don't want to press that on our community; it is intimidating, however
useful once one learns it.

On the statistical side there is R and (wince) Excel.

What do people think? Who is using what?

Randolph

import os
import sys
import math
import tempfile
import argparse
import subprocess

​On Unix, os, sys, and math are mostly wrappers around libraries familiar
to you; on Windows, they are often very close in functionality. I don't
expect they would be much trouble to your. Tempfile is a little bit more
confusing (it is loaded down with security "features," which are mostly
irrelevant in our work), and argparse and subprocess do require study.

This is, to some extent, the old decision as to use libraries or roll your
own code. The standard advice is to use libraries for the sake of
maintenance, since they are already debugged and documented, but libraries
can sometimes load you down with complexities unnecessary to your work.
Overuse of libraries can weigh your programs down; one can, for instance,
end up with XML formats when simple text files will do.

I am forming some thoughts on the broader issues, but I will wait for them
to gel before posting them, I think.

Randolph

  Does rlux even work under Windows? I suppose it
does, or you wouldn't bother. Also, where does this program exit?
How does it return an error if it doesn't get at least two arguments?
Shouldn't there be a call to os.exit(1) after the print call? Why
isn't print() os.print() or sys.print()? These things seem mysterious
to me in the land of the "language that doesn't get in they way." The
mixture of straight function calls, method calls on class names, and
calls on null objects like ''.doSomethingWithString() seems eccentric,
or at the least, inconsistent.

The "big" version of rlux.py runs on *any* platform supporting both
Radiance and Python. The "small" one would require some fiddling with
quotes to run on Windows, as long as there are no spaces involved.

Python programs can exit in three different ways (quite similar to
Perl, I think):
  By running off the bottom without error (exit value 0)
  By the builtin function exit(n)/quit(n) (with the given exit value)
  Via an uncaught exception (exit value 1)
That just reminds me that I probably should exit with a no-zero value
at the very bottom when catching the "Error" exception.

And a closely related bug you correctly detected in my quick-and-dirty
translation: Next to printing the usage message, it should indeed
exit() with a non-zero value as well.

One of the purposes of modules is to unclutter the local namespace.
However, there's still a number of very frequently used objects and
functions directly accessible from any context. Those include
   the system exceptions
   the type objects (which also serve as conversion functions)
   other type conversion functions that aren't types themselfes
   quit() and exit() (really the same thing)
   print()
   a smallish number of other very elementary functions
Part of that selection is necessarily arbitrary (design choice), and
has been reduced quite a bit over the evolution of the language.
The print function is global because it is probably one of the most
used functions of all. In earlyer versions of Python it actually used
to be a language keyword instead of a function.

Something like ''.split() or ''.join() is absolutely consistent with
the general object model, and handled pretty much the same in all
object oriented languages. It would rather be excentric to still
treat a string as an "array of char" in this context.

The use of qualified names for functions and methods serves to keep
namespaces seperate, in oder to avoid confusion. I understand that it
may not be obvious to you right now whether you see a function call in
a module, or a method call in an object instance (I don't think I'm
using any class methods in my code). But that will become clearer each
time you look at it.

My main concern is just the add-on nature of the libraries, and that
there can be too many to choose from. Having basic facilities that
everyone uses establishes conventions that make it easier to read
other people's code. So long as everyone chooses the same library to
make the same calls, and those calls don't change with new versions of
the libraries or of Python, then I don't have a problem with it. It's
not that I distrust libraries per se, just "extensionitis." Seeing
things like:

import os
import sys
import math
import tempfile
import argparse
import subprocess

at the top of a module is a bit scary -- it means I need to be
familiar with these classes to understand the code. It's just more
work. I prefer to avoid unnecessary work.

That block may look impressive (I could have written it on one line,
and you might have hardly noticed it). But the actual modules are
very common and rather obvious.

The documentation describes the most often used two modules as:
   os - Miscellaneous operating system interfaces
   sys - System-specific parameters and functions

You need "math" as soon as you want to do calculations beyond the basic
operators and min()/max().

"Tempfile" knows where the standard temp directories on every platforma
are, and helps to prevent tampering. I know that the latter is not
really critical for Radiance, but it's just good programming practise.

"Argparse" has an obvious name. Don't get fooled by the visually massive
appearance of the related code blocks, that is only because they
include all the text strings for the usage help output.

The "subprocess" module may be the least trivial of the lot, but it
simplifies things by encapsulating platform differences. And I've
again encapsulated its use in pyradlib/pyrad_proc. In the actual
scripts, we only need it for the constant subprocess.PIPE.
We could actually offer that for import through pyrad_proc, to make
it more obvious what it's used for.

Those are all very good questions that show your increasig grasp of
Python. All hope is not lost... :wink:
An outside view is also quite helpful in finding the bugs hiding in
some of my own blind spots.

Perl also offers object oriented possibilities nowadays, even if by
far not as simple and elegant. Those features just don't seem to be as
popular with the target audience.

I suppose it's what you're used to. As I said earlier, the issue with
libraries is mostly about vocabulary and what you need to know that
isn't right before you. To me, writing a class to do something that
should be straightforward doesn't make sense. I might even argue that
writing a class where you only expect to create a single object in
that class also doesn't make sense, unless you plan to share the class
with other classes or modules.

People have built whole life philosophies around that question...
In my case, after working with object oriented methods for so many
years, it has just become second nature to start with a class.
Experience shows that as things grow, they tend to turn into a class
anyway, so I'm usually saving on one of the refactoring stages.

When converting those scripts, I chose to use the same pattern for all
of them for consistency. I was fully aware that I was adding around 90%
of boilerplate to rlux.py, hence the comment at the top of the file.

But we also need to keep in mind, that when we start distributing
those things as exe files on Windows, those users may not want to go
to look up the sources on radiance-online just to see how the script
is invoked correctly. So the script itself really needs to give them
good diagnostics and usage instructions. And in the extreme case of
around three lines of actual functionality, that will lead to this
seemingly absurd ratio of content to packaging.

Btw.: That doesn't mean that the original csh scripts need to go away!
They may serve as a reference implementation verified by you, that we
can use to compare the translations against. As long as you haven't
familiarized yourself with Python enough to check the more complex
examples directly, they can happily live next to each other.

Cheers
-schorsch

···

Am 2016-03-24 17:58, schrieb Gregory J. Ward:

--
Georg Mischler -- simulations developer -- schorsch at schorsch com
+schorsch.com+ -- lighting design tools -- http://www.schorsch.com/

Hi Wouter,

such "interactive" scripts present a special challenge.

I made an experiment with this one, and you'll find the resulting
glaze.py on GitHub. The user interface works a bit different than
in the original, but I'm sure you'll figure it out.
Automatic testing is difficult here, so I didn't systematically test
all the possible permutations. But as far as I could tell so far it
should produce the same results as the original.

Cheers!
-schorsch

···

Am 2016-03-21 22:41, schrieb ascendilex | Wouter Beck:

Dear Georg,

I would vote for the glaze csh script.

Best,
Wouter

On 03/21/2016 05:02 PM, Georg Mischler wrote:

Hi again!

I have converted some of the original Radiance shell scripts into
Python.
https://github.com/gmischler/PyRad [1]

The examples so far are exact drop-in replacements of the original
csh
or Perl versions, but with some extra functionality and benefits.

* usage instructions (-H)
* progress report (-V)
* dry-run mode (-N)
* detailed error diagnostics
* compatible with Python 2.7 and Python 3.x
* self contained (all functionality can be combined in one file)
* truly cross-platform (no dependencies other than Python and
Radiance)
* direct process management (no intermediate shell calls)
* immune to whitespace in file names
* tamper-proof use of temporary files
* instrumented for building a single-file *.exe with pyinstaller

The current selection is still small, the examples were chosen for
varying reasons:

* falsecolor.py
This one has been sitting on my disk (in much less refined form)
for
many years. Now I've updated it to using color palettes and to
satisfy
all the points above.

* phisto.py
* rlux.py
* pveil.py
Those three became test candidates because they are simple and
have
a straightforward command line.

I'm looking for ideas (and contributions) on where to continue next.

Good candidates are scripts that are commonly used.
It is also very helpful if a script includes documentation about
what
it's actually supposed to do. Ideally with a set of test data to
verify that it really does that.
Actually, a solid set of test cases for the current collection would

be very helpful too.

Some of the csh/Perl scripts present a challenge, because they have
rather unconventional command lines. In those cases, we might want
to
consider changing the interface to something more regular, provided
this is possible.

Not all of the existing scripts are really worth the effort.
The Python versions with the extra functionality are definitively
not
as simple as the originals. Flexibility and safety has its price.
On the other hand, they will definitively be *much* easier to
maintain.

Many of the current scripts (csh *and* Perl) blindly assume the
existence of a unix type shell, a number of other posix tools
(grep/awk/sed/etc.), and they often fail with spaces in file and
directory names. Fixing this would introduce additional overhead
in any language.

Why Python?

For developers, it is simply one of the most productive tools
around.
Python has grown into one of the most popular languages just by its
practical merits, without any corporate backing, and without a very
strong web appeal.

Most Radiance users will already have it installed, no matter the
platform.

On unix, scripts can be invoked by "#!" (like any other).

Any script can be "compiled" into a standalone executable file.
This is important on Windows, because invoking scripts (Python,
*.bat, or otherwise) from within programs is a real hassle there.
In fact, it ended up being the simplest way to get winimage to
perform falsecolor analysis.
(This could also be done with Perl, but...)

I expect Python to play an increasing role in Radiance development
in
the future, with or without my own involvement. So we might just as

well embrace it.

I would like to suggest adding Python versions of the most commonly
used scripts to the distribution. There are several possible
configurations how this could be done, so we'd have to discuss a
number of technical details first. And yes, verification before
inclusion would be an important step.

Opinions?

-schorsch

Links:
------
[1] https://github.com/gmischler/PyRad

_______________________________________________
Radiance-dev mailing list
[email protected]
http://www.radiance-online.org/mailman/listinfo/radiance-dev

--
Georg Mischler -- simulations developer -- schorsch at schorsch com
+schorsch.com+ -- lighting design tools -- http://www.schorsch.com/