Sunday, December 23, 2007

The Jewel, Mars

Full Moon and Mars ©2007 Chris W. Johnson

Mars gleams like a tiny jewel
dangling from the full moon on an invisibly fine thread.

Wednesday, December 19, 2007

Wish I'd Thought of That

The Ultimate Present. Although, sooner or later, I think my neighbors, and even local law enforcement, would have objected to the detonations.

Wednesday, December 12, 2007

Spans of Night

When I visited the Bamberger Ranch on the 4th, I was down there to catch some fall color that Margaret told me had just appeared. I was also cleared to enter the chiroptorium, where I intended to shoot a spherical panorama - something I'd been waiting the better part of a year to try. As usual, I drove down there in the wee hours to avoid traffic. The air was dipping below freezing, and the skies were as clear, and the stars as bright, as you can hope for in these parts. On the way out there, I glimpsed two meteors, and saw a third once I'd arrived at the ranch and encamped up at the old windmill near the red pens. It was a gorgeous night, apart from the cold. My plan was to setup a camera looking north past the windmill and let it shoot 30 second exposures until it ran out of power or storage. While it did that, I was going to get some sleep. The point of the exercise was to capture a large number of frames of the moving stars, which I would later attempt to merge into a single image - one of those images you've probably seen that shows the stars blurred into concentric circles around the pole star.

