• Adjusting the Rangefinder on a Seagull 203-I

    I recently got a Seagull 203-I, a Chinese-made medium format folding camera with a coupled rangefinder. I haven’t seen results out of it yet, but I’m excited to use it. It takes a special occasion to get me out of the house with a camera larger than jacket pocket size, so something that just barely crams into a men’s jeans butt pocket (ymmv) and offers some focus assurance is a great combo for me.

    Of course, that rangefinder won’t help me to nail focus if it’s not adjusted properly. I didn’t find existing instructions online for setting the horizontal alignment of a Seagull 203 rangefinder, but with no other option I managed to figure it out myself, so here’s a brief account of how I did it. Again, I’m working with a Seagull 203-I, a later model with a flash hotshoe and a shutter without EV coupling. Seagull 203 cameras of one stripe or another seem to have been made from about the 1960’s into the 1990’s, but I haven’t heard of any particular changes to the rangefinder coupling during that time, so odds are this should also work for other variants.

    Open the folding shutter door, and look at the camera straight-on below the shutter apparatus. You should see a cylindrical flathead screw. As you turn the focus wheel, a specially shaped side of it pushes that screw more or less; I’m not a mechanical engineer, but I believe this arrangement makes the focus wheel a cam, and the screw a cam follower. A spring pulls up the lever the screw is attached to, so that it properly follows the cam. The level that’s moved by the cam follower screw pushes down another lever at a right angle to it. This lever, which runs from about the back end of the shutter into the camera body, is part of additional linkages that transmit that motion to the rangefinder mirror.

    OK, so that’s roughly how it works, let’s get down to aligning. Set the focus to infinity and look through the rangefinder at something very far away. If you’re reading this, then probably the double-image isn’t quite lined up. Now look at that screw again and see if you notice anything. Perhaps you noticed an irregularly shaped collar around the base of the screwhead? That’s right, fire up the old Xzibit memes, because your Seagull heard you loved cams, and got you a cam for your cam follower. Adjust that screw (a *tiny* amount) and that collar will nudge the lever up or down a smidge in relation to the cam follower screw head. For me, turning the screw a bit counter-clockwise nudged the ghost image to the left.

    That’s it! I hope this helped. A couple notes here at the end, though:

    • That screw only adjusts the horizontal alignment. The vertical alignment of my rangefinder is also a bit off, but not so much that I feel like removing the top plate to deal with it.
    • If you adjust your rangefinder, use it properly, and still end up with out-of-focus pictures, your problem may be with your lens. Basically, that it’s not actually focused to infinity when the focus wheel says it is. The process to fix this is called collimating the lens.
  • How to fix “This Apple ID is only valid for use in the U.S. Store”

    While googling a Japanese musician recently, I followed an Apple Music link, which opened the Music app on my iPad with this message:

    Item Not Available: The item you've requested is not currently available in the U.S. Store, but it is available in the Japanese Store. Tap Change Store to view this item.​
    Item Not Available: The item you’ve requested is not currently available in the U.S. Store, but it is available in the Japanese Store. Tap Change Store to view this item.

    This dialog makes the Change Store option seem pretty innocent, and you might assume (like I did) that changing back to your home store would be easy and obvious.

    But I found the iOS/iPadOS Music app was “stuck” in the Japanese store after this. My “Browse” suggestions were all from that store, and when I tried to actually play any music in the app, I got this message:

    This​ Apple ID is only valid for use in the U.S. Store.
    This Apple ID is only valid for use in the U.S. Store.

    At this point the problem is that if you go searching for how to change what iTunes / App / Apple Music store you are using, all of the results are long, inconvenient processes that involve cancelling all of your subscriptions and backing up all of your purchased media. If you are permanently emmigrating from one country to another and want your account associated with your new home nation’s store, then you really do have to do all that stuff. But if, like I did, you just ended up stuck in the wrong store through viewing an artist or album from a different country, then you haven’t actually changed what country your Apple ID is connected to, so you don’t have to do all of that!

    The Fix

    In short: you just have to sign out of the App Store in the iOS Settings app. When you sign back in, it will use the correct stores for whatever country your Apple ID is associated with. To do this, open Settings and select your Apple ID settings. Then tap “Media & Purchases”:

    Media & Purchases

    Rather than opening a panel, that will just open a small dialog box that includes a Sign Out option. Tap Sign Out:

    Sign Out

    It will ask if you’re sure you want to do this—you are. Note that this only signs your account out of the App Store and the media stores; it doesn’t affect anything else on your device using your Apple ID, so it won’t force you to later reload your entire iCloud Photo Library, for example.

    Now tap Media & Purchases again. This time it will open a dialog asking if you want to setup Media & Purchases using the Apple ID you’re otherwise using on your device.

    Just tap “Continue”, and you’re done! When you sign back in, you’ll be setup to use the stores for whatever country your Apple ID is associated with. I quit the Music app to force it to reload, but I don’t know if that’s necessary. When I opened it again, I was back (for better and for worse) in the U.S. store, and I was once again able to play my music.

    I was very relieved that I didn’t have to go through the entire “so you’re migrating to a new country” process outlined in the help documents, but this still seems like a lot of completely unnecessary stress. If Apple wants to let people switch stores easily in order to view music from other countries, they need to have an equally easy and obvious way to switch back. Or better yet, just automatically switch users back to their home country rather that displaying the useless and misleading “This Apple ID is only valid for use in the U.S. Store” message.

  • KickLogstash.sh: 7 Lines to Restart Logstash

    It might well be my naive, beginner’s implementation of it, but it sure seems like Logstash is pretty easy to confuse. Elasticsearch temporarily unavailable? Hang. Some weird formatting sneaks in? Hang. Some as-yet-undiscovered circumstance that causes java to eat all your memory? Hang. And each time it hangs, Logstash becomes unresponsive, never recovering. So for the moment, I’ve given up, and I’m resorting to a dumb, sledgehammer-like solution:

    #! /bin/sh
    FILELENGTH=`stat --format=%s /var/log/logstash/logstash.err`
    if [ $FILELENGTH != "0" ]
            killall -9 -u logstash
            service logstash restart
            logger Logstash Killed and Restarted Due To Non-Zero Error Log

    Again, I’ve only had about a week of actually sending a lot of input to Logstash, but so far, there’s always something in the error log when it hangs, and there’s rarely anything in there when things are going well. So this barely-a-script checks the size of the error log, and if it’s non-zero, it SIGKILLs every process belonging to the logstash user, and then tries to start Logstash. The restart part assumes you have a Logstash script in init.d, which I certainly hope will be included as part of a proper .deb distribution of Logstash someday soon. I run it every five minutes with cron:

    */5 * * * * /etc/logstash/kick_logstash.sh
  • Coping With EXIF Rotation Problems

    At Knowledge Architecture, we may not operate at the scale of Facebook or Flickr, but Synthesis sees enough image uploads that we’ve run into some pretty strange image rotation problems now and then. I’ve spend a lot of time with the issue, and while I’m not naive enough to declare victory over something as devilish as EXIF rotation gremlins, we’ve got an update rolling out this week that will at least avoid the species we’ve seen so far.

    First, a little background, and we’ll imagine a portrait-orientation photo of the Sutro Tower as our example image. Digital images are stored in a given rotation, which generally corresponds to the default rotation of the image sensor—so our Sutro Tower photo is probably sideways on disk. If we open the image in any half-decent viewer, though, the tower will be right-side up because most digital cameras annotate image files using the EXIF Orientation tag. That’s used by most image-viewing things to recognize situations where image may be stored on disk like this, but when displayed it should be (say) flipped, and rotated 90° to look like that.

    It’s gotten better, but support for that Orientation value isn’t perfect. So when someone uploads an image to Synthesis, we look for the Orientation EXIF field, rotate the image data itself so that it’s stored the way it should be displayed, and then we remove the Orientation field, because its instruction to rotate the image on display is no longer needed.

    The problem we’ve run into is that some image editors apparently don’t update EXIF data properly; they rotate the image data itself (so the Sutro Tower is right-side up), but leave the Orientation flag in place. So our uploading process would dutifullly rotate the image one more time, and the tower would end up pointing sideways. It was a frustrating situation.

    Luckily, those EXIF-unaware image editors seem to leave all the other EXIF data unchanged, too. So what our solution does is compare the so-called “EXIF Width” and “EXIF Height” field values to the width and height of the image data on disk. If it looks like the image has already been rotated, we simply remove the Orientation field.

    So here’s the important part of the code. In short, we:

    • calculate the ratio of actual image width to height, and the ratio of EXIF-reported height to width,
    • round them both to one decimal place (to account for resized images subtly changing that ratio),
    • and check to see if one equals the other. If so, the image has been rotated already.

    This is C# but it’s mostly math so it should be easy enough to port to whatever language you’re using. Not shown is fetching the orientation, exifWidth, and exifHeight values; they’re EXIF fields 0x0112, 0xa002 and 0xa003, respectively. I found this list of EXIF tags very helpful during this whole process.

    // Useless data check (this check doesn't work on squares)
    if (exifWidth > 0 && exifHeight > 0 && exifWidth != exifHeight)
        // To see if the bits were rotated, we calculate a height/width ratio, because 
        // we might be dealing with a resized image. We round, becuase resizing might 
        // slightly change this ratio
        decimal actualRatio = Math.Round(
    		((decimal)img.Height / (decimal)img.Width)
    		, 1); // height / width
        decimal exifRatio = Math.Round(
    		((decimal)exifWidth / (decimal)exifHeight)
    		, 1);  // width / height
        if ( orientation >= 5 && actualRatio == exifRatio )
            // SO, if the orientation is rotate90 or rotate270 (with or without flip),
            // and the image seems to have already been rotated 90 or 270 (the width 
    	// is now the height), we're going to assume that some bad software rotated 
    	// the pixels and never removed the orientation flag. In such a case, we'll
    	// trust the lousy software's rotation, and remove the flag.
            orientationPropItem.Value = new byte[1] { 1 };
            // We return true because in our implementation, we just need to know if the 
    	// image file we're storing has changed at all, whether that means rotation 
    	// or just removing an EXIF value.
            return true;
  • What I Like Is Looking At My Phone

    The other day I was thinking about the dawning of The Age of Smart Watches, and trying to answer a skeptical friend’s “why?” Why do people think they want such a thing?  Or, at least, why do companies think that people want such a thing? I ran through the usual suspects: the wrist is a convenient place to put always-on health sensors, it’s a place where (unlike your face) it’s already socially acceptable to wear some kind of gadget, it can give you feedback (or directions) without requiring you to wear headphones or look at a screen, etc.

    I thought my big finish would win her over: smart watches will help people to stop being Phone Jerks. People know it’s obnoxious to keeping pulling out their phone to check on some alert, you see, and a smart watch will let them deal with those interruptions quickly and unobtrusively! Years from now we’ll look back on this whole embarrassing Age of Smart Phones as just an impolite blip in history.

    She didn’t buy it, though, and rightly so. And the reason why is the same reason why I’m so happy that my wife and I never bought a video baby monitor.

    A Brief Digression On Video Baby Monitors

    If you haven’t looked into the list of accessories considered near-mandatory for baby-raising lately, you might be surprised at how common a home infant sleep surveillance setup is. The only downsides usually mentioned are cost, complexity/fiddliness, and the potential for some hacker to spy on your little one. The advantage boils down to: you can quickly and silently verify that your baby is still breathing! That’s no joke, and in addition to solving those paranoid “…a little too quiet…” moments, this benefit is even an important part of some sleep training schemes.

    Fortunately, we found some advice online that described the greatest downside of a video monitor: that you will never be able to look away. What’s billed as a way to quickly soothe those sudden, irrational worries instead becomes its own necessity; as soon as the way you know your baby is safe is by watching her on a video screen, you must always watch your baby on a video screen. Of course, new parents love to just look at their infants. Once you have one (a video monitor, that is), I’m sure that most of the time it just feels nice, and comforting, to watch a live stream of your infant sleeping.

    Remember BlackBerry?

    If that example feels more tangential than parallel, consider that eons ago, Blackberry devices, Palm Pilots, and other proto-smartphones were the heroes we were counting on to liberate us from our desktop email clients—go ahead, leave at 5:00 tonight, be with your family, and if something important comes up, you’ll know! It didn’t take long for experience to complicate such promises; a cursory Google turns up warnings as early as 2001 that, “your work hours suddenly are extended from finite to infinite.

    Just as we were right to be skeptical of the benefits of parental voyeurism and email gadgets, we should be skeptical of claims that smart watches will do anything but increase the amount of time we spend staring at screens. Because the truth is, we like playing with our gadgets. I don’t have notifications turned on for emails, and I generally keep clear of Facebook, but I have my Twitter feed crafted to ensure that whenever I need to look at my phone for a moment, there’s something waiting for me. Sure, I enjoy the thinkfluencers and whatever else, but if Twitter closed tomorrow I’d just find something else, because what I like is looking at my phone.

  • Traveling With a Baby in Italy

    Several months ago, my wife and I completed a two-week trip to Italy with our then seven month-old son, Felix, and for the most part, it was great! Before we left, though, we looked around for guidance and didn’t find much that lined up with our idea of a vacation: a “last” trip before Felix could walk (let alone express an opinion about our itinerary), where we’d take a few day trips, walk a lot, and experience life in a new city or two in addition to checking off a few postcard sites on our lists.

    So I wanted to post about some of what worked, and what didn’t work, for us. My TL;DR advice is that you should absolutely travel with your infant, too—I treasure my memories of this trip more each day. That said, every baby (and every family) is different, so I hope my notes will help you to draw your own conclusions.

    A quick itinerary outline:

    • We flew in to Florence, taking the tourist bus in to the city.  We stayed in an AirBnB for 10 days.
    • We went to Assisi for one night—and we actually would’ve liked more time there.  We stayed outside of the city, which was kind of a pain: we needed a ride from the train station, which my Italian (and our host’s English) was only barely good enough to arrange, and of course there was no infant car seat, which I guess is legal (?) but obviously isn’t ideal. Stay in the old city itself, and you can take a tourist bus to and from the train station.
    • We stayed in Lucca for one night, spur of the moment, mostly because the focaccia place I wanted to go to was closed on the day we arrived. No, I’m not kidding, and yes, Forno a Vapore Amedeo Giusti was worth it.
    • We took a day trip to Venice: the earliest train up in the morning, and the last train back at night.
    • Those trips were all during our ten days in Florence.  So we double-paid for the Assisi and Lucca overnights, but staying that long got us a discount, and it was great to be able to leave most of our stuff at “home” for those short trips.
    • Then we took the train down to Rome and stayed in Testaccio (a short walk from the Roma Ostiense train station) for three nights before flying home from Fiumicino.  Testaccio is not a short walk from the Pantheon or St. Peters, but there are buses, and the walk to the Forum / Palatine Hill / Colosseum area isn’t so bad.  Testaccio is very close to the Pyrimide metro stop, so you have convenient access to commuter trains to the airport and to Ostia Antica (which was another highlight of the trip).


    With that out of the way, on to the details:

    • As far as we saw, yes, Italians love babies. Ergo / Baby Bjorn -style carriers are relatively rare there, so a baby in one of those is extra adorable (and a little amusing), especially when a man is wearing it.
    • Babies are a great low-pressure conversation starter, and I had lots of fun using my pidgin Italian to answer questions about how old Felix was, where we were from, etc, etc.
    • The flights didn’t go all that well for us, because he didn’t sleep that much.  But we’re still glad that, when we checked in for the intercontinental flights, we asked for a bulkhead row with a little crib.  This is free, and if nothing else it gives you some extra room and place to put your baby even if she’s not sleeping, so do it!
    • We didn’t bring a stroller, and we didn’t regret it.  Spaces are tight, roads are bumpy, and you can split carrying duties.  Our baby was already used to falling asleep in our Ergo.
    • Part of what made 7 months an ideal age is that our son was still breastfeeding, almost exclusively.  So other than the occasional banana, we didn’t worry about finding appropriate food for him. Some reading I found online made me a little worried about how Italians would react to public nursing, but everyone was friendly and accommodating about it. My wife fed Felix in church squares, art galleries, ancient ruins, restaurants, trains, alleyways, etc, etc, etc.
    • Speaking of not being overly concerned with modesty, we didn’t find a whole lot changing tables in bathrooms, so that list also describes places where we changed Felix. The worst was in a traincar entryway (between compartments) on the way home from Venice, which we later learned was unnecessary: the bathrooms in the first class car at the head of the train has a changing table, and yes, 2nd class babies can still use it.
    • Although “everyone was cool with the baby” is the general theme, we were actually turned away from a restaurant. I can’t say I blame them, but after that we really scaled back our food ambitions. We tried to eat our special meals at lunch, when restaurants were a little emptier and a little more understanding.  Felix was just starting to get hard to handle at meals, though, so even that didn’t help much. In retrospect, we might have been better off just feeding him some real food to keep him happy and occupied—we didn’t do that because we were taking the injunctions to introduce foods slowly and selectively pretty seriously.  Two of our lunches we basically ate in shifts, alternating “hang outside with the baby” duty with “eating lunch”.  I still can’t believe that the wonderful people at Pallotta, in Assisi, not only put up with us, but were also incredibly kind about it.  Their food was one of the highlights of our trip.
    • Given that, very few of our dinners were in restaurants.  Instead, we got food to-go; cobbled together lunch-style meals of bread, cheese, and produce; and cooked at home.  We were definitely glad that we rented a place with a kitchen.
    • We did not rent a place with a crib, and that was OK; instead, we made him a little nest out of pillows and blankets. He didn’t sleep all that well, but then again that wasn’t unusual for him. In Assisi we had to all share a bed, which wasn’t a restful night; in Lucca he slept on the second of two beds, walled in by pillows; and in Rome (in Testaccio) they had a pack and play -style crib.
    • Our place in Florence was nice, but didn’t really have a great hanging-out area. In some ways, maybe that was a beneficial extra nudge to get out of the house. On the other hand, most of our nights we spent “in”, so in hindsight maybe we would’ve spent a little more for a balcony with a beautiful view…
    • We cloth diaper at home, but bought disposables (pannolini—”little cloths”) while we were there.  Our AirBnB had a (slow) washing machine, but come on, it’s a vacation!
    • We packed very light and didn’t regret it. For Felix, we had one warm and one cool sleep sack, a quilt, and a few toys, in addition to a few outfits.  We brought a breast pump and a bottle but I don’t think we ever used them.
    • Most of our trip was walking around, which was tiring, but left us free to stop for food / diapers / nursing / playtime at our leisure.  Honestly, our museum visits were more exhausting than the wandering.
    • It was great, but it was tiring, and we often slept poorly, so we had to preserve our sanity with the occasional solo expedition.  Often I’d leave early in the morning to walk around with Felix while my wife caught up on the sleep he’d denied her the night before.

    I’ll leave it at that, but you’re welcome to comment if you have any questions I might be able to answer.  It was a challenging trip, but also an incredibly rewarding one, and I can already tell that I won’t remember the hard parts.  If you’re on the fence about traveling with a ~7 month-old, stop reading and go book some tickets!

  • NSRangeMake

    Maybe this is common and maybe it’s not, but in the course of my work writing Objective-C for iOS, I end up using CGRectMake()—to make, yes, a CGRect—pretty frequently, but I only rarely need to build an NSRange.  So following the CGRectMake pattern, I inevitably start typing “NSRangeMake” and along the way the only method completion I get is for NSRangeFromString().  A few befuddled minutes later, I realize that what I’m looking for is NSMakeRange(), and then I can go back to slowly forgetting about that reversed word order until I run in to the same problem a month or two later.  Since I really my start programming in PHP, this kind of thing shouldn’t throw me, but it does.

    So on the off chance that this happens to you, too, here you go:

    #define NSRangeMake(location, length) NSMakeRange(location, length)

    I wouldn’t recommend actually using NSRangeMake() in code anywhere, but this will at least give you a little reminder.

  • SQL Azure, Management Studio 2008, and the ‘sys.configurations’ error

    Here you are, just trying to get some work done by connecting to a SQL Azure instance using Microsoft SQL Server Management Studio (hereafter “SSMS”) 2008. But instead of a connection, all you get is a line of Microsoft free verse:

    Invalid object name 'sys.configurations'. (Microsoft SQL Server, Error: 208)

    Googling around for help returns several instances of the same solution, that has you start by clicking the “New Query” button.  With this workaround, however, you lose the helpful hierarchical DB browser in the left pane of the window.

    A better solution is to install (deep breath first) Microsoft SQL Server Server 2008 R2 RTM – Management Studio Express.  MSSSR2RMSE works with SQL Azure, the only catch is that if you choose the “Upgrade” option in the installer, your SSMS won’t be… upgraded.  Instead, you want the “New Installation or Add Features” option.  From there, you just accept the legalese, make sure “Management Tools – Basic” is selected (which it should be by default), decide whether or not to allow diagnostic info to be sent, and then leave the installer to its work.  When it’s done, you’ll find that your old SSMS has been updated to 2008 R2, no need to create new shortcuts, etc.

    I should note that I followed the “upgrade” path first, which did seem to be doing something, to the point of even requiring a restart.  If you follow these instructions to skip straight to the “New Installation” and things aren’t working, try running the “upgrade”.  If it looks like the upgrade procedure is a necessary first step, please let me know, and I’ll update this post.

  • When Your DataMember Custom Property Names Aren’t Working

    Let’s say you’re writing a WCF REST service, and in proper C# fashion, your object’s properties start with a capital letter. Then your service is being consumed by Objective-C code or javascript, which call for lowercase. Since WCF uses the DataContractJsonSerializer, you can set a different name for the property to serialize to:

        public class MyObject
            [DataMember(Name = "name")]
            public string ObjectName { get; set; }

    But for some reason, it’s not working; you still end up with “ObjectName: ‘Yadda’”. I ran into this issue, and the problem turned out to be a missing line of boilerplate:

    public class MyObject
            [DataMember(Name = "name")]
            public string ObjectName { get; set; }

    As least as far as I’ve seen, a WCF REST service can chug along just fine without that DataContract parameter in most respects, but if you leave it out, you forego being able to set custom property names. Hope this saved you a headache!