Wednesday, January 26, 2011

Stems added and fairing the hull

Slow progress on the Black Pearl (yet to give it my own name yet) kayak. I’ve added stems (just the white paulownia so not so tough but shows up nicely against the stained hull), and I’ve been applying a fairing compound made of epoxy, lightweight filler, wood dust etc.

Just waiting 7 days now for it to thoroughly set before I sand back.

Here’s a pic:

 

20

Biggest lesson from all this… get the strips flat before staining! Basically the better the stripping the easier the rest will be.

Staining has been interesting… painful but interesting. The Resene Colorwood stain does work but you definitely need only a light rag application and maybe a wash with water after it’s set up. For the fairing I’ve managed to replicate the color using epoxy colours (black, blue and red – I watched them making it at Resene so I knew the constituent colours and proportions – it was on a their computer screen Smile).

Hard to get a good photo while it sits in the garage but this boat looks real sleek.

Monday, December 27, 2010

Hull Stripping and Attempted Staining

Stripping was relatively easy and very quick. The wood reminded me of making balsa wood models when I was a kid:)

Main points were:

  • Make sure strips are even thickness – if I do this again I’ll invest in a planner thicknesser.

WP_000011

  • I mostly just stapled strips only occasionally using a bead of glue – this had one advantage – towards the end as I looked at the forms and the shape of the hull I realised I had one form on  slightly wrong angle – not sure how this happened as I was sure I had it right at the beginning. Nevermind, I unscrewed it and re-adjusted just a tiny bit and suddenly it looked great.
  • I thought I’d stain the strips before using epoxy to glue them all thogether – unfortunately, Resene interior stain turns out to not be as epoxy compatible as the Resene staff thought it would be. It beaded a bit but wasn’t irrecoverable – I might even put more stain on after I rub it all back in preparation for fibreglassing – but if I do I’ll wash with acetone and use a much thinner application of stain. Check the image below…

WP_000024

 

Hull looks great but I can’t get a good photo showing it the way I see it in real life. Perhaps for the next posting…

Wednesday, December 08, 2010

Spatial Notes–Getting Started

Thought this would be harder than it turned out to be.

Objective: chart some metrics across geographic regions (in my case looking at customer metrics over New Zealand).

