Saturday, October 31, 2009

New M8 Rail Cars A Year Late In Delivery

It’s the question I am asked almost every day: “When are the new rail cars coming?” The answer: “Later than we’d thought”.

Yes, the new M8 rail cars, which lawmakers authorized in 2005 and we hoped would be in service late this year, won’t be in service until late 2010… a year later than planned.

We on the CT Rail Commuter Council (a state-appointed watchdog group) have been tracking the progress of the M8’s from engineering design to focus groups on the interiors to initial “crush tests” (which they failed). Every month we ask if there are any delays, and CDOT says “no, we’re right on track”.

Initially the plan was to have a set of prototype “pilot” cars delivered by “late 2008”. (Look it up. It’s still on the CDOT website!) Those cars would then undergo testing for four to six months while production continued on the “revenue” cars, which would be held out of service until the tests were complete. That probably meant we’d be able to ride in the new M8’s by April or May of 2010, about 16 or 17 months later than planned.

But the timeline is now slipping further.

At our September Commuter Council meeting, CDOT Commissioner said that the M8’s manufacturer, Kawasaki, had been having problems with suppliers delivering steel later than planned. And their sub-contractors (who account for 60% of the cars) were also delayed.

Commissioner Marie also said that the planned delivery schedule of ten cars per month was extremely ambitious as railcar makers have a “deplorable record” of keeping their production promises. Marie should know, having worked for Bombardier in years past.

But wait… it gets even worse. By the time the Commuter Council met in October, this time with Metro-North President Howard Permut, the delays had been stretched. Permut said it would be months before even the test cars arrive, meaning the four to six months of testing would delay putting the cars in service until “late 2010”.

And that assumes that everything goes well and no serious problems are found during the testing!

Those tests are crucial as we’re spending $713 million on the first 300 cars. These cars should last 30 years, if they live up to their warranty. That’s why the first prototypes have to be run into the ground until something breaks.
And if some component does fail, Kawasaki will have to go back to retrofit a “fix” onto all the cars in production, both in Kobe Japan and Lincoln Nebraska.

Mind you, there is some good news in all of this mess…

First, Kawasaki is paying millions of dollars in penalties for the delays. And second, the plans for a fare hike to pay for the new cars is also delayed.

We commuters are a patient bunch. We’ve waited a decade beyond when our old fleet should have been retired, and I guess we can wait a few more months.

But what we cannot wait for any longer is candor and honesty from CDOT, an agency whose credibility is in tatters.

The long needed New Haven Railyard facility morphed from a $300 million project in 2005 to $1.2 billion in 2008. Governor Rell was incredulous and ordered a $630,000 study of the ballooning costs.

A rework of the plan brought the cost down to $850 million. But just opened bids for Phase One of the project, expected to cost $261 million, came in at $125 million!

It’s a long way from $300 million to $1.3 billion and from $261 million to $125 million. And along the way people start wondering if anyone has a clue about estimating costs.

All we need are honest answers, not excuses. Get the new M8 prototypes, start testing them and please, be honest about any further delays.

Saturday, October 17, 2009

Leaves vs Loco's: "Slip Sliding Away"

It sounds like a question on a kid’s quiz show: “How do you stop a train?”
A) Hail it like a cab? B) Pull the emergency brake? C) Put wet leaves on the track?

If you chose “C”, you were correct… and you must be a regular commuter on Metro-North.

This is the time of year that tries train engineers’ souls and commuters’ patience. On a single day last fall, 60 rush-hour trains were delayed by “slippery rails” when wet leaves caused trains to “slip-slide” on their usually solid tracks.

You may not realize it, but the flanged wheel of a train contacts the rail only on a surface area the size of a dime. That’s why trains can move so smoothly with minimal power… riding a small, but firm area of friction.

But when the leaves fall and get wet, they are ground into one of the slipperiest substances known to man, a compound called pectin. As the train rolls along, its braking computer senses the slip and tries to apply the disc brakes, which eventually scrape off the gelatinous slime.

But often the brakes are applied so hard that a locked wheel is ground against the track, creating a flat spot on the usually round surface. In years past these flat wheel issues have taken 25% of cars out of service for regrinding. That means not enough cars, which means standees.

Sophisticated train computers don’t like it when they think the train can’t stop so, on the new M7 cars running in Westchester county, the railroad had to reprogram the safety systems to reassure them the train wasn’t out of control and didn’t need emergency braking.