That worked out, except for two things: (1) I completely failed to interpret the compass display on my GPS unit correctly (frankly, it still doesn't make sense to me), and (2) I didn't manage to get to the ranch and start the camera until just a few hours before sunrise - not nearly enough time to capture the kind of motion I wanted, even if I had pointed the camera in the correct direction. Next time, I'll do better.

All the same, when I returned home with all of those sky photos, I set about writing the utility program I'd had in mind for merging the images without accumulating the light pollution that a single, multi-hour exposure would have done. The algorithm was trivial: from each pixel in every one of those photos, take the brightest components, and build a single image exclusively from those. Since the algorithm isn't summing the values of pixels or their components, the sky stays as black as it was in any one of those exposures (and the stars stay as bright), while the motion of the stars accumulates nicely.

The code worked fine and produced the following image from the pre-dawn exposures.

Night sky image. ©2007 Chris W. Johnson

It's not much of an image, but it proved the technique could work. Then, since I still had the much larger set of night sky images I'd shot earlier in the year during the Perseid meteor shower, I ran them through the code. Those frames produced a much more satisfying image:

Night sky image. ©2007 Chris W. Johnson

The windmill is illuminated because I had briefly pointed a little LED flashlight at it a number of times during the Perseid shoot. That trivial amount of light turned-out to be plenty.

So, my shoot on the morning of the 4th was useless, but it did get me to write the little image merge utility that I'd had in mind for a while, and that retroactively extracted a nice little image from my Perseid shoot back in August. A roundabout way of getting things done, but, hey, it worked. And, if you care about this sort of thing, by all means try it yourself; the utility is included below.

That useless shoot turned-up one other interesting thing, after careful examination: While I slept, and the pre-dawn sun began to brighten the sky and make the images useless for the merge experiment, the camera just happened to catch a meteor for me. Not a spectacular one, but a fine one that happened to be in just the right place at the right time to make a pleasant photo. Little space rock, I thank you.

Windmill and Meteor. ©2007 Chris W. Johnson

On the subject of little space rocks, it goes without saying that I've been looking forward to shooting the Geminid meteor shower that'll take place this Thursday-night/Friday-morning. I even placed a rush order for a battery grip for the camera, so that it could shoot for twice as long without me disturbing it. Unfortunately, it looks like the weather in this region is going to make seeing the Geminids impossible. Someday, with a bit of luck, I'll capture an ideal meteor photo, but it looks like I'll have to wait about eight months before I'll get to try again. Bloody clouds.

My Image Merging Utility

I can't be the first person to have come-up with the simple brightness merging algorithm I used to combine my night sky shots; more probably I'm the thousandth person. Nonetheless, since I don't know of any tool that does it, I enclose below the source code for the single-class Java application I wrote to perform the merge. (Consider it GPL-ed.) It makes no effort to be fast, just to be correct, short and clear. An implementation that included direct pixel access could be about four times faster, in my experience, and multi-processor support would be easy enough to add, but all of that would only clutter this little piece of code. And, performance aside, support for so-called "16-bit" images would be a worthwhile improvement. But I'll leave all that cluttering as an exercise for the reader, or for later, or both.

In any case, good luck with your own photos.

package com.mac.chriswjohnson.bmerge;


import javax.imageio.ImageIO;
import java.io.File;
import java.io.IOException;
import java.awt.image.BufferedImage;


/** BrightnessMerge is a program that combines the brightest elements of any number of image files into a single image
 *  file. The first parameter should be the name of the output image file. All other parameters should be the paths 
 *  of the directories containing the images that should be merged to produce the output image file. The directories
 *  may contain other directories.
 * 
 *  @author Chris W. Johnson
 */
public class BrightnessMerge {

    public static void main
    (
        final String[]          Args
    ) 
    throws Exception 
    {
        final int               ArgCount = Args.length;
        
        if (ArgCount == 0) {
            
            System.out.println("The first parameter, the name of the output file, is missing.");
            return;
        }
        
        final File              DestImgFile;
        
        if (Args[0].endsWith(".png"))
            DestImgFile = new File(Args[0]);
        else
            DestImgFile = new File(Args[0] + ".png");
        
        if (DestImgFile.exists()) {

            System.out.println("The output file, \"" + DestImgFile + "\", already exists. Please choose a different output file name.");
            return;
        }
        
        final BrightnessMerge CombinedImage = new BrightnessMerge();
        
        for (int ArgIndex = 1; ArgIndex < ArgCount; ArgIndex++) {
            final File              SrcImgsDir = new File(Args[ArgIndex]);
            
            if (SrcImgsDir.exists() == false) {
                
                System.out.println("The directory \"" + SrcImgsDir + "\" does not exist.");
                return;
            }
            
            if (SrcImgsDir.isDirectory() == false) {

                System.out.println("The item at \"" + SrcImgsDir + "\", which should be a directory of images, is not a directory at all.");
                return;
            }
            
            CombinedImage.mergeDir(SrcImgsDir);
        }

        System.out.println("All images merged.");
        
        CombinedImage.savePNG(DestImgFile);

        System.out.println("Done.");
    }
    
    
/** The image into which all other images are merged. */
    
    private BufferedImage       DestImg;
    
/** The width of DestImg, and of all input images. */
    
    private int                 Width;
    
/** The height of DestImg, and of all input images. */
    
    private int                 Height;


/** Merges all of the images found in a directory, or a hierarchy of directories, into our output image.
 * 
 *  @param SrcImgsDir           The directory of images to be merged, or a directory of other directories containing 
 *                              images to be merged.
 *  @throws IOException         If <code>SrcImgsDir</code> is not a directory, or does not exist.
 */ 
    private void mergeDir
    (
        final File              SrcImgsDir
    )
    throws IOException
    {
        System.out.println("Processing images in directory: " + SrcImgsDir);        
        
        for (final File SrcImgFile : SrcImgsDir.listFiles()) {
            
            if (SrcImgFile.isHidden())
                continue;
            
            if (SrcImgFile.isFile())
                mergeFile(SrcImgFile);
            else if (SrcImgFile.isDirectory())
                mergeDir(SrcImgFile);
        }
    }

/** Merges the contents of an image file into our output image.
 * 
 *  @param SrcImgFile           An image file in any of the formats supported by Java.
 *  @throws IOException         If <code>SrcImgFile</code> cannot be read.
 */
    private void mergeFile
    (
        final File              SrcImgFile
    )
    throws IOException 
    {
        final BufferedImage     SrcImg = ImageIO.read(SrcImgFile);
        
        if (DestImg == null) {
            
            Width   = SrcImg.getWidth();
            Height  = SrcImg.getHeight();
            DestImg = new BufferedImage(Width, Height, BufferedImage.TYPE_INT_RGB);
        
        } else {
            
            if (SrcImg.getWidth() != Width || SrcImg.getHeight() != Height)
                throw new IllegalArgumentException("All input images must be " + Width + " X " + Height + " pixels, but the image \"" + SrcImgFile + "\" is not.");
        }
        
        for (int Y = 0; Y < Height; Y++) {
            
            for (int X = 0; X < Width; X++) {
                final int               SrcPixel  = SrcImg.getRGB(X, Y);
                final int               SrcR      = SrcPixel >> 16 & 0xFF;
                final int               SrcG      = SrcPixel >>  8 & 0xFF;
                final int               SrcB      = SrcPixel & 0xFF;
                
                final int               DestPixel = DestImg.getRGB(X, Y);
                int                     DestR     = DestPixel >> 16 & 0xFF;
                int                     DestG     = DestPixel >>  8 & 0xFF;
                int                     DestB     = DestPixel & 0xFF;
                
                if (DestR < SrcR)
                    DestR = SrcR;
                if (DestG < SrcG)
                    DestG = SrcG;
                if (DestB < SrcB)
                    DestB = SrcB;
                
                final int               NewDestPixel = DestR << 16 | DestG << 8 | DestB;
                
                if (NewDestPixel != DestPixel)
                    DestImg.setRGB(X, Y, NewDestPixel);
            }
        }

        System.out.println("Processed image: " + SrcImgFile);
    }

/** Saves the output image to the specified output file in the Portable Network Graphics (PNG) format.
 * 
 *  @param DestImgFile      The file to which our output image will be written.
 *  @throws IOException     If the file could not be created, or written-to.
 */
    private void savePNG
    (
        final File          DestImgFile
    ) 
    throws IOException
    {
        System.out.println("Saving combined image to: " + DestImgFile);
        ImageIO.write(DestImg, "png", DestImgFile);
    }
}

Monday, December 10, 2007

The Bamberger Ranch Chiroptorium - Main Chamber VR Panorama

The chiroptorium is the artificial bat cave constructed by the Bambergers to try to bring a substantial bat population to the ranch. Like many others, I've photographed it from outside, but all that really shows is the big, artificial cave mouth. I haven't seen any photos of the interior since it was under construction (it was a work of art before its surface was covered with concrete and the whole structure buried). So, I've thought for a while that a spherical panorama ought to be shot inside it in order to clearly show people the end-result of that construction. However, the chiroptorium's success, in the form of the 120,000 Mexican free-tail bats that occupied it this year, kept me from entering to shoot a panorama before last Tuesday, December 4th, because we didn't want to risk disturbing the bats. With the arrival of winter the free-tails have returned to Mexico, so the chiroptorium's only residents are many hundreds of cave myotis tucked-away in the warmth of a pair of internal bat boxes, and untold legions of flesh-eating dermestid beetles occupying the foot or more of accumulated bat guano that covers the cave floors wall-to-wall. The consensus was that I could enter without disturbing the myotis, provided that I wasn't disturbed by the flesh-eating beetles. A pair of rubber boots proved to be adequate for keeping the beetles at bay, and the shoot went smoothly, to the continuous accompaniment of the chattering myotis.

The result is the following high dynamic-range, high-resolution QuickTime VR panorama. The panorama is 8.4 MB, so it may take some time to load.

Chiroptorium Main Chamber. Click to View.

The panorama initially looks from the main chamber into the exit tunnel. If you were an exiting bat, that's where you'd be headed. The tunnel to the right of that leads to the smaller second chamber, which leads in-turn to the very small, inner-most third chamber. The main chamber shown here is the best exemplar of the chiroptorium's design. Key features include the following:

  • The chiroptorium was designed as sequence of intersecting domes. The domes were formed from an elaborate weave of rebar, which was then covered with metal mesh. Concrete thickened with fiberglass was sprayed onto the mesh (without that thickener, the concrete went right through the mesh). The richly textured interior surface created by that concrete is a design feature - it provides innumerable footholds for the bats. When construction was complete, the chiroptorium, built at the bottom of a small valley, was covered with earth, thus effectively filling-in much of the valley, and transforming the domes into a cave. (A large drain pipe prevents the remaining portion of the valley from forming a lake behind the cave, and keeps the cave floor dry.)
  • The floor is covered with years of accumulated bat guano, which, when I encountered it, was a dry, almost fluffy layer of material, that must have been somewhere around a foot deep over the entire area of the floor. It is home to (among other things) a large population of flesh-eating dermestid beetles, which eat fallen bats. (Some of the white specks visible on the surface of the guano are bones. Some of the black, shiny specks are the beetles.) The invertebrate population of the chiroptorium is being studied by researchers who are interested in learning how the invertebrate populations typically found in bat-occupied caves establish themselves. Since the chiroptorium began as a clean slate, so to speak, the chiroptorium probably represents a unique opportunity for such studies.
  • The ceiling of the dome is interrupted by three concentric vertical rings of concrete. They provide additional surface area on which bats may roost.
  • Two bat boxes, one square and one rectangular, hang from the ceiling. They were a part of the chiroptorium from the beginning. Their purpose was to provide roosts for the initial population of bats. Their compactness is a feature with a small population: tightly packed into those boxes, the bats keep each other warm. At the time this panorama was shot, both boxes were filled with cave myotis bats, which find the boxes to be ideal winter roosts.
  • The large tubes extending up through the ceiling are ventilation shafts, though they are not used while bats are present.
  • The wood set into the wall covers the viewing gallery's windows. Those windows turned-out to be the reason that the chiroptorium went for years without acquiring a population of bats. I've heard conflicting explanations of why the windows were a problem for the bats, but, whatever the reason, once the windows were covered, the bats found the chiroptorium (now minus its "torium"-ness) a very agreeable home.

    Margaret Bamberger supplies some details on the conflicting explanations regarding the windows: "Either/or or both are true (probably): (1) When flying around in daylight bats use eyesight for navigation. If light came through the window from the other side, it would look like an opening, and they'd fly into it. (2) Glass doesn't send back a signal to the bat's echolocation, because it has no surface variation, and the bats don't know that it is there. Bats will swoop down and try to drink from very flat surfaces that are horizontal. They have no experience with such surfaces on a vertical plane, except where humans put them. In a cave built for them it becomes a huge problem."

    (I first met David Bamberger at a Bat Conservation International (BCI) outing to Bracken Cave, whose purchase he had years earlier organized on behalf of BCI. Having seen an article about the construction of the chiroptorium in the BCI newsletter years before, I asked him how the project had turned-out. He paused, then said unhappily "let me put it this way: I'm currently housing bats at five thousand dollars a head." During that period, I gather the chiroptorium was labelled by some as "Bamberger's Folly." It took years to realize that the observation gallery windows were the problem, but as soon as the windows were covered, the bats came, stayed, and bred, making the chiroptorium a bigger success with each passing year.)

Margaret Bamberger can say a great deal more about every aspect of the chiroptorium, and what they've learned from it about constructing artificial bat habitat. Post questions to her blog as comments, and I'm sure she'll have plenty to say.

Photographic Notes

This panorama is composed of 12 segments, each photographed at three different exposures: 30, 8 and 2 seconds, all at f8 and ISO 400. Nothing less could produce useful exposures using only the dim, indirect light coming in through the entry tunnel. The images, totaling 364 megapixels, were assembled into three separate panoramas, which were combined into a single high-dynamic range image, then tonemapped down to a range that monitors can handle. Unfortunately, using only three exposures per segment still left the entry tunnel over-exposed, which is exactly the sort of thing that high-dynamic range photography is meant to prevent. My camera will only take three different exposures automatically, so taking additional exposures would have meant a lot of manual manipulation of the camera. Such manipulation brings with it the danger of causing the tripod to shift its footing, thereby ruining the precise alignment of the images. (The spiked feet of my tripod never did find the concrete floor - eventually I just made them stable in the guano.) That limitation may have been fortunate, however: the HDR and image manipulation applications that I depend on kept choking on the size of these images. In the end, it seemed like pure luck that I finally got them to do their jobs. An additional exposure or two might have prevented the tools from ever doing their jobs.

With the three panoramas finally combined into a single rectilinear image (360° by 180°), that image was broken into six images, corresponding to the faces of a cube. Doing so made it possible to heavily retouch the image of the floor to remove the tripod, the panoramic head and its counter-weight from the image. (In other words, the floor seen beneath the caption and copyright notice is an artificial construct.) The cube faces, including the heavily retouched floor face, were then combined to make the final QuickTime VR panorama.

Thursday, December 6, 2007

Fragments of Fall

Reports from Margaret Bamberger of trees displaying their fall colors brought me back to the Bamberger Ranch on Tuesday, November 4th. Walking the Rachel Carson trail did, indeed, lead me to the colors. They were impressive, though confined to the young, scattered maples. However, what they lacked in quantity they made up for in intensity, as the high-dynamic range images below attest.

Due to the fact that most of the other trees in the area had already shed their leaves, I didn't find any scene along that trail that I thought would make a pleasing panorama. However, the grasses continued to be impressive, and as sunset approached, I setup in a tall stand of grass whose seed heads were catching the light beautifully, operating the pano rig while crouching beneath the tripod, in the hope that I could stay out of the shot, without moving around the camera and trampling the near-field grasses that were to be the focus of the pano. That worked-out alright, but the wind never did cooperate. With the last rays of sunlight rapidly disappearing up the stalks of grass, I shot the pano out of desperation, knowing it couldn't work. But, below, a few frames of that failed pano provide good samples of what I was trying to capture.

By the way, the one place where wind didn't interfere with my panoramic efforts, was my first target of the day: the chiroptorium, the artificial bat cave constructed by the Bambergers to try to bring a substantial bat population to the ranch. Like many others, I've photographed it from outside, but all that really shows is the big, artificial cave mouth. I haven't seen any photos of the interior since it was under construction (it was a work of art before its surface was covered with concrete and the whole structure buried). So, I've thought for a while that a spherical panorama ought to be shot inside in order to clearly show people the end-result of that construction. However, the chiroptorium's success, in the form of the 120,000 Mexican free-tail bats that occupied it this year, kept me from entering to shoot a panorama before now, because we didn't want to risk disturbing the bats. With the arrival of winter, however, the free-tails have returned to Mexico, so the chiroptorium's only residents are many hundreds of cave myotis tucked-away in the warmth of a pair of internal bat boxes, and untold legions of flesh-eating dermestid beetles occupying the foot or more of accumulated bat guano that covers the cave floors wall-to-wall. The consensus was that I could enter without disturbing the myotis, provided that I wasn't disturbed by the flesh-eating beetles. A pair of rubber boots proved to be adequate for keeping the beetles at bay, and the shoot went smoothly, to the continuous accompaniment of the chattering myotis. The result should be a good high dynamic-range spherical panorama as soon as I have time to assemble it. Stay tuned.

Tuesday, December 4, 2007

Sunset in High Lonesome

“Bamberger Ranch, Sunset in High Lonesome” ©2007 Chris W. Johson

The last of the panoramas shot on 27-Nov-2007 at the Bamberger Ranch. It could do with a bit more tinkering, mostly with the white balance, but it's pretty fair as it stands, IMHO. Happily, it suggests that my difficulties with Annie Leibovitz and the wind were not the undoing of that day's shooting. More importantly, I hope that it manages, in some small way, to share the beauty of that place and time with those who can appreciate it, but could not be there. Apologies for the tiny image, but Blogger automatically imposes these size limits on images. Once I'm finished working with the image, I'll place a high-resolution version of it on my panoramas page.

Sunday, December 2, 2007

Bamberger Ranch Journal

My friend, Margaret Bamberger has started a blog about the Bamberger Ranch Preserve, the Bamberger Ranch Journal. Ranchers, conservationists, sustainable-use advocates, nature lovers, and even people in general, may all find items of interest there. Please welcome Margaret to the world of blogging, and, if you have any questions relating to the preserve and its work, I expect that leaving a comment for her would be likely to provoke an informative response.

Thursday, November 29, 2007

Best Laid Plans, Meet Annie Leibovitz

I took the day off of work on Tuesday and went down to the Bamberger Ranch to shoot some fall panoramas. Arriving in the wee hours of the morning (the drive is a lot less of a hassle on empty roads), I slept away the remainder of a near-freezing night in the back of my pickup, regained consciousness at noon, had lunch with Margaret Bamberger, then set out to re-shoot my "Jacob's Ladder no. 1" panorama, roughly one year later. I thought it'd be interesting to compare the scene in drought conditions (as seen in the existing pano), and in the aftermath of this year's wet winter, spring and summer. I also thought I'd shoot some more panoramas on the creek that feeds the Jacob's Ladder tank; there'd been a good, solid (and much-needed) rain a day or two before, so the creek should have had a nice flow, and, with luck, the bald cypresses and grasses would be at the height of their fall colors.

However, things didn't work out as I expected. It turned-out that there was another photographer with permission to be on the ranch that day, and they'd already claimed the full-length of the road leading to Jacob's Ladder, and even the trail-head that leads to it from far upstream. And they'd laid claim in a big way: catering trucks, motorcycles, support vehicles, loads of staff, etc. Turns out that Annie Leibovitz, of all people, was on the ranch to shoot—if the third-hand information I received was correct—the Paul Mitchell heirs.

I commend her on the choice of locations, but ...well... damn.

That meant quickly coming-up with a plan "B" and "C" for my day's shooting. The trees were no help at all; the fall-colors were minimal and spotty. According to Margaret, most of the trees went more-or-less directly from green to brown this year, skipping the "fall color" phase almost completely. Speculation is that the wet winter, spring and summer conspired with the dry fall to throw-off the trees in a big way.

What fall color there was, lay in the grasses, which were a beautiful mix of reds, oranges and golds. I'd been wanting to capture the fall grasses, anyway, so the Liebovitz/tree conspiracy wasn't a complete show-stopper. I re-shot some of my early work around Madrone Lake (plan "B"), then, taking advantage of a temporary ceasefire that had been negotiated with the season's hunters for Liebovitz's visit, I hiked up into a valley of High Lonesome that I'd had my eye on for years (plan "C") where I shot a sequence of panos as sunset approached.

“High Lonesome Sunset” ©2007 Chris W. Johnson

The big problem with trying to shoot high-dynamic-range panoramas of grasses (and a lot of other things, for that matter) is the wind. Even shooting with a 10mm lens, as I do, eighteen photos are required to capture each scene (three separate exposures for each of the six segments of a 360 degree pano), so a pano can be ruined by the movement of a single prominent stalk of grass in any one of those eighteen images. Needless to say, that means waiting long and hard for the local air to come to a complete stop, and, due to the scarcity of such moments, doing without second takes. Pieces of the panos look promising (see above), but there's no telling whether any of them were shot when their scenes were still enough, long enough, for them to assemble cleanly. I'll have to assemble them to find out, and that's going to take a lot of work.

If the panos don't assemble well enough to be usable, the silver lining will be that I can truthfully say that Annie Liebovitz ruined one of my shoots, which should do a wonderful job of conveying the mis-impression that I move in elite photographic circles, when I really move in a tiny, second-hand pickup truck.

Thursday, November 22, 2007

Snapshots from the Ranch

Snapshots from a visit to the Bamberger Ranch, back on the 13th.

A very-near sunset shot looking out over Big Valley and into the valleys of High Lonesome and Round Mountain. If the clouds had been more cooperative earlier, when the foreground wouldn't have been in shadow, this shot could have really been something.

The dinosaur tracks in their protective enclosure, and Margaret Bamberger photogaphing them.

Three large turtles, of a species unknown to me, enjoying a recently fallen tree in an ancient, spring-fed lake. Arrowheads and other artifacts found around this lake suggest that it has been important to more than just turtles for a very long time.

Wednesday, November 21, 2007

Qwicap 1.4b12 Released

Qwicap 1.4b12 has been released. Thanks go out to Sunil for noticing the problem with extracting numeric values from XML when using the Qwicap XML engine stand-alone. That bug has been fixed. Also, the Qwicap.getStatusReport method works again. Full details in the change history. Source code, binaries and examples are available on SourceForge, as usual.

Monday, November 19, 2007

Qwicap 1.4b11 Released

Version 1.4b11 of the Qwicap Java web application framework (or anti-framework, IMO) has been released. This beta kind of got away from me, frankly. It really should have been broken-up into a succession of betas, and possibly version 1.5 betas, at that. But I was running low on things to do before declaring version 1.4 done, and some untouched items on the original 1.4 "to do" list were staring at me, and I started to think that it'd just be a downright shame to go to release without a few more of those features. One thing led to another, of course, and here we are.

My project management skills aside, good things have happened to Qwicap. Notably, this version embraces Java 1.5, provides Qwicap's first support for internationalization/localization/multi-lingualism, and allows Qwicap applications to run both directly from their WAR files, and within the default configuration of the Security Manager in Tomcat. It also wraps-up the effort to make Qwicap fully character-set aware. (It's so character-set aware at this point, that you can make web applications that operate entirely in the EBCDIC code page of your choice, or in any mix of the many other character sets known to Java. The limiting factor is the range of character sets supported by the various browsers, and the bugs therein.) See the change history for full details.