To get started I took advantage of SQL Server Spatial. Initially appearances are a  bit daunting until you try it… and it’s fairly easy.

  • Finding the GIS data
    • for NZ  Statistics NZ publish digital boundaries – versioned by publication year (2007, 2001, 1996 etc: http://www.stats.govt.nz/browse_for_stats/people_and_communities/geographic-areas/download-digital-boundaries.aspx
    • The data is available in both ESRI Shapefile format and MapInfo format. You can use shape2sql to load this data into sql server spatial. Unfortunately… it has a bug, it won’t create a table from the shp file inside shape2sql – I had to use SQL Profiler to capture the create table instruction and run it interactively – after that the data load works fine - not sure why.
    • The data has a hierarchy of increasingly larger geometrical areas made up of units of the smallest size (the meshblock). There’s Area Units, Urban Areas, Regional Councils etc.
  • Connecting people to areas
  • Aggregating
    • Use SQL Server Analysis Services, or much faster
    • Use PowerPivot – for me this allowed me to very quickly aggregate customer metrics from an internal database across areas loaded from the Stats NZ files
  • Reporting
    • It’d be nice if Excel had spatial reporting support, but it doesn’t – big thumbs down Microsoft…
    • I used SQL Server Reporting Services and the Map control. Problem is that I need to have the map data in SQL/SSAS. It’d be nice to load from PowerPivot but I can’t do that unless I store the Excel PowerPivot doc in Sharepoint 2010. Jumping through hoops to do this though… Microsoft – just get the spatial support into Excel please!

Sunday, December 05, 2010

Strip cutting

I followed Bjorn’s instructions and cut the strips with a circular saw. The planks were pinned to a folding stand at each end. The paulownia was extremely stable. It didn’t split when I pinned it at the edge of the plank. Not one of the strips split or snapped. In the end it was much easier than I expected. Suspect it would’ve been even easier if I had a decent saw…

Photo0045

Ebonizing Paulownia

Vinegar and steel wool, left for a few days, filtered and then applied to paulownia strip – thinking of using this on my kayak. Top of the strip has been painted twice.

Photo0047

Sunday, November 28, 2010

Black Pearl Forms

So terribly slow but here’s a snippet of the forms.

IMG_1180

 

Lessons learned:

  • Level everything first – makes it much easier to align cross sections
  • Don’t start screwing cross sections to wooden cross bars until they all line up right. Use clamps first.
  • Drill a hole about 5mm on the center of the waterline and shine a bright light from one end – you should be able to see the light all the way down
  • I pre-cut the forms for the deck and re-attached them – supposedly to make it easier for later. Not sure it was worth it.

Here’s that light shining through a couple of the holes.

IMG_1182

Tuesday, October 05, 2010

New Kayak Build: Black Pearl

Two years on from building a Guillemot Kayaks Night Heron stitch and glue I’ve just purchased plans for a Bjorn Thomasson Black Pearl. The Night Heron is a great kayak that’s very quick in the water but I just enjoyed the building side too much so I’ve decided to try building a strip kayak. Rather than go with something closer to the Night Heron I decided to go down a slightly different path:

  • As light as possible – means small or low volume
  • Doesn’t need speed – the Night Heron fulfils that requirement for me
  • Play boat – I’ve taken up canoe polo so I want the most manuverable sea kayak experience I can get – something that will respond to hip/torso movement.

I think the Black Pearl will do this but the proof will be in the pudding. You don’t just order this off the book – the plans are custom printed to your height, arm span and hip measurements.

I’ll update the blog as I go. It will take awhile – no rush as I have an existing kayak already.

Monday, October 04, 2010

Populating a Word Document from a Sharepoint List

I thought this would be simpler since Sharepoint and Word are so closely related. A mail merge based on list data perhaps? Maybe it’s possible with an office data connection file but I couldn’t figure it out.

Well, it was useful to me so here’s how I did it with Powershell and Word automation. The example here is a list of standards and the output will be a list of those standards formatted on one Word document. The soap call from powershell comes from somewhere on the net with an added soapaction header. The list has been created with folder items so it needs to list the items recursively – this wouldn’t apply to a normal list. You’ll figure it out as you start looking at the xml attributes. Best way to make progress with these sharepoint soap calls is to use Wireshark in combination with Stramit Caml Viewer.

Here we go…

function Execute-SOAPRequest 
(
[Xml] $SOAPRequest,
[String] $SOAPAction,
[String] $URL
)
{
write-host "Sending SOAP Request To Server: $URL"
$soapWebRequest = [System.Net.WebRequest]::Create($URL)
$soapWebRequest.Headers.Add("SOAPAction","`"" + $SOAPAction + "`"")

$soapWebRequest.ContentType = "text/xml;charset=`"utf-8`""
$soapWebRequest.Accept = "text/xml"
$soapWebRequest.Method = "POST"

write-host "Authenticating"
$soapWebRequest.Credentials = [System.Net.CredentialCache]::DefaultCredentials
if($soapWebRequest.Proxy -ne $null) {
$soapWebRequest.Proxy.Credentials = [System.Net.CredentialCache]::DefaultNetworkCredentials
}

write-host "Initiating Send."
$requestStream = $soapWebRequest.GetRequestStream()
$SOAPRequest.Save($requestStream)
$requestStream.Close()

write-host "Send Complete, Waiting For Response."
$resp = $soapWebRequest.GetResponse()
$responseStream = $resp.GetResponseStream()
$soapReader = [System.IO.StreamReader]($responseStream)
$ReturnXml = [Xml] $soapReader.ReadToEnd()
$responseStream.Close()

write-host "Response Received."

return $ReturnXml
}

function Add-Standard
(
[String] $Standard,
[String] $Justification,
$Doc
)
{
$p = $Doc.Paragraphs.Add()
$p.Range.Text = $Standard
$p.Format.Style = "Heading 1"
$p.Range.InsertParagraphAfter()

$p = $Doc.Paragraphs.Add()
$p.Range.Text = $Justification
$p.Range.InsertParagraphAfter()
}

$d4 = [xml] @"
<?xml version="
1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="
http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Body>
<GetListItems xmlns="http://schemas.microsoft.com/sharepoint/soap/">
<listName>{CF6E48BA-650A-489E-83AB-8EF1E545388A}</listName>
<queryOptions>
<QueryOptions>
<ViewAttributes Scope="Recursive"/>
<IncludeMandatoryColumns>False</IncludeMandatoryColumns>
</QueryOptions>
</queryOptions>
</GetListItems>
</soap:Body>
</soap:Envelope>
"@


# create a document from list data!
$w = new-object -com Word.Application
$w.Visible = $true
$d = $w.Documents.Add()

Execute-SOAPRequest -SOAPRequest $d4 -SOAPAction "
http://schemas.microsoft.com/sharepoint/soap/GetListItems" -URL "http://<some sharepoint site>/sites/CTO/_vti_bin/lists.asmx" |
foreach {$_.Envelope.Body.GetListItemsResponse.GetListItemsResult.listitems.data.row |
foreach {Add-Standard -Standard $_.ows_Standard -Justification $_.ows_Justification -d $d }
}

$d.SaveAs([ref]"c:\temp\standards.docx")
$d.Close()
$w.Quit()

Sunday, August 15, 2010

FST Auckland Conference Presentation

You can find the presentation I did for the Financial Services Technology conference in Auckland last week here.

Brief synopsis: systems/operational management provides a useful analogue to the problems faced by implementers of business intelligence environments: huge volumes of data streaming in for which you need to provide health indicators and predictions of the future.

In the case of Microsoft’s System Center Operations Manager tool this is done in a manner that is very different from conventional BI efforts that rely on staging large quantities of data, building relational and dimensional models and producing KPIs. The solutions developed for operations management can be usefully applied to BI efforts, particularly when not dealing with financial data.

Monday, August 09, 2010

CIO Conference–Enterprise 2.0 Presentation

I’ve put the presentation here: http://cid-0e5ff53cd7f11485.office.live.com/browse.aspx/Public/CIO%20Conference%20July%2010

Questions from the audience about my criticism of data focussed BI got me thinking about what might be a better model. I’ve changed the slide deck to cover more of a BI story for presentation at the FST conference in Auckland this Wednesday.

Seq.unfold

Don’t know why this had escaped me for so long!

 

let PascalsTriangle =
let nextLine aLine =
let partialLine =
aLine
|> Seq.pairwise
|> Seq.map (fun (x,y) -> x+y)
|> Seq.toList
List.append (1::partialLine) [1]
[1] |> Seq.unfold (fun s -> Some(s, nextLine s))

Compare to: Pascal’s Triangle in F#

Friday, July 30, 2010

Heat/Image Mapping with .Net/F#

As part of a demonstration to the Wellington .net user group this week I put together a demo showing a heat mapping of the performance of a transactional system as a function of time of day and arrival rate. My objective was to provide a simple eye balling test of whether performance was being impacted more by daytime customer loading or by competing overnight batch processing. I’ve tried a similar task before with Python and MatPlotLib but this time I wanted to see how easy it was to accomplish in .Net/F#.

The answer was ‘very easy’.

The interactive F# environment in VS2010 gives you JIT compiled code so it’s very fast to work with. The data structures/collections available within F# make importing and manipulating data simple – once it’s in memory you spend most of the time using filter, map and fold operations on elements – explicit recursion or iteration is rarely necessary.

I found I started with sequences then moved to arrays as data volumes increased and performance slowed. Array.Parallel.map/mapi seemed to make a significant difference whenever the operation being performed was of order a few milliseconds. It’s pointless parallising when the operation performed is short – the overhead of managing threads must just be too great.

Most of the effort was spent aggregating and binning the data, the actual image prep was trivial. The following assumes you have an array of data to display.

open System.Drawing
open System.Drawing.Imaging
open System.Windows.Forms
// adapted some code here from http://thecodedecanter.wordpress.com/2010/04/30/modelling-the-2d-heat-equation-in-f-using-100-lines-of-code/
let toBitmap (arr:Color[,]) =
let image = new Bitmap(arr.GetLength(0),arr.GetLength(1),Imaging.PixelFormat.Format24bppRgb)
for i=0 to image.Width-1
do
for
j=0 to image.Height-1
do
image.SetPixel(i, j, (arr.[i,j]))
done
done
image

let maxInArray2D (ar:'a[,]) =
seq{ for r in 0..Array2D.length1 ar-1
do
yield
Seq.max (ar.[r..r,*] |> Seq.cast<'a>)
} |> Seq.max

let intensityMap intensity = Color.FromArgb((int (intensity * 255.0)),0,0)

let bitmap imageArray =
let max = imageArray |> maxInArray2D
imageArray
|> Array2D.map (fun f -> f/max)
|> Array2D.map (fun f -> intensityMap f)
|> toBitmap

let ShowForm (f : Form) =
#if INTERACTIVE
f.Show()
#endif
#if
COMPILED
Application.Run(f)
#endif

let
BitmapForm bitmap =
let picBox = new PictureBox(BorderStyle = BorderStyle.Fixed3D, Image = bitmap, Size = bitmap.Size,
Dock = DockStyle.Fill, SizeMode = PictureBoxSizeMode.StretchImage)
let form = new Form(Text = "F# Connection Performance versus Connection Rate and Time", Size = bitmap.Size, AutoSize = true)
form.Controls.Add(picBox)
form

bitmap surfaceArray |> BitmapForm |> ShowForm


If you don’t have many points that’s going to generate a small image which you can expand by dragging the corner and Windows will magically interpolate for you. I’m sure there’s a way to explicitly do this with the BitmapForm API as well – just didn’t have time to figure that out.



If you want to interpolate yourself, you could try something simple like a bilinear approach:



let bilinearInterpolation f00 f01 f10 f11 x y =
let boundingBox = Array2D.zeroCreate<float> 2 2

boundingBox.[0,0] <- f00
boundingBox.[0,1] <- f01
boundingBox.[1,0] <- f10
boundingBox.[1,1] <- f11
let A = RowVector.ofList [1.-x; x]
let B = Matrix.ofArray2D boundingBox
let C = Vector.ofList [1.-y; y]
A * B * C


Or why not just double the resolution?



// take an array m x n and return (2m-1) x (2n-1)
let interpolate (A:float[,]) =
    let B = Array2D.zeroCreate<float> (2*(A.GetLength 0) - 1) (2*(A.GetLength 1) - 1)
    for row in 0..((A.GetLength 0) - 1) do
        for col in 0..((A.GetLength 1) - 1) do
            B.[2*row, 2*col] <- A.[row,col]
        done
    done
    //
    for row in 0..((B.GetLength 0) - 1) do
        if row % 2 = 0 then
            for col in 0..((B.GetLength 1) - 1) do
                if col % 2 = 1 then
                    B.[row, col] <- (B.[row,col-1] + B.[row,col+1]) / 2.
            done
        else
            for col in 0..((B.GetLength 1) - 1) do
                if col % 2 = 0 then
                    B.[row, col] <- (B.[row-1,col] + B.[row+1,col]) / 2.
                else
                    B.[row, col] <- (B.[row-1,col-1] + B.[row+1,col-1] + B.[row-1,col+1] + B.[row+1,col+1]) / 4.
            done
    done
    B

// now I can do this...
bitmap (surfaceArray |> interpolate |> interpolate |> interpolate |> interpolate)|> BitmapForm |> ShowForm


And generate results like this (where connection rate increases down, time goes across, and redness indicates duration of calls):



performancemap

Monday, July 26, 2010

F# for Analysis: Wellington .Net User Group Meeting Wed 28th July

Some brief notes for anyone attending this session.

There’s a brief slide deck here.

There’s sample code working through the basics of the language here.

Sample code for the cross correlation of two time series in F# here.

I’ll put a separate post together for image generation of a heat map showing web performance data.

System Center Operations Manager and BI

Last week as part of a presentation to the CIO summit in Auckland I had a bit of fun criticising conventional corporate BI efforts as being too focussed on data management. Basically, the argument went that companies spend too much of the budget worrying about getting the data right and not about enabling people to use it – and that ‘easy to use’ BI front ends are a pointless exercise. It’s not a hard argument to make – you can expend a great deal of time and effort on staging, transforming, cubing, KPI development, and reconciliation quality checks – usually driven by the fact that corporate BI is focussed on financial measures which drives people to want the data correct to the cent.

The natural question that comes back in response is what should be done instead?

Operations management using a model driven tool like System Center Operations Manager provides some useful pointers.

Think about it – what’s operations management?

= Data + Model + Health logic + Alerting for response

What’s BI?

= Data + Model + Business Health Logic + “Strategy execution” for response

What’s smart about model driven operations management?

The tools (like SCOM) monitor systems that can produce huge volumes of data; they give that data context with hierarchical models (à la cubes) that can even be graphical (LiveMaps/Visio 2010 diagrams); they provide health indicators (cf KPIs) and they empower end users by making the information available for more detailed analysis at the desktop.

So how would you put this kind of model into action for BI?

How about mirrored true to source data sources using cheap databases (maybe SQL Express/MySQL). You’d need a grooming schedule to stay on top of the data volumes – perhaps and agent model just like the operations management tools have.

To collect the data from multiple sources, and give some context a cube model is attractive, but what about implementing with PowerPivot. It puts the end user in charge. They can create health indications in an Excel like environment; and they can submit back into a shared (Sharepoint) repository.

I’ve got to present at the longwinded FST 3rd Annual Technology & Innovation – the Future of Banking & Financial Services New Zealand conference in August. I’ll be exploring this in more detail and hopefully have a few examples to test out.

Sunday, July 18, 2010

Dynamically changing format statements in the F# ISE

This had me stuck yesterday – how to change the width of  some formatted printf output. In the end with a bit of searching I realised the TextWriterFormat member gives you a way to define the format such that you can change it in your program. An example is a better viewer for the Pascals Triangle sequence generator I made recently – all related to a school math project. Also – where does it tell you that to print a % you need to double it? Why didn’t they do as with speech marks and use a leading \?

let rec PascalsTriangle = seq {
yield [1];
for aLine in PascalsTriangle
->
let
newLine =
aLine
|> Seq.pairwise
|> Seq.map (fun (x,y) -> x+y)
|> Seq.toList
List.append (1::newLine) [1]
}

PascalsTriangle |> Seq.take 10
//|> Seq.iter (fun i -> printfn "%A" i)
|> Seq.iter (fun v
->
v |> Seq.iter (fun w -> printf "%3i" w)
printfn
""
)

// smarten up the printing...
let samplePT = PascalsTriangle |> Seq.take 12
let maxDigits = (Seq.concat samplePT |> Seq.max).ToString().Length
let numberFormatter digits = Printf.TextWriterFormat<int->unit>(sprintf "%%%dd" digits)
let spaceFormatter digits = Printf.TextWriterFormat<string->unit>(sprintf "%%%ds" digits)
let rows = Seq.length samplePT
samplePT |> Seq.iteri ( fun u v
->
for
i in 1..((rows / 1) - u)
do
printf (spaceFormatter ((int)((maxDigits+1)/2)))
" "
v |> Seq.iter (fun w -> printf (numberFormatter (maxDigits+1)) w)
printfn
""
)


The output is like this:


                      1

                    1   1


                  1   2   1


                1   3   3   1


              1   4   6   4   1


            1   5  10  10   5   1


          1   6  15  20  15   6   1


        1   7  21  35  35  21   7   1


      1   8  28  56  70  56  28   8   1


    1   9  36  84 126 126  84  36   9   1


  1  10  45 120 210 252 210 120  45  10   1


1  11  55 165 330 462 462 330 165  55  11   1


Wish I knew how to do this in WPF…



Wish I knew a better way to post into the blog…