Worse yet, on some lines the slippery leaves can virtually leave the trains unable to move. Case in point, the Danbury branch line which is an almost continual up-hill climb from Norwalk to “The Hat City”, 397 feet above sea level. On this branch, diesel locomotive-pulled trains often can’t stop on hills at stations like Cannondale, so on some days they skip such stops and make a running start for the steeper climbs.

On an MU (multiple-unit) mainline train, all cars are locomotives, spreading out the traction-power the full length of the train. But on a branch line, a single Genesis locomotive weighing 120+ tons has only eight wheels touching the track, seeking enough traction to pull a fully loaded eight car train. That means eight dime-sized points of friction for a multi-ton load.

Sometimes the solution is as simple as sand dropped from special hoppers on the train just in front of the drive-wheels. The resulting friction gets the train going or helps it stop.

Mind you, this is a problem for railroads worldwide, not just here in the northeast.

Of late, Metro-North has brought in heavier armament… a specially designed car dubbed “Water World” equipped with high pressure hoses that blast the tracks free of the gooey mess.

They’re also experimenting with chemical sprays. And one inventor in the UK is even proposing to zap the goo off the rails with lasers!

So in the fall as we appreciate the gorgeous foliage, remember the words of Paul Simon during your next ride on Metro-North: “Slip sliding away, slip sliding away. You know the nearer your destination, the more you’re slip sliding away.”

Thursday, October 8, 2009

Escaping MaxL quotes


How do I quote thee, let me count the ways

As I explore the terra incognita that is ODI/Oracle EPM, I've come up with an overloading technique that makes ODI's Essbase dimension build and data load functionality redundant.
How, you ask, has yr. obdnt. svnt. managed to do this?
In a single word, MaxL.  Truly the Most awesome excellent Language ever.
I'll write about how not to use the Essbase Knowledge Module in ODI, and why you shouldn't,  in my next blog (this is generally known as a tease), but first a brief dive/ investigation/rant into how MaxL handles quotes natively and when used with parameter variables as they are heavily used in the aforementioned technique.
I am afraid in this case MaxL stands for Most awful excerable Language ever.  

A foolish consistency is the hobgoblin of little minds

Was Emerson thinking about the Oracle EPM space when he wrote this famous line?  Logic says “No”, but Essbase is so awesome it’s maybe just possible?  If true, we might deduce that quote handling in MaxL is either non-foolish or, more flatteringly, the province of great minds, because it surely isn't consistent. 
If you want to get all smart on me and read the documentation, the best place to look in the Tech Ref is in Quoting and Special Characters Rules for MaxL Shell.

I think I have eluded consistency pretty well

Let’s take a little trip through the land of inconsistency with a sample dimension build statement.

import database Cameron.Basic dimensions
    connect as 'sa' identified by "password"
    using server rules_file hMkt
    preserve all data on error write to
    "c:\\temp\\hDimBuild_Mkt.err" ;

Did you catch (you’re not paying the least bit of attention if you didn’t) all the different ways to handle (or not) quotes? 
Anyone who writes code like the above doesn't stay awake at night worrying about the quality of his work; I envy him.  :)

Hardcoding and quotes

So let’s try to get to some kind of standard way to handle quotes.
The statements:
spool stderr on to 'c:\temp\DimBuild_Mkt.err' ; 
and
spool stderr on to c:\temp\DimBuild_Mkt.err ;
both work.  Why?  What is the point of the quotes?  Why even bother with them?

Maybe there is a point

Well, if you foolishly put a space instead of an underscore and end up with this in your code:
spool stderr on to c:\temp\DimBuild Mkt.err ;
When you run the script MaxL drops all of the backslashes and returns this to the console:
MAXL> spool stderr on to c:tempDimBuild Mkt.err ;
      essmsh error: Parse error near Mkt.err
That is a giant frosty, heavy, highly breakable mug of Not Good. 

The rule (not the last, there will be a summary and a short quiz at the end)

So fix strings by enclosing them in quotes.  You will then get your spaces in your file name/error label/whatever.
spool stderr on to 'c:\temp\DimBuild Mkt.err' ;
As a rule, I tend to act like it's 1974, and never, ever, ever, put spaces in file names.  I think Windows (I cannot speak for *nix) now supports the real name, spaces and all, but I was scarred by Windows 95 and FAT, and still think in the back of mind about how file names used to be stored. Scary.

An addendum to the rule

Put file names in quotes.  That’s easy to understand. 
What kind of quotes do I use?  Single?  Double?  I forget.  Let’s try double quotes because that’s what I use most of the time when quoting strings.
Unfortunately, double quotes do work, but not in a way you would want:
 spool stderr on to "c:\temp\DimBuild_Mkt.err" ;