By the way, in connection with Qwicap's new internationalization features, I'm looking for people with good non-English language skills who'd be willing to translate Qwicap's internal error messages (there are something like 22 of them), and its "number guess" example application (one web page, and a few other strings). I expect that Qwicap's internationalization features will evolve with use, so translations will help not only with the actual translation problem, but will probably aid in the refinement and growth of Qwicap's internationalization API. If you're interested, there's contact information on the Qwicap main page, or you can leave me a comment here.

Tuesday, November 13, 2007

The Show's Over

The LBJ Wildflower Center show, in which my Bamberger Ranch panoramas were being shown, closed Sunday. I picked-up the unsold canvases this afternoon (Monday). There's no telling when I'll see my cut of the money from the pano that did sell; having been subsumed into my old friend, The University of Texas at Austin, the Wildflower Center has to have State paperwork filled-out and filed before they can give me a dime. The economics of this art are such that, unless I'm fortunate enough to sell a helluva lot more material, the difference between having that money and not, is just a matter of how deep a hole I'm standing in. I'm kinda used to my hole at the moment, so the money will come whenever it comes, and I can live with that. What the future holds for shows I know not, but this show went well, so, for the time being, I'm not concerned.

On the other hand, Margaret sold none of her sketches, and Kathy none of her photos. I suspect that the show was improperly structured for their needs; I've seen Margaret sell a passel of prints in a single evening of a single day show, and Kathy has no trouble selling her work, though she's usually showing other material. Possibly this extended show lacked the sense of occasion, and the opportunity to spend some time with the artists, learn about their subject matter, and form a sense of connection with it. Or not. All that aside, it was still a pleasure to have this opportunity. My thanks to the folks at the Wildflower Center for making it possible.