gets translated to:
tempDimbuild_Mkt.log
That file will probably get written to the same directory as your MaxL script.  Why would you want to do that?  (Anyone who ever worked with Comshare will recognize that immortal line.)
Let’s say you are addicted to double quotes – it’s what you use in other languages, you are in love with the left shift key, it just looks like perfection – whatever.  How are you going feed that double quote monkey on your back?

The problem is escaping characters

Finally, the title of the blog comes around.
Per the excerpt I took from the Tech Ref, backslashes are special characters and get escaped differently based on context (MaxL shell versus MaxL).  That means that you can (confusingly) mix and match quoting strings, single quoting strings, and double quoting strings all within a single MaxL statement and have it syntactically correct.  Bizzare, but true and shown in the first example.

Make those double quotes work

How, oh how, will you get the double quotes to work?  Of course, you will insert double backslashes, in the file path. 
spool stderr on to "c:\\temp\\DimBuild_Mkt.err" ;
Why, oh why, does it work?  The answer lies in what is the MaxL shell and what is MaxL proper (oh yes, there's a difference).
 To quote my dear friend the Tech Ref on the Use of Backslashes:
One backslash is treated as one backslash by the shell, but is ignored or treated as an escape character by MaxL. Two backslashes are treated as one backslash by the shell and MaxL.
'\ ' = \ (MaxL Shell)


'\ ' = (nothing) (MaxL)


'\\' = \\ (MaxL Shell)


'\\' = \ (MaxL)

You’d think a friend would tell you the truth

Although I enjoy reading, on a quiet Sunday afternoon, the Tech Ref from cover to cover (no, I don’t, actually), I am here to tell you an unfortunate fact. 
It’s wrong.  Often.
This statement:
One backslash is treated as one backslash by the shell, but is ignored or treated as an escape character by MaxL.
Ain’t so.  This MaxL code line:
import database Cameron.Basic dimensions
    connect as sa identified by password
    using server rules_file hMkt
    preserve all data on error write to
   'c:\temp\hDimBuild_Mkt.err' ;
works just fine. 

As does this:
import database Cameron.Basic dimensions
    connect as sa identified by password
    using server rules_file hMkt
    preserve all data on error write to
   "c:\temp\hDimBuild_Mkt.err" ;
Both statements work, and both write a dimension build error file to c:\temp\hDimBuild_Mkt.err.

I hope you’re noticing the single backslash that is supposed to resolve to nothing as the import command is part of the MaxL language. 

This bad information is there in the 9.3.1 documentation, and in the 11.1.1 release as well.  It has been wrong, I think, since MaxL was first released to a clamoring world.

Cameron’s observation on quotes

  • When you use a command that is in the MaxL shell (spool, echo, shell, and msh), enclose stings in single quotes or use double quotes but escape backslashes with another backslash.

  • When you use a command that is MaxL proper (practically everything else), enclose strings in double quotes.  Just for giggles, escape the backslash with another backslash.  Yes, that contradicts my correction above which shows that single quotes work in MaxL proper, but in a little bit you’re going to see why this isn’t so when MaxL variables are discussed.

Cameron’s first rule on quotes (there will be more)

So, must  strings always be encapsulated in double quotes?  No, but really, you should follow that rule – it’s simpler to just remember to use double quotes backslashes.
A foolish consistency?  You decide. 
Remember, login, iferror, import, define label and execute calculation work fine with single quotes, double quotes, or no quote characters at all so long as there are no spaces in the name (that isn't an issue for a calc script).  But why remember?  Just go with the “double everything” rule. 

Cameron’s second rule on quotes, in four parts

If you’re not going to follow my advice re double quotes and backslashes (you would just be the latest in a long list on a whole variety of subjects), then follow the below maxims:
If there are spaces and file paths, use either a single or double quote to encapsulate the string
1)      If in the MaxL shell, and if you have an allergy to double quotes, use single quotes and single backslashes
2)      If in the MaxL shell, and if you are allergy free to double quotes, use them, and double backslashes
3)      If MaxL and you use single quotes, use single backslashes
4)      If MaxL and you use double quotes, use double backslashes

Is the horse dead yet?

I know, I know, just because you can doesn’t mean you should, but still it’s fun.  Repeating my first example, the below code works just fine :

import database Cameron.Basic dimensions
    connect as 'sa' identified by "password"
    using server rules_file hMkt
    preserve all data on error write to
    "c:\\temp\\hDimBuild_Mkt.err" ;

Again, if you think this is acceptable, are you crazy?  And if so, what medication are you taking to make it in the “normal” world, because I want some.  J  I’m pretty convinced the normal world is anything but, so maybe you’ve got a coping mechanism I should be using.
Go on, be foolish, be consistent.  Don’t write your code like the above example.
Note that the \\ in the import actually resolves to \ because import is a MaxL command, not a MaxL shell command.

Parameters make it easier?

 Oh no they don’t.  Think back to the consistency = foolish minds bit by Emerson.  We are veering off into the so unfoolish part of the pitch it’s uncanny.
I often use positional parameters to make MaxL scripts reusuable across multiple dimensions, data files, databases, etc.  It's a powerful technique but of course it crashes headlong into the way MaxL handles quotes and backslashes.  It wouldn't be fun if it was easy, right?

Hardcoding lives!

Here’s an example of a fixed MaxL script, complete with every different combination of quoting and backslashing I could think of:
/*   
      Purpose:    Load dimension in Essbase    
      Written by: Cameron Lackpour
      Modified:   5 September 2009, intitial write
      Notes:           
*/

/*    Write errors to disk    */
spool stderr on to ‘c:\temp\DimBuild_Mkt.err’ ;
iferror "ErrorHandler" ;

/*    Log into Essbase  */
login 'essadmin' "essbase" on d630 ;
iferror 'ErrorHandler' ;

/*    Write general output to disk  */
spool stdout on to "c:\temp\DimBuild_Mkt.log" ;
iferror "ErrorHandler" ;

/*    Load dimension to Essbase     */
import database Cameron.Basic dimensions
      connect as 'sa' identified by "password"
      using server rules_file hMkt
      preserve all data on error write to
      "c:\\temp\\hDimBuild_Mkt.err" ;
iferror "ErrorHandler" ;

/*    Execute calc script     */
execute calculation 'Cameron'."Basic".MktCalc ;
iferror "ErrorHandler" ;

/*    Error handler label     */
define label 'ErrorHandler' ;

exit ;

And the inconsistencies keep on coming

Why does the \\ work in the spool stderr command?  It’s a MaxL shell command and as such \\ resolves to \\ (according to the Tech Ref) which you would think would be a big no-no in Windows except it isn’t, apparently.  Nope, it’s really resolving to \.  Arrgh. 

Don’t worry, you’re following the double quote, double backslash convention, so it’s all good.

Hardcoding is dead, long live parameter variables!

Note that I’ve hardcoded the script error, script log, user name, password, server, SQL username, SQL password, and Essbase app/db.  This means that I have to set this information in every script I have.  There has to be a better way and indeed, there is as shown below.

/*   
Purpose:    Load dimension in Essbase    
      Written by: Cameron Lackpour
      Modified:   5 September 2009, intitial write
      Notes:           
      *     Parameter variable notes:
      --    Two backslashes to properly expand the parameter variables in *all* MaxL shell or MaxL statements.
      *     Variable declaration:
      --    $1    =     Essbase username
      --    $2    =     Essbase password
      --    $3    =     Essbase server
      --    $4    =     Script log, error file, load rule, and dimension load error file,
                        e.g., DimBuild_emp.log, DimBuild_emp.err, hemp.rul, and hDimBuild_emp.err
      --    $5    =     SQL username
      --    $6    =     SQL password
      --    $7    =     Essbase application and database
*/

/*    Write errors to disk    */
spool stderr on to "c:\\temp\\DimBuild_$4.err" ;
iferror "ErrorHandler" ;

/*    Log into Essbase  */
login $1 $2 on $3 ;
iferror 'ErrorHandler' ;

/*    Write general output to disk  */
spool stdout on to "c:\\temp\\DimBuild_$4.log" ;
iferror 'ErrorHandler' ;

/*    Load dimension to Essbase     */
import database $7 dimensions
      connect as "$5" identified by "$6"
      using server rules_file h$4
      preserve all data on error write to
      "c:\\temp\\hDimBuild_$4.err" ;
iferror 'ErrorHandler' ;

/*    Execute calc script     */
execute calculation Cameron.Basic.MktCalc ;
iferror "ErrorHandler" ;

/*    Error handler label     */
define label 'ErrorHandler' ;

exit ;

The Tech Ref isn’t being foolish this time, but it is being consistent

Tokens enclosed in single quotation marks

Last time we looked at the Tech Ref re backslashes, it was somewhat challenged in the veracity department.  Not this time, because the below statement is 100% correct:
Contents within single quotation marks are preserved as literal, without variable expansion.
Example: echo '$3';
Result: $3

Tokens enclosed in double quotation marks