Sunset at the LBJ Wildflower Center's tower. ©2007 Chris W. Johnson

P.S. If you did happen to catch the show and liked some of the panorama canvases, but not enough to plunk down $1,900 for one, I also have high-quality, unframed, archival-grade paper prints measuring 44 X 17 inches (the image itself occupies 40 X 12 inches of that space) which I can sell for a great deal less. (But remember that framing costs will consume some of the savings.) Leave a comment with your contact information for more information. (I won't publish the comment.)

Monday, October 29, 2007

Resolved: Mac OS X 10.5 vs. Sonnet Tempo-X eSATA 4+4 card

My previously mentioned problem—that the Sonnet Tempo-X eSATA 4+4 card's firmware is violently incompatible with Mac OS X 10.5—has been resolved. Owners of that card or other cards that use the same firmware need to be aware of the following: Version 2.1.2 of the firmware is 10.5 compatible. Apparently there was a problem with a 10.5 beta version, but that was corrected at Apple's end prior to 10.5's release. The reason that people, like myself, who went to the Sonnet downloads page to get the latest firmware for their cards received firmware that was not compatible with 10.5 was an error in the page markup. Specifically, if you clicked on the great, big down-arrow graphic to download the firmware, you received version 2.1.1 (which is not 10.5 compatible), but if you chose to click on the word "download" next to it, you received version 2.1.2 (which is 10.5 compatible). I've alerted Sonnet to the problem and it's probably been fixed by now. Hopefully, they've added a big, red note about this fact, since the version number of the firmware won't have changed to tip-off people about the difference.

One mild caveat: I had only a few minutes to try the Tempo 2.1.2 firmware with Mac OS X 10.5 before I had to leave for work earlier today, but they did seem to be working together just fine, which is consistent with what Sonnet technical support claims about the 2.1.2 firmware.

Follow-up: Yes, the 2.1.2 firmware works fine with Mac OS X 10.5.

Sunday, October 28, 2007

A Pano from the Show

I've been meaning to swing by the show of my, Margaret's and Kathy's works at the LBJ Wildflower Center before it closes, in order to shoot some panoramas by which to remember it. I shot a few shortly before closing time this Saturday, October 27th. There were a few people taking-in the show even at that hour, which was nice to see, and left me tempted to introduce myself, and offer to answer any questions they might have had about the images or the ranch. I suppose they might have enjoyed that, I also suppose that they might have felt waylaid by an emotionally needy artist. So I shelved that urge and shot panos until the security guard came-in to lock-up. Below is the first of those panos that I've assembled. It includes about 40% of Margaret's drawings, 75% of my panos, and most of Kathleen Marie's photos, although none of these works can be appreciated in the available resolution. It does, however, capture some of the nice setup the Wildflower Center has provided for the show.

Photographically, the scene presented some serious challenges. One was the white balance; with the scene illuminated by direct and reflected sunlight, along with one or more types of artificial lighting, there was no single white point that would be correct for the entire image – more like three or four. There's no way that I know of to reconcile all of them, although I can imagine a white balance algorithm that would apply different pre-established white point corrections to separate areas of an image, while gracefully interpolating plausible white points for the areas between the pre-established points. Tone-mapping algorithms already perform similar spatially-adaptive work on other aspects of images, so I don't think I'm going out on a limb with this notion. Unfortunately, I don't have time to try coming-up with an implementation of my own. In any case, a lot of color-tweaking brought this image to a reasonable compromise among its varied white points.

The other challenge in this pano was that, even when shooting three "raw" exposures (at separations of two f-stops) of each segment of the panorama, the sunlit world outside the windows still ended-up overexposed. Unfortunately, my camera has neither support for automatically shooting more than three separate exposures at one time, nor for increasing the difference between them to anything beyond two f-stops. Perhaps when I return to finish shooting the show, I'll try manually shooting the additional exposures that these scenes need, but doing so introduces a lot more opportunities to make mistakes, and seriously slows-down the shooting process, which causes its own problems.

One of these days, I hope, we'll have affordable cameras with the kind of native dynamic range in their sensors that will make the multi-exposure approach obsolete. That'll leave the current crop of high-dynamic range photographers with a lot more competition, but I'm looking forward to the development of such cameras, nonetheless.

(On the other hand, I run into a lot of photographers who don't mind their skies showing-up white when they were actually blue, etc., and who are, therefore, perfectly happy living within the constraints imposed by shooting JPEG images, even when they could just as easily shoot "raw", and thereby eliminate at least some of those dynamic-range limitations. I don't understand that, but there are a lot of things I don't understand, and perhaps I'm so hopelessly outside the mainstream, that there won't turn-out to be enough of a market to justify the development-, or sustain the production-, of cameras with the ultra-high-dynamic-range sensors for which I'm waiting. It'd be a shame if things worked-out that way, but the successes and failures of technologies have surprised me before, and, doubtless, will again.)

Saturday, October 27, 2007

Mac OS X 10.5 vs. Sonnet Tempo-X eSATA 4+4 card

I installed Mac OS X 10.5 this evening. I knew it could be a mistake (I've been using Macs since the first one was released in 1984, and have been punished for being an early adopter many times), but the list of disappointments I was expecting proved to be too short in one critical respect: having installed 10.5, my Mac started freezing every time the Finder loaded. No way out, except to power-cycle the machine. After much experimenting and checking of vendor web pages for firmware updates, I discovered that the Sonnet Tempo-X eSATA 4+4 card, which I depend on to access the vast majority of the storage on my Mac, is not compatible with 10.5. In the final sentence of the paragraph describing the latest firmware update for that card, Sonnet does acknowledge this: "Note that Mac OS X Version 10.5 beta will not currently operate with these cards and Power Mac computers." Wish I'd thought to go searching through vendor web pages for these tiny, vital gems of information before I'd installed 10.5. But even more, I wish Sonnet had fixed the problem during 10.5's lengthy beta period. (My past experiences with the company lead me to expect better than this from them.) So, if you happen to have one of these Sonnet cards, best to hold-off on the 10.5 upgrade, and maybe even drop Sonnet a line expressing your interest in a fix. I know I'm waiting anxiously for their response to my email.

Late addition: It also seems worth noting that Apple's practice of releasing products like 10.5 on Fridays (and in the late afternoon, no less) leaves customers who encounter problems like mine stranded without access to tech support from most vendors for more than two days. Monday releases would be a vastly better choice in this regard.

As an article in Mac User magazine, I think it was, said of early adopters about twenty years ago: "you can tell the pioneers by the arrows in their backs." This is a hopelessly flawed summary of events in the settlement of the American west, but a very good description of the settlement of many technological frontiers. Of course, if my judgement had been better, I'd've skipped being an early adopter in this case, as I usually do, but it remains to be seen, from Sonnet's response to this problem, whether that would have made any difference.

Much later addition: This issue has been resolved.

Friday, October 26, 2007

Sold!

I learned this morning that my panorama-on-canvas "Bamberger Ranch, West Slope Middle Grassland, no. 2", which is currently on display at the LBJ Wildflower Center, has been sold.

I don't know who bought it, but I send them my compliments. I hope they get many decades of enjoyment from it. It is, by the way, the "artist's proof" no. 1 print—the very first print of that image in that format (or, as it happens, in any format)—so it is singular; more limited even than the small limited edition that will follow. So, on the off chance that my work becomes collectable in the future, that print should be uniquely valuable.


For any readers wondering about that image, here's the description of it that I wrote for the show:

July 29, 2007 – Hip-high grass swaying in a warm breeze, scattered oak stands, sunshine, and an oncoming storm.

Three years of random visits may be required, but a sweeping field of grass scattered with shady stands of oak, and gifted with a distant horizon, may eventually be caught in a favorable condition, season, and light, and, just maybe, with dramatically unfavorable weather impending. There’s some persistence and judgement in such an endeavor, and a lot of luck.

This field adjoins those reserved for the world’s last wild herd of Scimitar-horned Oryx. From time to time, it, too, plays host to the critically-endangered antelope. Its elements should bear some deeply-welcomed resemblance to their native African savanna, and its most striking element—the grass—most of all. Planted specifically for the Oryx, the African Klein grass stands fine, tall, and dense. Its blades pass luxuriantly against an interloper’s legs. If their flavor is the equal of their look and feel, the Oryx eat well at the edge of extinction.

Friday, October 12, 2007

Enjoy it while you can, Al Gore

As most of you have probably heard already, Al Gore won the Nobel Peace Prize for his work in raising awareness about global warming. The White House has even said it's happy for him (ya, sure). I'd just like to say: Congratulations, Al, and enjoy it while you can, because I expect the next thing that will happen is that the Supreme Court will rule 5-4 that George Bush actually won it.

Monday, October 8, 2007

Nocturnal Photographic Trivia

Over the previous few months, I've made a number of visits to the Bamberger Ranch for purposes other than taking new photographs; mostly picking-up panoramas from the Kirchman Gallery in Johnson City, where I've been having them printed. It is my usual practice to make the drive more pleasant by doing at least the outbound leg at night, then catching some sleep in the guest quarters (when available), and getting on with the business of the day whenever I regain consciousness. I usually bring along all of my photographic gear just-in-case. On several of these visits the "just-in-case" has been "just-in-case I arrive there early enough to try shooting a moonlight panorama, before I absolutely have to get to sleep".

All of those moonlight panoramas have been complete failures, because they turned-out so clear and colorful that they look a lot like they were shot in the middle of the day. I more-or-less expected that, but figured that I could add the "moonlight look" after the fact by playing with colors, levels, etc. That failed, too, probably because the way that the camera's sensor and the human eye's retina experience these low-light conditions are very different. There may yet turn out to be a way to get the look that we humans expect by processing the images after the fact, but I'm not optimistic at this point.

So, I pass along my failures for your amusement:

The panorama above was shot halfway up a valley wall in the region of the ranch known as Wildlife Preserve. Crossing valley-bottom streams and climbing by the light of the moon and a small red-LED flashlight was very time consuming and a bit dangerous. Nonetheless, I was eventually able to reach a spot very near where I had shot a panorama two years ago. That time, it was broad daylight and the exposures were trivially short. This time, there was a full moon, elegantly obscured by clouds, so I could only obtain reasonable exposures at f8 by using ISO 800, and a shutter speed of 2 minutes. With the camera taking an additional two minutes to perform noise reduction on each image, each shot really took 4 minutes, and therefore the whole, six-segment pano took about half an hour to shoot, and a lot longer if you include the time spent on various test exposures. As you can see, nothing about the image suggests that it was shot between 5 and 5:30 in the morning, exclusively by moonlight.

From one of the test exposures, above is a sample of the wonderful texture of the clouds that night. Unfortunately, little of that texture comes through in the panorama because the longer exposures used for those images allowed the steadily moving clouds to become undifferentiated blurs.

While I stood up there on the valley wall, waiting for the camera to do its job, there came a moment when I heard a descending whistle sound from one of the four or five valleys that open onto that scene. For some reason, I associated that call with a Great Horned owl (I'm not sure that's right, but that's what I thought it was at the time). With nothing else to do, I thought I'd try to call the owl over to me. Since I can't imitate any Great Horned calls, I settled for my iffy impression of a screech owl call, knowing that Great Horneds will gladly make a meal of screech owls. I never did see any evidence of a Great Horned owl, but I was surprised to find that my lousy screech owl impression was answered by at least one pair of screech owls in each valley. I knew screeches were in the area, but I was surprised to find that there were so many.

The failure of the previous moonlight panorama notwithstanding, on a subsequent visit I tried again by the light of a ¾ moon, and this time at the mouth of the chiroptorium, the artificial cave that the Bambergers built in an effort to establish a large bat population on the ranch. After a rocky start, the chiroptorium has become a complete success; the last bat count put the population at around 120,000. And what could be a more appropriate time of day to shoot a panorama at the mouth of a bat cave than the middle of the night? So I setup there, with bats hurtling all around me, and after a time-consuming series of test shots, began shooting the pano starting at 3:56 AM. To achieve acceptable exposures at f8 and ISO 800, I had to settle for a shutter speed of five minutes. Add to each of those exposures a further five minutes of noise reduction processing by the camera, and it took a full hour to shoot the six segments. Unfortunately, ten minutes gives the moon a lot of time to move, and that changed the lighting noticeably from one frame to the next. Those changes give rise to the obvious intensity differences in the sky at the frame boundaries. (There'd be some of that anyway, due to vignetting in the lens, but let the light source change its position with respect to the camera, and the problem is compounded.) And, it goes without saying that, once again, the pano looks like it was shot in daylight.

It also goes without saying that the panorama includes thousands, perhaps tens of thousands, of bats. Only one bat held still long enough to be recorded in any of the images, but, believe me, they were there. One of the many nice things about working amongst all those bats was what wasn't there: mosquitos. Despite a pair of nearby ponds that should have been producing mosquitos in quantity, I was bothered by only two in the hour-and-half I spent there. As a mosquito attractor, I may have even been providing easy pickings for the bats that raced all around me; some returning to the cave, a smaller number emerging, and many others just swooping through the area.

One of those mosquito producing ponds provided the other great pleasure of that shoot; a chorus of leopard frogs. Their voices often sound a bit like a pair of inflated rubber balloons being rubbed against each other. Whimsically, I was left thinking that the species has been trying to sing with all its might for millions of years, but still hasn't managed to get the hang of it. And, I thought, on some distant night when they do, at long last, get the hang of it, these ponds ought to put the world's opera houses to shame, due to the cumulative effect of all that practice. My peculiar ponderings aside, the lady leopard frogs obviously find the singing appealing, so the fellows are doing something right. And I can't help but smile when I hear them, so I suppose I agree with the ladies.

Lastly there's the above experiment in long, night sky exposures on a moonless night. I had to guess at the pole star's location from some short, test exposures, and didn't get it exactly right, but I was in the neighborhood. That shot was a 45 minute exposure at 10 mm, f4 and ISO 400. Once again, noise-reduction processing after the exposure took as long as the exposure itself, so that was 90 minutes of continuous work for the camera, which makes it important to start with a freshly-charged battery. Fortunately, the noise reduction process works fine even with the lens cap in place and the camera standing at the end of a bed burdened with a snoozing photographer.

Sunday, October 7, 2007

Opening Day

I dropped by the Wildflower Center shortly before closing time today, the show's opening day. My purpose was to upgrade the artist biographies that are included in the exhibit. Those printed-up by the Center turned-out to be sad black & white affairs, carelessly mounted on scrap foam core. I'm all for the recycling, but the quality of the results made it a wasted effort. So, Kathleen Marie printed and mounted the bios herself, I drove out to her studio near Johnson City to collect them, then returned home by way of the Wildflower Center to install them. The McDermott building was empty, so there was no trouble performing the unscheduled exhibit upgrade. (The headline "Artist arrested vandalizing own show" ran through my head more than once while considering this little errand.)

After the upgrade, I tried to stand back and see the exhibit the way a visitor might - but failed. Knowing those people and places, and especially my panoramas, which are something like frozen, idealized memories for me, I don't think I can possibly know what the exhibit will look like to anyone else. I can say that the lighting seemed good, and that the panoramas look a lot smaller on those big, 1883 carriage-house walls than they do on the modest, 1953 walls of my house. I straightened a few pictures, tidied up our business cards, read through the guest book, and slipped out as quietly as I'd come. It was nice to have seen a few familiar names in the guest book.

This evening, Margaret Bamberger called to ask about the exhibit, having returned home from the hospital late in the afternoon. The cancer treatment and aftermath sound like they were hell, but she's on the mend now, and all indications are that the results will be good, so, hopefully, she'll be back to a normal life in the not-too-distant future. It's not clear, however, whether she'll be feeling well enough to attend David's presentation at the Wildflower Center next Friday morning, and to join in the subsequent book-signing. By the way, she set me straight on the book signing. The text on the Wildflower Center's events page had led me to believe that Jeffrey Greene would be there to sign the book, but, in fact, it'll be the book's subject, David Bamberger, rather than its author, who will be doing the signing. That's understandable, given that Jeffrey lives in France, and the commute's a bitch.

Friday, October 5, 2007

Karma Vertigo

While working to finish the latest beta of Qwicap, I've also re-read Stewart Brand's book The Clock of the Long Now, which has previously tickled my mind in interesting ways. In that book, specifically on page 120, Jaron Lanier is quoted:

The computer code we are offhandedly writing today could become the deeply embedded standards for centuries to come. Any programmer or system designer who takes that realization on and feels the full karmic burden, gets vertigo.

I've had that feeling from the beginning of the Qwicap project, and it grows with each new release. (And I've only been thinking in terms of a decade or two.) The work on the latest beta has included several vertigo inducing issues, from big things like creating an internationalization/multi-lingualization architecture, to seemingly trivial issues in the process of adopting Java 1.5 features, like whether, where, and how best, to add support for the "for each" loop and its associated Iterable interface to the public API.

There's been another kind of vertigo, too; one for which I know of no clever name. It occurs as the point of completion for the current beta seems to recede further into the future with every day I spend working on it. I'm getting plenty of work done on it, but, get one new feature more-or-less sorted-out, and it either uncovers the need for related work elsewhere in the code, or reveals whole new vistas of work in the form of features that suddenly seem both inevitable, and urgent, because, if I don't implement them now, while they can be cleanly integrated into the rest of the new work, I'll have to implement them awkwardly later. And thus the completion date seems to retreat further into the future the more I work to finish this beta. I'll be relieved when it's finally released.

Installation complete – the Wildflower Center show is almost ready

I spent much of Thursday at the Lady Bird Johnson Wildflower Center installing the art for the Bamberger Ranch exhibit. If my mental count is correct, we installed 50 pieces, including my four panoramas, Margaret Bamberger's 21 prints, and something like 25 photographs by Kathleen Marie. Margaret couldn't make it (we await word of the results of her latest cancer treatment), so Kathleen Marie and I, ably assisted by Johnny Ramirez of the 'Center staff, performed the installation. I had planned to shoot a few panoramas of the exhibit after the installation, for inclusion here, but the exhibit still needs to be lit. That task will take Johnny most of Friday, so it won't be in a fit state to be photographed until shortly before the exhibit opens on Saturday. So, I'll have to find some quiet day during the next month to slip back and shoot my show panos.

While the Center wasn't overrun with visitors this Thursday, we did have to keep turning-away small groups of people who happened upon us and wanted to see the works. Sorry about that, folks. Here's hoping that you can make it back after the exhibit opens this Saturday, October 6th (and before it closes on November 11th). There's no opening party, or anything; that'll just be the first that time visitors will be permitted into the McDermott Learning Center to see the show.

The closest that anyone will come to making an event out of the show is on Friday, October 12th when David Bamberger will be giving the presentation "Selah: The Story of the Bamberger Ranch Restoration" at 10:30 AM, followed by a signing of the book "Water from Stone: The Story of Selah, Bamberger Ranch Preserve" by its subject, David Bamberger, and, with luck, its illustrator, Margaret Bamberger. Salesman's blood runs in David's veins, so he gives a very good presentation. I recommend attending, provided that you aren't too busy earning a living at the time. (Why is it that these sorts of things are so often scheduled while most people are working?)

Anyway, every piece on display in the show is available for purchase through the Wildflower Center's gift shop. (Purchasers will have to wait until the show closes to collect their purchases, of course.) So, if you have friends with lots of disposable income, and some blank spots on their walls, please bring them along. Also, if you happen to see something that you like that has already been sold, other prints from those editions can be ordered from each artist. The Center should provide our contact information. (If they don't, drop me a line, and I'll provide it.) In my case, I can not only provide additional limited-edition canvas prints of my panoramas (60 X 18 inches, mounted and ready to hang, as seen in the show), but also smaller, unframed, and much less expensive, archival-grade paper prints (40 X 12 inches). I have one such paper print of each of the panos at the show "in stock", at the moment, so I can say with confidence that the quality of those prints is excellent.

It's good to have the show, the prints, pricing, bios, descriptions, and everything else squared-away at long last, but my main feeling at this point is not accomplishment, or even relief – it's exhaustion. I'm also struck by just how bare the walls of my house have suddenly become.

Oh, well. Wish us luck.

By The Way...

...there are several upcoming public tours of the Bamberger Ranch, including a public tour this Saturday, October 6th. See the ranch tour schedule for details.

Tuesday, September 18, 2007

At Work

It's purest trivia, but Margaret Bamberger sent a few photos of me at work, shooting panoramas on the ranch. It's not a perspective I've ever had before, not least because, like anyone without prehensile eyes, I can't see the back of my own head, which may be its best side.

The panorama being shot above was a complete failure, due to a wind that just would not stay gone long enough to let me shoot the whole thing before it resumed waving the near-field trees back and forth. And I waited hours. I did, however, manage to shoot that scene successfully months later: Bamberger Ranch, Jacob's Ladder Tank, David's Overlook. If you've seen the book Water from Stone, that's the scene David and his dog would have seen from their location in the sketch on page 46. Except that those bloody trees hadn't grown large enough to be in the way, back then. It must have been a much better view without them.

The panorama I was on my way to shoot in the photo above, "Bamberger Ranch, West Slope Middle Grassland, no. 2", turned out very well, I think, and after only two takes. I had to be careful to walk out into the hip-high grass in such a way that my trail would not be visible in the pano, so I moved along the fence first, then zig-zagged my way into the scene.

That panorama will be one of the four that I'll have on display (and on sale) at the Lady Bird Johnson Wildflower Center, from October 6th to November 11th. I wish I'd been able to show more than four, but those 60" X 18" archival-grade canvas prints are expensive, and four was about all I could manage. If they sell well, I'll be able to print additional works for future shows. If not, ouch ... but the walls of my house have never looked better. By the way, all of Margaret's sketches from Water from Stone, and then some, will also be on display/sale, including the aforementioned item on page 46.

Friday, September 14, 2007

Exhibition goes Bamberger-free

I've just learned that our exhibition of Bamberger Ranch-related drawings and photographs, which opens October 6th, at the LBJ Widlflower Center, will be a Bamberger-free zone on opening day, even though the core of the show is Margaret Bamberger's drawings. Unfortunately, more pressing business, in the form of Margaret's cancer treatments, has undone our best laid plans.

Nuts.

(And good luck, Margaret.)

That misfortune notwithstanding, all of the planned works, Margaret's included, will be on display on day one (and available for purchase, by the way). so the show will go on.

Thursday, September 13, 2007

Country Lifestyle article

I received my complementary copies of the October issue of Country Lifestyle magazine this afternoon. The article on the Bamberger Ranch uses eight of my photos, including five panoramas. Several of the panos are used as page background, so you can't get a good look at them, but they're there.

For the record, the pictures that include people (the Bambergers, specifically) are not mine. Those were taken by the article's author, Susan M. Sander. So, the credit should actually read something more like "most photos by Chris Johnson". That's not ideal, but it is a big improvement over the magazine's web site, which initially gave credit for the article to someone named "Beverly Burmeier" and credit for the photos to a "Scott Vallance".

Anyway, it's a nice article, and the folks at the magazine did a good job with the layout, so I'm pleased with the result. The curious among you can find the magazine at some of the larger book stores like Barnes & Noble. However, the distribution may be regional, so this may not apply to folks outside the general vicinity of Texas.

Wednesday, September 12, 2007

That's Java internationalization? Really?

In an effort to knock-off one last, major item from Qwicap's "to do" list before version 1.4 is released, I've begun trying to internationalize it. As I currently conceive the problem, this mostly involves removing from the code the error messages that Qwicap automatically adds to a web application's XHTML pages. For example, there's the message that the various numeric input retrieval methods (Qwicap.getInt, Qwicap.getDouble, etc.) add to pages when input is outside of the application-defined valid range of values: "The number must be in the range 0 to 100 (inclusive). The number '900' is not in that range." Complicating matters a bit is a standard feature of Qwicap that automatically replaces phrases like "The number" in such messages with the label of the relevant form control, as found in the web page, if there is such a label in the page.

I knew that there were internationalization features somewhere in Java (I'm using Java 1.5, by the way), but that's almost all that I knew. (I haven't made a serious effort to internationalize anything since my Macintosh programming days.) So, I worked my way through my colleagues until I found one who knew more than me on this subject, and doing some follow-on Google searches and related reading, I learned that the basic facility in Java for abstracting language-specific text from one's code is the ResourceBundle, and, typically, the PropertyResourceBundle subclass, which loads language/nation-specific text from a hierarchy of "properties" files.

So I now understood that, for a start, I needed to setup a properly named and formatted "properties" file for PropertyResourceBundle to discover and load. And the documentation for the PropertyResourceBundle class promptly referred me to the Properties class for information about character encoding issues. The main issue, it turns-out, is that the Properties class only supports one character set, ISO-8859-1. Therefore, if you need to represent any non-Latin characters, a cumbersome Unicode escape sequence must be used for each and every one of them. I find an internationalization "feature" designed without direct support for non-Latin characters tough to take seriously, and in a language like Java, which uses Unicode natively, such a design beggars belief. Of course, we all having things in our past that we wish we could go back and do differently. Maybe this is one such thing for the Java platform.

Fortunately, Java 1.5 added to the Properties class a method for loading "properties" from XML files, and XML can be represented in any character set, since the XML declaration (for example: <?xml version="1.0" encoding="UTF-8"?>) can tell an XML parser how its characters were encoded. It appeared that the problem was solved.

Of course, the problem wasn't really solved, because it turns-out that the PropertyResourceBundle class does not support XML "properties" files. The solution to that problem seemed to be creating a subclass of ResourceBundle that does support them. And creating that subclass looked straightforward at first glance - just create appropriate implementations of the abstract methods handleGetObject and getKeys, then declare victory. Unfortunately, doing so is nearly useless, because the static ResourceBundle.getBundle methods that implement the hierarchical search for language- and/or nation-specific resource bundles, and which then instantiate the list of appropriate ResourceBundle subclasses that are necessary to represent the hierarchy of potentially applicable resource bundles, have their choice of subclasses hard-coded into them. So, they can instantiate the built-in ListResourceBundle and PropertyResourceBundle classes, and nothing else.

Having come that far, I couldn't admit defeat, however, so I took the time to completely re-implement the ResourceBundle.getBundle(String, Locale, ClassLoader) method in my subclass. I thought that that would finally do the trick, but, I was wrong again, because I'd forgotten that static methods can't be overridden, they can only be hidden. Which meant that the lesser implementations of ResourceBundle.getBundle (getBundle(String) and getBundle(String, Locale)) were still invoking the original implementation of getBundle(String, Locale, ClassLoader), rather than mine. That left me feeling dumb, but creating my own implementations of those lesser getBundle methods would be a piece of a cake, and, with all of the original implementations hidden, I would finally have a subclass of ResourceBundle that looked and acted just like a normal ResourceBundle, but which supported XML "properties" files. So that's what I did (mistaking the light that was drawing ever nearer for the daylight at the end of the tunnel).

At this point, it should go without saying that that didn't work, which it didn't. My IDE almost immediately pointed-out something that I hadn't noticed in the API documenation: the two lesser getBundle methods are marked final, and therefore can't even be hidden by the methods of a subclass. For some reason the primary getBundle method isn't final, but the two little convenience methods that front-end for it, are final. Like so many other aspects of my day's dalliance with internationalization, that seems utterly pointless to me, but there it is.

The only good news at that stage was that hiding those two methods didn't really matter, since I was only going to use my subclass of ResourceBundle internally, and I know to use my implementation of the getBundle method when instantiating it. In fact, having already re-written all of the hard parts of the ResourceBundle class well enough for my purposes, I didn't even need to subclass ResourceBundle anymore; I could pretty much just remove the "extends ResourceBundle" phrase from my class' declaration and be done with it.

On the other hand, the main reasons for not implementing my own resource scheme from scratch at the beginning were (1) the belief that by using the familiar mechanism represented by the ResourceBundle class, other developers would have an easier time understanding my code, if the need ever arose, and (2) the hope that somewhere under all that rubbish lay a core of undiscovered, but wonderful, internationalization functionality, from which my code would benefit. There's some sense to the former concern, but the latter appears to be utterly groundless; if there is anything wonderful below, I haven't found it, and I don't see anywhere left for it to hide.

The niftiest feature associated with using "properties" files for internationalization that I'm aware of, is that the internationalized text can contain MessageFormat patterns. However, that feature is orthogonal to the Properties and ResourceBundle classes, which make no use of MessageFormat, and therefore leave it as an exercise to the developer to make his/her MessageFormat patterns do anything.

By the way, the documentation for the Properties class says of its loadFromXML method and the XML files that it loads: "the system URI (http://java.sun.com/dtd/properties.dtd) is not accessed when exporting or importing properties; it merely serves as a string to uniquely identify the DTD". This turns out to be somewhere between "misleading" and "wrong"; either that DTD really is accessed, or a local copy of it is used instead, because the rules in that DTD are enforced when loadFromXML reads XML. Which makes the XML support in the Properties class useless for my purpose, because the strings that Qwicap needs to make internationalizable frequently contain elements of XHTML markup. Those XHTML elements are well-formed (in the simple sense that any start tags are matched by corresponding end tags), so they would pose no problems for an XML parser that wasn't trying to enforce the rules in a DTD, but, sadly, that is not the case here.

Qwicap's XML engine made implementing my own support for XML "properties" files a trivial matter, but the end result of doing so was that, of the three Java classes that appear to be the cornerstones of Java of internationalization (ResourceBundle, Properties, and MessageFormat), I had to re-implement two of them to get an internationalization capability that was useful to my application.

Maybe my requirements are unusual, but they boil down to nothing more than supporting encodings other than the obviously limited ISO-8859-1 for my application's internationalized text, and needing to include XML (specifically XHTML) elements within some of that text. Neither requirement strikes me as remarkable individually, or in combination.

I'm new to Java internationalization, so it's easy to believe I'm missing something. Please set me straight if I am. If I'm not, put me down as lightly stunned by the substantially roll-your-own character of the Java platform's internationalization "solution".

Friday, September 7, 2007

Shooting Perseids in Armadillo Central

I went out to the Bamberger Ranch to do a bit of Perseid watching—and, with luck, photography—shortly after midnight on August 12th. Unfortunately, the peak of the shower was a day later, but on the plus side, the conditions were perfect when I went out, and the conditions for the peak were forecast to be partly cloudy.

Wanting a picturesque old windmill to include in the photos, and reasoning that the highest point on the ranch had to be a good vantage point, I headed-up to the area of the ranch known as the "red pens". As I bumped along the gravel road leading up there, I was surprised to be delayed by traffic. It was dark, squat, short, and moving at about one mile per hour. I could only see its back end. As it walked, there were flashes of light alternating right and left as the headlights reflected off of the light-colored pads of its feet. I couldn't figure-out what it was, but it plainly didn't consider pickup trucks to be among its natural enemies, and deference was due, since I was the one trespassing on its home (the approvals for my visit from the ranch staff, notwithstanding). Our encounter lasted several minutes before the critter veered off onto a trail through the several-foot-tall grass alongside the road. As it turned and vanished into the grass, I finally realized what I'd encountered: a porcupine. Somewhere in the back of my head I knew that they lived in these parts, but this was the first time I'd ever seen one.

Once the traffic let-up, I completed my journey to the windmill and began setting up my gear: camera, cable release, tripod, and a cheap, folding lounge chair that I'd acquired earlier in the day. I'd chosen a spot out in the grass that silhouetted the windmill against a slightly illuminated patch of sky, just to make sure that it showed-up clearly in the photos. With an f1.8, 20mm lens focused on infinity, and the camera set for 30 second, ISO 400 exposures, I locked-down the shutter release button on my cable release, and let the camera take back-to-back raw exposures for the next three hours, when the battery finally gave-out.

During that time, I laid out flat on the cheap lounge chair, relaxed, and did my best to watch the whole sky for meteors. The night was splendidly quiet, in a way that is still a little surprising to this city boy. But I hadn't picked that spot for its quiet, I had picked that spot (leaving aside the windmill for a moment) in the hope that the population of rio grande leopard frogs living in the circular concrete watering trough nearby would sing while I counted meteors. As I occasionally walked back to my truck for one thing or another, I could see them piled-up on the rebar cage that protects the float valve which is the center of their world, both literally and figuratively. I could also see them scattered here and there on the concrete lip of the trough, and floating at the surface of the water. I worried at first that I might frighten them all back into the water, but most of them just went about their regular business of sitting very still and staring at things. That regular business should also have included mating, and the prelude to that should have been singing, but apart from one tentative grunt, they were a complete disappointment. Maybe that bunch of frogs never does much singing; when your world is only about six feet in diameter, you may not need to sing in order to find a mate; you may not need to do anything at all.

One of those Rio Grande Leopard Frogs from a previous visit to the windmill

Though the frogs were a let-down, something out in the thick grass around me was making sounds from time to time, and it wasn't the crickets. No, this was something that made a sort of muted snort from time to time, a bit like something clearing its nose. The snorts always came from different locations, yet there was no sound of movement through the grass in-between snorts. It was a pleasant little mystery as I counted meteors and the camera clicked away the hours. In time, however, there was a snort from only about three feet away to one side, near where my camera bag sat, and the tripod was setup. That, I thought, ought to be something I can investigate, and ought to investigate before it blunders into the camera equipment. With a red-light flashlight, I illuminated the grass over on that side and saw nothing, but I soon noticed that at the foot of my lounge chair, there was a large armadillo nosing its way through the thick grass. Amazingly, to me, its progress through the grass was silent. Apart from the occasional snorts that I'd been listening to all night, it didn't make a sound. My armored acquaintance gave my chair a quick sniff, decided it was neither friend, nor foe, nor dinner, and continued on its way, seemingly completely indifferent to my presence. Apart from wishing that I'd had the foresight to stop at the grocery store and pickup a box of armadillo treats before heading out to the ranch, I was enormously pleased to have not just seen, but more-or-less met an armadillo – a species that most of my fellow Texans and I encounter exclusively as road kill.

It must be armadillo central up there, because variations on that encounter continued. In one case, I found an armadillo working the grass under the lounge chair I was laying on; in the red light of my flashlight, I saw it through the cheap, transparent vinyl of the chair. It looked up, gave the vinyl a sniff, then silently sauntered away into the grass. Before I gave up meteor watching that night, there were a total of four armadillo visitations.

But what of the meteors? I counted about 80 in the three plus hours before the camera's battery finally gave-out. I was dead tired by that time, but might have changed the battery and continued, had I not found that the lens had completely fogged-up with dew over the course of the previous hours. Fortunately, it turned out that the dew only ruined the last hour of photos, and I did catch a few meteors in the preceding time. I have yet to take my definitive meteor picture, but I did add one more photo to my tiny collection of almost-acceptable meteor shots, as you can see below. Click to see the larger version of the image; theses almost-acceptable meteors don't put on enough of a show to look good in thumbnails.