As is this statement:
Contents of double quotation marks are treated as a single token, and the contents are perceived as literal except that variables are expanded.
Example: spool on to "$ARBORPATH\\out.txt";
Result: MaxL Shell session is recorded to
c:\hyperion\essbase\out.txt.
In the code examples I’ve shown, this is crucial.

This:
spool stderr on to 'c:\temp\DimBuild_$4.err'
will create the file:  c:\temp\DimBuild_$4.err – this is A Bad Thing.

And this:
spool stderr on to "c:\\temp\\DimBuild_$4.err" ;
will create the file:  c:\temp\DimBuild_Mkt.err – this is A Good Thing.

Unfoolish consistency is no hobgoblin, or, we have a rule, let’s stick with it

Double quotes rule – they work with hardcoded MaxL shell and MaxL statements and they correctly expand MaxL variables (of any variety – parameters, environment, or locally defined, although I didn’t review the last two).  What’s not to like?

Just remember to escape all backslashes with another backslash and this particular wee bit of confusion is all taken care of.

Resolving this bit of MaxL inconsistency  sets the stage for my next post – using ODI with not even a hint of the Essbase Knowledge Module against Essbase. 

Is the above a hack?  I think so.  Is figuring out how MaxL, which after all, isn’t used for anything but Essbase, uses quotes and backslashes a hack?  Maybe not, but it falls under the heading of necessary.

See you next time.

Monday, October 5, 2009

Are Some Rail Fares Unfairly Too Low?

If you’re a regular commuter on Metro-North, you won’t like this week’s column, but please read on.

A recent editorial in the rabid, rightwing, appropriately-named “Waterbury Republican American” suggested that rail fares in Connecticut are too low, and that this is unfair to taxpayers who don’t ride but are asked to subsidize those who do.

They argued that in-state fares cost less than driving, which is true, especially on the branch lines (New Canaan, Danbury and Waterbury) where fares are kept low on purpose.

For example, from Waterbury to Grand Central is 88 miles but costs less than New Haven to GCT which is 72 miles. And on the upscale New Canaan line, traveling from that town to NYC costs no more than going from Stamford to the city… making the eight mile ride from Stamford to New Canaan “free”.

On the main line our fares are based on a distance formula: 18.17 cents per mile, plus an additional $5.45 to go to 125th Street or Grand Central. Why the extra fare to go into Manhattan?

Within Connecticut the lowest one-way fare is $2.25, even to go just two miles. That hardly seems fair.

Or consider monthly fares. They are “commuted” from the regular fares by about a 50% discount of the regular peak fare. But why?

Monthly commuters travel at peak hours and place the greatest strain on the railroad. So why do they get the biggest discount? What other industry gives a price break at its busiest time, even to frequent customers?

You want to see a movie on a Saturday night, you pay top dollar. Travel by air to see your in-laws at Thanksgiving, no discounts there. Even if you are a regular ticket-buyer, higher cost is one way of managing the demand, given a limited supply of seats. So why do Metro-North and CDOT, which jointly set our fares, give such a huge price break to monthly commuters?

Sure, those commuters are the railroad’s bread and butter. And keeping transportation affordable is crucial to making Connecticut a livable jumping-off point for their journeys to work.

But increasingly it’s the “discretionary” rider who’s keeping monthly fares low… the people who go into the city on weekends, even at reduced off-peak fares. By keeping the seats full on trains, the cost of crews and electricity is amortized across the entire week, not just AM and PM rush hours.

On off-peak trains, senior citizens get a 50% discount. Why? If it’s because they’re living on a fixed income, why not discount fares for the unemployed, those on welfare or disability?

(By the way, I was not in favor of Senator Don Williams’ nutty 2007 plan to offer free mass transit to senior citizens at a time when our trains were standing-room only. That would have led to some nasty confrontations between commuters and free-riding blue hairs.)

Now don’t get me wrong: I am all for keeping fares low. What I am suggesting is that we seek equity between in-state and inter-state riders and across all day-parts. And, of course, we want to make sure conductors collect everyone’s tickets, which is still an on-going problem.

Should taxpayers who don’t ride Metro-North subsidize fares for those who do? Absolutely!

Fairfield County represents 20% of the state’s population but pays 42% of the taxes. And I don’t remember any of us complaining when we were asked to subsidize a new convention center in Hartford or football stadium for UConn.

What we need is equity, each of us contributing a fair share for the greater good.
So as the CDOT prepares for public hearings around upcoming fare increases, I hope they keep this in mind. Rather than a flat “X percent” hike across the board, let’s revisit our entire fare structure, branch lines, weekends, seniors and daily commuters. Let’s keep our fares fair.

Popular Posts