<!--{{{-->
<link rel='alternate' type='application/rss+xml' title='RSS' href='index.xml' />
<!--}}}-->
Background: #fff
Foreground: #000
PrimaryPale: #8cf
PrimaryLight: #18f
PrimaryMid: #04b
PrimaryDark: #014
SecondaryPale: #ffc
SecondaryLight: #fe8
SecondaryMid: #db4
SecondaryDark: #841
TertiaryPale: #eee
TertiaryLight: #ccc
TertiaryMid: #999
TertiaryDark: #666
Error: #f88
/*{{{*/
body {background:[[ColorPalette::Background]]; color:[[ColorPalette::Foreground]];}

a {color:[[ColorPalette::PrimaryMid]];}
a:hover {background-color:[[ColorPalette::PrimaryMid]]; color:[[ColorPalette::Background]];}
a img {border:0;}

h1,h2,h3,h4,h5,h6 {color:[[ColorPalette::SecondaryDark]]; background:transparent;}
h1 {border-bottom:2px solid [[ColorPalette::TertiaryLight]];}
h2,h3 {border-bottom:1px solid [[ColorPalette::TertiaryLight]];}

.button {color:[[ColorPalette::PrimaryDark]]; border:1px solid [[ColorPalette::Background]];}
.button:hover {color:[[ColorPalette::PrimaryDark]]; background:[[ColorPalette::SecondaryLight]]; border-color:[[ColorPalette::SecondaryMid]];}
.button:active {color:[[ColorPalette::Background]]; background:[[ColorPalette::SecondaryMid]]; border:1px solid [[ColorPalette::SecondaryDark]];}

.header {background:[[ColorPalette::PrimaryMid]];}
.headerShadow {color:[[ColorPalette::Foreground]];}
.headerShadow a {font-weight:normal; color:[[ColorPalette::Foreground]];}
.headerForeground {color:[[ColorPalette::Background]];}
.headerForeground a {font-weight:normal; color:[[ColorPalette::PrimaryPale]];}

.tabSelected{color:[[ColorPalette::PrimaryDark]];
	background:[[ColorPalette::TertiaryPale]];
	border-left:1px solid [[ColorPalette::TertiaryLight]];
	border-top:1px solid [[ColorPalette::TertiaryLight]];
	border-right:1px solid [[ColorPalette::TertiaryLight]];
}
.tabUnselected {color:[[ColorPalette::Background]]; background:[[ColorPalette::TertiaryMid]];}
.tabContents {color:[[ColorPalette::PrimaryDark]]; background:[[ColorPalette::TertiaryPale]]; border:1px solid [[ColorPalette::TertiaryLight]];}
.tabContents .button {border:0;}

#sidebar {}
#sidebarOptions input {border:1px solid [[ColorPalette::PrimaryMid]];}
#sidebarOptions .sliderPanel {background:[[ColorPalette::PrimaryPale]];}
#sidebarOptions .sliderPanel a {border:none;color:[[ColorPalette::PrimaryMid]];}
#sidebarOptions .sliderPanel a:hover {color:[[ColorPalette::Background]]; background:[[ColorPalette::PrimaryMid]];}
#sidebarOptions .sliderPanel a:active {color:[[ColorPalette::PrimaryMid]]; background:[[ColorPalette::Background]];}

.wizard {background:[[ColorPalette::PrimaryPale]]; border:1px solid [[ColorPalette::PrimaryMid]];}
.wizard h1 {color:[[ColorPalette::PrimaryDark]]; border:none;}
.wizard h2 {color:[[ColorPalette::Foreground]]; border:none;}
.wizardStep {background:[[ColorPalette::Background]]; color:[[ColorPalette::Foreground]];
	border:1px solid [[ColorPalette::PrimaryMid]];}
.wizardStep.wizardStepDone {background:[[ColorPalette::TertiaryLight]];}
.wizardFooter {background:[[ColorPalette::PrimaryPale]];}
.wizardFooter .status {background:[[ColorPalette::PrimaryDark]]; color:[[ColorPalette::Background]];}
.wizard .button {color:[[ColorPalette::Foreground]]; background:[[ColorPalette::SecondaryLight]]; border: 1px solid;
	border-color:[[ColorPalette::SecondaryPale]] [[ColorPalette::SecondaryDark]] [[ColorPalette::SecondaryDark]] [[ColorPalette::SecondaryPale]];}
.wizard .button:hover {color:[[ColorPalette::Foreground]]; background:[[ColorPalette::Background]];}
.wizard .button:active {color:[[ColorPalette::Background]]; background:[[ColorPalette::Foreground]]; border: 1px solid;
	border-color:[[ColorPalette::PrimaryDark]] [[ColorPalette::PrimaryPale]] [[ColorPalette::PrimaryPale]] [[ColorPalette::PrimaryDark]];}

.wizard .notChanged {background:transparent;}
.wizard .changedLocally {background:#80ff80;}
.wizard .changedServer {background:#8080ff;}
.wizard .changedBoth {background:#ff8080;}
.wizard .notFound {background:#ffff80;}
.wizard .putToServer {background:#ff80ff;}
.wizard .gotFromServer {background:#80ffff;}

#messageArea {border:1px solid [[ColorPalette::SecondaryMid]]; background:[[ColorPalette::SecondaryLight]]; color:[[ColorPalette::Foreground]];}
#messageArea .button {color:[[ColorPalette::PrimaryMid]]; background:[[ColorPalette::SecondaryPale]]; border:none;}

.popupTiddler {background:[[ColorPalette::TertiaryPale]]; border:2px solid [[ColorPalette::TertiaryMid]];}

.popup {background:[[ColorPalette::TertiaryPale]]; color:[[ColorPalette::TertiaryDark]]; border-left:1px solid [[ColorPalette::TertiaryMid]]; border-top:1px solid [[ColorPalette::TertiaryMid]]; border-right:2px solid [[ColorPalette::TertiaryDark]]; border-bottom:2px solid [[ColorPalette::TertiaryDark]];}
.popup hr {color:[[ColorPalette::PrimaryDark]]; background:[[ColorPalette::PrimaryDark]]; border-bottom:1px;}
.popup li.disabled {color:[[ColorPalette::TertiaryMid]];}
.popup li a, .popup li a:visited {color:[[ColorPalette::Foreground]]; border: none;}
.popup li a:hover {background:[[ColorPalette::SecondaryLight]]; color:[[ColorPalette::Foreground]]; border: none;}
.popup li a:active {background:[[ColorPalette::SecondaryPale]]; color:[[ColorPalette::Foreground]]; border: none;}
.popupHighlight {background:[[ColorPalette::Background]]; color:[[ColorPalette::Foreground]];}
.listBreak div {border-bottom:1px solid [[ColorPalette::TertiaryDark]];}

.tiddler .defaultCommand {font-weight:bold;}

.shadow .title {color:[[ColorPalette::TertiaryDark]];}

.title {color:[[ColorPalette::SecondaryDark]];}
.subtitle {color:[[ColorPalette::TertiaryDark]];}

.toolbar {color:[[ColorPalette::PrimaryMid]];}
.toolbar a {color:[[ColorPalette::TertiaryLight]];}
.selected .toolbar a {color:[[ColorPalette::TertiaryMid]];}
.selected .toolbar a:hover {color:[[ColorPalette::Foreground]];}

.tagging, .tagged {border:1px solid [[ColorPalette::TertiaryPale]]; background-color:[[ColorPalette::TertiaryPale]];}
.selected .tagging, .selected .tagged {background-color:[[ColorPalette::TertiaryLight]]; border:1px solid [[ColorPalette::TertiaryMid]];}
.tagging .listTitle, .tagged .listTitle {color:[[ColorPalette::PrimaryDark]];}
.tagging .button, .tagged .button {border:none;}

.footer {color:[[ColorPalette::TertiaryLight]];}
.selected .footer {color:[[ColorPalette::TertiaryMid]];}

.sparkline {background:[[ColorPalette::PrimaryPale]]; border:0;}
.sparktick {background:[[ColorPalette::PrimaryDark]];}

.error, .errorButton {color:[[ColorPalette::Foreground]]; background:[[ColorPalette::Error]];}
.warning {color:[[ColorPalette::Foreground]]; background:[[ColorPalette::SecondaryPale]];}
.lowlight {background:[[ColorPalette::TertiaryLight]];}

.zoomer {background:none; color:[[ColorPalette::TertiaryMid]]; border:3px solid [[ColorPalette::TertiaryMid]];}

.imageLink, #displayArea .imageLink {background:transparent;}

.annotation {background:[[ColorPalette::SecondaryLight]]; color:[[ColorPalette::Foreground]]; border:2px solid [[ColorPalette::SecondaryMid]];}

.viewer .listTitle {list-style-type:none; margin-left:-2em;}
.viewer .button {border:1px solid [[ColorPalette::SecondaryMid]];}
.viewer blockquote {border-left:3px solid [[ColorPalette::TertiaryDark]];}

.viewer table, table.twtable {border:2px solid [[ColorPalette::TertiaryDark]];}
.viewer th, .viewer thead td, .twtable th, .twtable thead td {background:[[ColorPalette::SecondaryMid]]; border:1px solid [[ColorPalette::TertiaryDark]]; color:[[ColorPalette::Background]];}
.viewer td, .viewer tr, .twtable td, .twtable tr {border:1px solid [[ColorPalette::TertiaryDark]];}

.viewer pre {border:1px solid [[ColorPalette::SecondaryLight]]; background:[[ColorPalette::SecondaryPale]];}
.viewer code {color:[[ColorPalette::SecondaryDark]];}
.viewer hr {border:0; border-top:dashed 1px [[ColorPalette::TertiaryDark]]; color:[[ColorPalette::TertiaryDark]];}

.highlight, .marked {background:[[ColorPalette::SecondaryLight]];}

.editor input {border:1px solid [[ColorPalette::PrimaryMid]];}
.editor textarea {border:1px solid [[ColorPalette::PrimaryMid]]; width:100%;}
.editorFooter {color:[[ColorPalette::TertiaryMid]];}
.readOnly {background:[[ColorPalette::TertiaryPale]];}

#backstageArea {background:[[ColorPalette::Foreground]]; color:[[ColorPalette::TertiaryMid]];}
#backstageArea a {background:[[ColorPalette::Foreground]]; color:[[ColorPalette::Background]]; border:none;}
#backstageArea a:hover {background:[[ColorPalette::SecondaryLight]]; color:[[ColorPalette::Foreground]]; }
#backstageArea a.backstageSelTab {background:[[ColorPalette::Background]]; color:[[ColorPalette::Foreground]];}
#backstageButton a {background:none; color:[[ColorPalette::Background]]; border:none;}
#backstageButton a:hover {background:[[ColorPalette::Foreground]]; color:[[ColorPalette::Background]]; border:none;}
#backstagePanel {background:[[ColorPalette::Background]]; border-color: [[ColorPalette::Background]] [[ColorPalette::TertiaryDark]] [[ColorPalette::TertiaryDark]] [[ColorPalette::TertiaryDark]];}
.backstagePanelFooter .button {border:none; color:[[ColorPalette::Background]];}
.backstagePanelFooter .button:hover {color:[[ColorPalette::Foreground]];}
#backstageCloak {background:[[ColorPalette::Foreground]]; opacity:0.6; filter:'alpha(opacity=60)';}
/*}}}*/
/*{{{*/
* html .tiddler {height:1%;}

body {font-size:.75em; font-family:arial,helvetica; margin:0; padding:0;}

h1,h2,h3,h4,h5,h6 {font-weight:bold; text-decoration:none;}
h1,h2,h3 {padding-bottom:1px; margin-top:1.2em;margin-bottom:0.3em;}
h4,h5,h6 {margin-top:1em;}
h1 {font-size:1.35em;}
h2 {font-size:1.25em;}
h3 {font-size:1.1em;}
h4 {font-size:1em;}
h5 {font-size:.9em;}

hr {height:1px;}

a {text-decoration:none;}

dt {font-weight:bold;}

ol {list-style-type:decimal;}
ol ol {list-style-type:lower-alpha;}
ol ol ol {list-style-type:lower-roman;}
ol ol ol ol {list-style-type:decimal;}
ol ol ol ol ol {list-style-type:lower-alpha;}
ol ol ol ol ol ol {list-style-type:lower-roman;}
ol ol ol ol ol ol ol {list-style-type:decimal;}

.txtOptionInput {width:11em;}

#contentWrapper .chkOptionInput {border:0;}

.externalLink {text-decoration:underline;}

.indent {margin-left:3em;}
.outdent {margin-left:3em; text-indent:-3em;}
code.escaped {white-space:nowrap;}

.tiddlyLinkExisting {font-weight:bold;}
.tiddlyLinkNonExisting {font-style:italic;}

/* the 'a' is required for IE, otherwise it renders the whole tiddler in bold */
a.tiddlyLinkNonExisting.shadow {font-weight:bold;}

#mainMenu .tiddlyLinkExisting,
	#mainMenu .tiddlyLinkNonExisting,
	#sidebarTabs .tiddlyLinkNonExisting {font-weight:normal; font-style:normal;}
#sidebarTabs .tiddlyLinkExisting {font-weight:bold; font-style:normal;}

.header {position:relative;}
.header a:hover {background:transparent;}
.headerShadow {position:relative; padding:4.5em 0 1em 1em; left:-1px; top:-1px;}
.headerForeground {position:absolute; padding:4.5em 0 1em 1em; left:0px; top:0px;}

.siteTitle {font-size:3em;}
.siteSubtitle {font-size:1.2em;}

#mainMenu {position:absolute; left:0; width:10em; text-align:right; line-height:1.6em; padding:1.5em 0.5em 0.5em 0.5em; font-size:1.1em;}

#sidebar {position:absolute; right:3px; width:16em; font-size:.9em;}
#sidebarOptions {padding-top:0.3em;}
#sidebarOptions a {margin:0 0.2em; padding:0.2em 0.3em; display:block;}
#sidebarOptions input {margin:0.4em 0.5em;}
#sidebarOptions .sliderPanel {margin-left:1em; padding:0.5em; font-size:.85em;}
#sidebarOptions .sliderPanel a {font-weight:bold; display:inline; padding:0;}
#sidebarOptions .sliderPanel input {margin:0 0 0.3em 0;}
#sidebarTabs .tabContents {width:15em; overflow:hidden;}

.wizard {padding:0.1em 1em 0 2em;}
.wizard h1 {font-size:2em; font-weight:bold; background:none; padding:0; margin:0.4em 0 0.2em;}
.wizard h2 {font-size:1.2em; font-weight:bold; background:none; padding:0; margin:0.4em 0 0.2em;}
.wizardStep {padding:1em 1em 1em 1em;}
.wizard .button {margin:0.5em 0 0; font-size:1.2em;}
.wizardFooter {padding:0.8em 0.4em 0.8em 0;}
.wizardFooter .status {padding:0 0.4em; margin-left:1em;}
.wizard .button {padding:0.1em 0.2em;}

#messageArea {position:fixed; top:2em; right:0; margin:0.5em; padding:0.5em; z-index:2000; _position:absolute;}
.messageToolbar {display:block; text-align:right; padding:0.2em;}
#messageArea a {text-decoration:underline;}

.tiddlerPopupButton {padding:0.2em;}
.popupTiddler {position: absolute; z-index:300; padding:1em; margin:0;}

.popup {position:absolute; z-index:300; font-size:.9em; padding:0; list-style:none; margin:0;}
.popup .popupMessage {padding:0.4em;}
.popup hr {display:block; height:1px; width:auto; padding:0; margin:0.2em 0;}
.popup li.disabled {padding:0.4em;}
.popup li a {display:block; padding:0.4em; font-weight:normal; cursor:pointer;}
.listBreak {font-size:1px; line-height:1px;}
.listBreak div {margin:2px 0;}

.tabset {padding:1em 0 0 0.5em;}
.tab {margin:0 0 0 0.25em; padding:2px;}
.tabContents {padding:0.5em;}
.tabContents ul, .tabContents ol {margin:0; padding:0;}
.txtMainTab .tabContents li {list-style:none;}
.tabContents li.listLink { margin-left:.75em;}

#contentWrapper {display:block;}
#splashScreen {display:none;}

#displayArea {margin:1em 17em 0 14em;}

.toolbar {text-align:right; font-size:.9em;}

.tiddler {padding:1em 1em 0;}

.missing .viewer,.missing .title {font-style:italic;}

.title {font-size:1.6em; font-weight:bold;}

.missing .subtitle {display:none;}
.subtitle {font-size:1.1em;}

.tiddler .button {padding:0.2em 0.4em;}

.tagging {margin:0.5em 0.5em 0.5em 0; float:left; display:none;}
.isTag .tagging {display:block;}
.tagged {margin:0.5em; float:right;}
.tagging, .tagged {font-size:0.9em; padding:0.25em;}
.tagging ul, .tagged ul {list-style:none; margin:0.25em; padding:0;}
.tagClear {clear:both;}

.footer {font-size:.9em;}
.footer li {display:inline;}

.annotation {padding:0.5em; margin:0.5em;}

* html .viewer pre {width:99%; padding:0 0 1em 0;}
.viewer {line-height:1.4em; padding-top:0.5em;}
.viewer .button {margin:0 0.25em; padding:0 0.25em;}
.viewer blockquote {line-height:1.5em; padding-left:0.8em;margin-left:2.5em;}
.viewer ul, .viewer ol {margin-left:0.5em; padding-left:1.5em;}

.viewer table, table.twtable {border-collapse:collapse; margin:0.8em 1.0em;}
.viewer th, .viewer td, .viewer tr,.viewer caption,.twtable th, .twtable td, .twtable tr,.twtable caption {padding:3px;}
table.listView {font-size:0.85em; margin:0.8em 1.0em;}
table.listView th, table.listView td, table.listView tr {padding:0px 3px 0px 3px;}

.viewer pre {padding:0.5em; margin-left:0.5em; font-size:1.2em; line-height:1.4em; overflow:auto;}
.viewer code {font-size:1.2em; line-height:1.4em;}

.editor {font-size:1.1em;}
.editor input, .editor textarea {display:block; width:100%; font:inherit;}
.editorFooter {padding:0.25em 0; font-size:.9em;}
.editorFooter .button {padding-top:0px; padding-bottom:0px;}

.fieldsetFix {border:0; padding:0; margin:1px 0px;}

.sparkline {line-height:1em;}
.sparktick {outline:0;}

.zoomer {font-size:1.1em; position:absolute; overflow:hidden;}
.zoomer div {padding:1em;}

* html #backstage {width:99%;}
* html #backstageArea {width:99%;}
#backstageArea {display:none; position:relative; overflow: hidden; z-index:150; padding:0.3em 0.5em;}
#backstageToolbar {position:relative;}
#backstageArea a {font-weight:bold; margin-left:0.5em; padding:0.3em 0.5em;}
#backstageButton {display:none; position:absolute; z-index:175; top:0; right:0;}
#backstageButton a {padding:0.1em 0.4em; margin:0.1em;}
#backstage {position:relative; width:100%; z-index:50;}
#backstagePanel {display:none; z-index:100; position:absolute; width:90%; margin-left:3em; padding:1em;}
.backstagePanelFooter {padding-top:0.2em; float:right;}
.backstagePanelFooter a {padding:0.2em 0.4em;}
#backstageCloak {display:none; z-index:20; position:absolute; width:100%; height:100px;}

.whenBackstage {display:none;}
.backstageVisible .whenBackstage {display:block;}
/*}}}*/
/***
StyleSheet for use when a translation requires any css style changes.
This StyleSheet can be used directly by languages such as Chinese, Japanese and Korean which need larger font sizes.
***/
/*{{{*/
body {font-size:0.8em;}
#sidebarOptions {font-size:1.05em;}
#sidebarOptions a {font-style:normal;}
#sidebarOptions .sliderPanel {font-size:0.95em;}
.subtitle {font-size:0.8em;}
.viewer table.listView {font-size:0.95em;}
/*}}}*/
/*{{{*/
@media print {
#mainMenu, #sidebar, #messageArea, .toolbar, #backstageButton, #backstageArea {display: none !important;}
#displayArea {margin: 1em 1em 0em;}
noscript {display:none;} /* Fixes a feature in Firefox 1.5.0.2 where print preview displays the noscript content */
}
/*}}}*/
<!--{{{-->
<div class='header' macro='gradient vert [[ColorPalette::PrimaryLight]] [[ColorPalette::PrimaryMid]]'>
<div class='headerShadow'>
<span class='siteTitle' refresh='content' tiddler='SiteTitle'></span>&nbsp;
<span class='siteSubtitle' refresh='content' tiddler='SiteSubtitle'></span>
</div>
<div class='headerForeground'>
<span class='siteTitle' refresh='content' tiddler='SiteTitle'></span>&nbsp;
<span class='siteSubtitle' refresh='content' tiddler='SiteSubtitle'></span>
</div>
</div>
<div id='mainMenu' refresh='content' tiddler='MainMenu'></div>
<div id='sidebar'>
<div id='sidebarOptions' refresh='content' tiddler='SideBarOptions'></div>
<div id='sidebarTabs' refresh='content' force='true' tiddler='SideBarTabs'></div>
</div>
<div id='displayArea'>
<div id='messageArea'></div>
<div id='tiddlerDisplay'></div>
</div>
<!--}}}-->
<!--{{{-->
<div class='toolbar' macro='toolbar [[ToolbarCommands::ViewToolbar]]'></div>
<div class='title' macro='view title'></div>
<div class='subtitle'><span macro='view modifier link'></span>, <span macro='view modified date'></span> (<span macro='message views.wikified.createdPrompt'></span> <span macro='view created date'></span>)</div>
<div class='tagging' macro='tagging'></div>
<div class='tagged' macro='tags'></div>
<div class='viewer' macro='view text wikified'></div>

<div class='tagClear'></div>
<!--}}}-->
<!--{{{-->
<div class='toolbar' macro='toolbar [[ToolbarCommands::EditToolbar]]'></div>
<div class='title' macro='view title'></div>
<div class='editor' macro='edit title'></div>
<div macro='annotations'></div>
<div class='editor' macro='edit text'></div>
<div class='editor' macro='edit tags'></div><div class='editorFooter'><span macro='message views.editor.tagPrompt'></span><span macro='tagChooser excludeLists'></span></div>
<!--}}}-->
To get started with this blank [[TiddlyWiki]], you'll need to modify the following tiddlers:
* [[SiteTitle]] & [[SiteSubtitle]]: The title and subtitle of the site, as shown above (after saving, they will also appear in the browser title bar)
* [[MainMenu]]: The menu (usually on the left)
* [[DefaultTiddlers]]: Contains the names of the tiddlers that you want to appear when the TiddlyWiki is opened
You'll also need to enter your username for signing your edits: <<option txtUserName>>
These [[InterfaceOptions]] for customising [[TiddlyWiki]] are saved in your browser

Your username for signing your edits. Write it as a [[WikiWord]] (eg [[JoeBloggs]])

<<option txtUserName>>
<<option chkSaveBackups>> [[SaveBackups]]
<<option chkAutoSave>> [[AutoSave]]
<<option chkRegExpSearch>> [[RegExpSearch]]
<<option chkCaseSensitiveSearch>> [[CaseSensitiveSearch]]
<<option chkAnimate>> [[EnableAnimations]]

----
Also see [[AdvancedOptions]]
<<importTiddlers>>
A1	~NO3 dark 	#2
A2	~NO3 dark 	#3
A3	~NH4 T0	#1
A4	~NH4 T0	#2
A5	~NH4 T0	#3
A6	~NH4 100%	#1
A7	~NH4 100%	#2
A8	~NH4 100%	#3
A9	~NH4 50%	#1
A10	~NH4 50%	#2
A11	~NH4 50%	#3
N-Allylthiourea
* 4.05g of [[Allylthiourea]] in 1 L
* Not volumetric
Sodium azide solution
* 0.7 ml of 2M stock ~NaN3 solution in 1L
* Not volumetric (not for use as standard)
My name is Martin Johnson and I'm a researcher in Marine and Atmospheric Chemistry in the [[School of Environmental Sciences | http://www.uea.ac.uk/env/]] at the [[University of East Anglia | http://www.uea.ac.uk/]]. My key research interests are [[air-sea trace gas exchange| AirSea]], [[marine microbial biogeochemistry | MarineBiogeochemistry]] (particularly nitrogen cycling) and [[understanding and expressing uncertainty | Uncertainty]] in measured, modelled and estimated data. When I'm not at work I like to play the banjo and viola, get out and about in the countryside and geek about with my computer and smartphone. I have a wife, Lisa and 2-year old son, Oliver and live on the Outskirts of Norwich next to a wood .

This site is an open notebook of my scientific and technical work, started in November 2010 (I may add some of my previous work retrospectively if time allows, which it probably wont). This is done in the spirit of Open Research. With a growing number of others I share the opinion that the greatest benefit to society and to knowledge itself is the completely free and open sharing of data. You can read more at http://en.wikipedia.org/wiki/Open_research and also at Cameron Neylon's site [[Science in the Open | http://cameronneylon.net/about/]].


You can follow my (mostly non-scientific) brief ramblings on twitter [[@martwine| http://twitter.com/#!/martwine]] and read my blog at http://martwine.wordpress.com
I have done extensive work on air-sea trace gas exchange and will document ongoing stuff here. To get started, have a look at my recent paper in Ocean Science: <<cite johnson2010 bibliography:Bibliography>> (http://www.ocean-sci.net/6/913/2010/) and forthcoming book chapter: <<cite johnson2011>> (http://www.researchpages.net/publications/725).

<<bibliography>>
Cruise on THV Alert 22/10/2010 Lowestoft-Gabbard-Warp-Lowestoft. 

At each of the SMARTBuoy stations [[Warp]] and [[Gabbard]] samples were taken for the [[storage tests | SMARTBuoyStorage]] for NH$_4^+$, DON/DOC, inorganic nutrients, trace gases and DIC. 
~N-Allythiourea 98%
* Aldrich 108804-50g
* ~MKDB3265 (batch number?) 
* rmm 116.2
* Arrived today
<<cite Atkinson1990 bibliography:Bibliography>> present experimentally-derived second order rate constants for dimethylselenide in the atmosphere for reactions with OH radical, O3 and ~NO3 radical:

|!reaction with|!second order rate constant / cm$^3$ molecules$^{-1}$ s$^{-1}$|
|OH|6.8 x10$^{-11}$|
|~NO3|1.4 x10$^{-11}$|
|O3|6.8 x10$^{-17}$|

(1 OOM more rapid than the same reactions with DMS!)

Typical MBL concentrations of the reactants are as follows:

|!reactant|!typical MBL concentration / molecules cm$^{-3}$|!ref/link|
|OH|1.4 x10$^{6}$|http://www.atmos-chem-phys.org/9/9225/2009/acp-9-9225-2009.html|
|~NO3|1 x10$^7$|http://www.agu.org/pubs/crossref/2000/2000JD900314.shtml|
|O3|5 x10$^{11}$|http://www.atmos-chem-phys.net/10/4611/2010/acp-10-4611-2010.html|

We can calculate an e-folding lifetime for a second order bimolecular reaction:

$\tau_{A_x}$ = $\frac{1}{k[B]}$

where A is in this case DMSe and [B] is the concentration of the reactant (OH, O3 or ~NO3)

This gives atmospheric lifetimes wrt each of the reactants as follows: $\tau_\mathrm{OH}$ = 2.9 hr; $\tau_\mathrm{NO3}$ =  2.0 hr; $\tau_\mathrm{O3}$ = 8.16 hr.

An overall lifetime can then be calculated as:

$\tau_A$ = $\frac{1}{\frac{1}{\tau_A1}+\frac{1}{\tau_A2}+\frac{1}{\tau_A3}...}$

which gives an overall night-time lifetime of 1.6 hours and daytime of 2.14 hours. Within the large uncertainties, an overall estimate of ~2 hours seems reasonable.

<<bibliography>>
Below Detection Limit
Seawifs chlorophyll images from: http://oceancolor.gsfc.nasa.gov/cgi/l3

*dimensions: 4320(w) x 2160(h) 
*meridian approx at column 2160  (depends on how column 1 is defined (starting at 0 or 1 degree etc?) - doesn't matter for our current purposes)
*12 pixels per degree (lat and long)
*Need to extract West Antarctic Peninsula area (and later quantify number of pixels where chlorophyll>5ug/L)
* 61.5 to 69.5 S, 80 to 54 West (= 280 to 306 E)
* in pixel-space:
** long:  12*(280-180) to 12*(306-180) =  1200 to 1512
** lat: 12*(90+61.5) to 12*(90+69.5) = 1818 to 1914

using http://nickhumphrey.net/showthread.php?p=3334 we will use gimp to batch crop:

{{{gimp -i -b '(batch-crop "*.png" 313 97 1200 1818)' -b '(gimp-quit 0)'}}}
/***
|Name|BetterTimelineMacro|
|Created by|SaqImtiaz|
|Location|http://tw.lewcid.org/#BetterTimelineMacro|
|Version|0.5 beta|
|Requires|~TW2.x|
!!!Description:
A replacement for the core timeline macro that offers more features:
*list tiddlers with only specfic tag
*exclude tiddlers with a particular tag
*limit entries to any number of days, for example one week
*specify a start date for the timeline, only tiddlers after that date will be listed.

!!!Installation:
Copy the contents of this tiddler to your TW, tag with systemConfig, save and reload your TW.
Edit the ViewTemplate to add the fullscreen command to the toolbar.

!!!Syntax:
{{{<<timeline better:true>>}}}
''the param better:true enables the advanced features, without it you will get the old timeline behaviour.''

additonal params:
(use only the ones you want)
{{{<<timeline better:true  onlyTag:Tag1 excludeTag:Tag2 sortBy:modified/created firstDay:YYYYMMDD maxDays:7 maxEntries:30>>}}}

''explanation of syntax:''
onlyTag: only tiddlers with this tag will be listed. Default is to list all tiddlers.
excludeTag: tiddlers with this tag will not be listed.
sortBy: sort tiddlers by date modified or date created. Possible values are modified or created.
firstDay: useful for starting timeline from a specific date. Example: 20060701 for 1st of July, 2006
maxDays: limits timeline to include only tiddlers from the specified number of days. If you use a value of 7 for example, only tiddlers from the last 7 days will be listed.
maxEntries: limit the total number of entries in the timeline.


!!!History:
*28-07-06: ver 0.5 beta, first release

!!!Code
***/
//{{{
// Return the tiddlers as a sorted array
TiddlyWiki.prototype.getTiddlers = function(field,excludeTag,includeTag)
{
          var results = [];
          this.forEachTiddler(function(title,tiddler)
          {
          if(excludeTag == undefined || tiddler.tags.find(excludeTag) == null)
                        if(includeTag == undefined || tiddler.tags.find(includeTag)!=null)
                                      results.push(tiddler);
          });
          if(field)
                   results.sort(function (a,b) {if(a[field] == b[field]) return(0); else return (a[field] < b[field]) ? -1 : +1; });
          return results;
}



//this function by Udo
function getParam(params, name, defaultValue)
{
          if (!params)
          return defaultValue;
          var p = params[0][name];
          return p ? p[0] : defaultValue;
}

window.old_timeline_handler= config.macros.timeline.handler;
config.macros.timeline.handler = function(place,macroName,params,wikifier,paramString,tiddler)
{
          var args = paramString.parseParams("list",null,true);
          var betterMode = getParam(args, "better", "false");
          if (betterMode == 'true')
          {
          var sortBy = getParam(args,"sortBy","modified");
          var excludeTag = getParam(args,"excludeTag",undefined);
          var includeTag = getParam(args,"onlyTag",undefined);
          var tiddlers = store.getTiddlers(sortBy,excludeTag,includeTag);
          var firstDayParam = getParam(args,"firstDay",undefined);
          var firstDay = (firstDayParam!=undefined)? firstDayParam: "00010101";
          var lastDay = "";
          var field= sortBy;
          var maxDaysParam = getParam(args,"maxDays",undefined);
          var maxDays = (maxDaysParam!=undefined)? maxDaysParam*24*60*60*1000: (new Date()).getTime() ;
          var maxEntries = getParam(args,"maxEntries",undefined);
          var last = (maxEntries!=undefined) ? tiddlers.length-Math.min(tiddlers.length,parseInt(maxEntries)) : 0;
          for(var t=tiddlers.length-1; t>=last; t--)
                  {
                  var tiddler = tiddlers[t];
                  var theDay = tiddler[field].convertToLocalYYYYMMDDHHMM().substr(0,8);
                  if ((theDay>=firstDay)&& (tiddler[field].getTime()> (new Date()).getTime() - maxDays))
                     {
                     if(theDay != lastDay)
                               {
                               var theDateList = document.createElement("ul");
                               place.appendChild(theDateList);
                               createTiddlyElement(theDateList,"li",null,"listTitle",tiddler[field].formatString(this.dateFormat));
                               lastDay = theDay;
                               }
                  var theDateListItem = createTiddlyElement(theDateList,"li",null,"listLink",null);
                  theDateListItem.appendChild(createTiddlyLink(place,tiddler.title,true));
                  }
                  }
          }

          else
              {
              window.old_timeline_handler.apply(this,arguments);
              }
}
//}}}
/***
|''Name:''|BibTeXPlugin|
|''Description:''|Very incomplete BibTeX implementation to work with bibliographic references|
|''Author:''|Paulo Soares|
|''Version:''|1.4|
|''Date:''|2009-11-20|
|''Source:''|http://www.math.ist.utl.pt/~psoares/addons.html|
|''Overrides''|Story.prototype.refreshTiddler|
|''Documentation:''|[[BibTeXPlugin Documentation|BibTeXPluginDoc]]|
|''License:''|[[Creative Commons Attribution-Share Alike 3.0 License|http://creativecommons.org/licenses/by-sa/3.0/]]|
|''~CoreVersion:''|2.5.0|
***/
//{{{
if(!version.extensions.BibTeXPlugin) { //# ensure that the plugin is only installed once
version.extensions.BibTeXPlugin = {installed: true};

(function($) {
config.macros.cite = {
  noReference: "(??)",
  refreshTiddler: Story.prototype.refreshTiddler
};

config.macros.cite.handler = function(place,macroName,params,wikifier,paramString,tiddler) {
  var pos, cmb = config.macros.bibliography;
  if(params.length==0) return;
  var entry = params[0];
  var args = paramString.parseParams(null,null,false);
  var title = getParam(args,"bibliography",null);
  if(title) {
    this.biblioTiddler = title;
  } else {title = this.biblioTiddler;}
  title = getParam(args,"thisBibliography",title);
  var format = getParam(args,"format",null);
  if(format) {
    this.format = format;
  } else {format = this.format;}
  format = getParam(args,"thisFormat",format);
  var argsArray = paramString.readMacroParams();
  var showAll = ($.inArray('showAll',argsArray) > -1);
  if(title && store.tiddlerExists(title)) var bib = cmb.extractEntry(title, entry);
  if(bib.content) {
    var entries = this.entries;
    if($.inArray(entry, entries)==-1) this.entries.push(entry);
    entries = this.entries;
    pos = $.inArray(entry, entries)+1;
    var author = cmb.processNames(bib.content.extract("author"), showAll);
    var year = bib.content.extract("year");
    var citation = format.replace("author", author);
    citation = citation.replace("year", year);
    citation = citation.replace("number", pos);
    wikify(citation, place);
  } else {
    wikify(this.noReference, place);
  }
}

Story.prototype.refreshTiddler = function(title,template,force){
  config.macros.cite.biblioTiddler = null;
  config.macros.cite.format = "author (year)";
  config.macros.cite.entries = [];
  var tiddler = config.macros.cite.refreshTiddler.apply(this,arguments);
  return tiddler;
}

config.macros.bibliography = {
   article: {fields: ["author", "year", "title", "journal", "volume", "pages"], format: "author (year). title. //journal// ''volume'', pages."},
   book: {fields: ["author", "year", "title", "publisher"], format: "author (year). //title//. publisher."},
   inproceedings: {fields: ["author", "year", "title", "editor", "booktitle", "pages", "publisher"], format: "author (year). title. In editor //booktitle//, pages. publisher."},
   incollection: {fields: ["author", "year", "title", "editor", "booktitle", "pages", "publisher"], format: "author (year). title. In editor //booktitle//, pages. publisher."},
   techreport: {fields: ["author", "year", "title", "institution"], format: "author (year). title. Technical report, institution."},
   manual: {fields: ["author", "year", "title", "organization"], format: "author (year). //title//. organization."},
   unpublished: {fields: ["author", "year", "title"], format: "author (year). //title//. Unpublished."}
};

config.macros.bibliography.handler = function(place,macroName,params,wikifier,paramString,tiddler) {
        var cmc = config.macros.cite;
	var title = (cmc.biblioTiddler) ? cmc.biblioTiddler : params[0];
	if(!title || !store.tiddlerExists(title)) return;
        var argsArray = paramString.readMacroParams();
	var i, entryText;
	var entries = [];
	if($.inArray('showAll',argsArray) > -1) {
		entryText = this.extractAllEntries(title);
		for(i=0; i<entryText.length; i++) {
			entries[entries.length] = this.processEntry(entryText[i], i);
		}
	} else {
		for(i=0; i<cmc.entries.length; i++){
			entryText = this.extractEntry(title, cmc.entries[i]);
			if(entryText) {
                                entries[entries.length] = this.processEntry(entryText, i);
			}
		}
	}
	entries.sort();
        wikify(entries[0] , place);
	for (i=1; i < entries.length; i++) {
		wikify("\n\n" + entries[i] , place);
	}
	return true;
}

config.macros.bibliography.processNames = function(names, showAll) {
	var i, authors = names.split(" and ");
	var entry = authors[0];
	var numAuthors = authors.length;
	var fullEntry = entry;
	if (numAuthors==2) {
		entry += " and " + authors[1];
		fullEntry = entry;
	}
	if (numAuthors>2) {
		fullEntry = entry;
		for (i=1; i < numAuthors; i++) {
			if (i==numAuthors-1) {fullEntry += " and "} else {fullEntry += ", "};
			fullEntry += authors[i];
		}
		if(showAll) {entry = fullEntry;} else {entry += " et al.";}
	}
	return entry;
}

config.macros.bibliography.processEntry = function(entry, pos) {
  var field, text=entry.content;
  var fields={};
  fields.number = pos+1;
  var type = this[entry.type];
  var output = type.format;
  for(var i=0; i<type.fields.length; i++){
    field = type.fields[i];
    switch(field){
    case "author":
      fields.author = this.processNames(text.extract("author"), true);
      break;
    case "title":
      var url = text.extract("url");
      fields.title = text.extract("title");
      fields.title = (url=='') ? fields.title : "[[" + fields.title + "|" + url + "]]";
      break;
    case "editor":
      var editor = text.extract("editor");
      fields.editor = (editor=='') ? editor : this.processNames(editor,true) + " (Eds.), ";
      break;
    default:
      fields[field] = text.extract(field);
    }
    output = output.replace(field, fields[field]);
  }
  return output;
}

config.macros.bibliography.extractEntry = function(title,entry) {
    var bib = {type: null, content: null};
    var text = store.getTiddlerText(title);
    var re = new RegExp('\\s*@(\\w+?)\\{\\s*' + entry + '\\s*,\\s*(.[^@]+)\\}','mi');
    var field = text.match(re);
    if(field) {
        bib.type = field[1].toLowerCase();
        bib.content = field[2];
    }
    return bib;
}

config.macros.bibliography.extractAllEntries = function(title) {
    var bib, field, entries = [];
    var text = store.getTiddlerText(title);
    var bibs = text.match(/\s*@(\w+?)\{\s*(.[^@]+)\}/mgi);
    for(var i=0; i<bibs.length; i++){
        field=bibs[i].match(/\s*@(\w+?)\{\s*(.[^@]+)\}/mi);
        bib = {type: null, content: null};
        if(field) {
            bib.type = field[1].toLowerCase();
            bib.content = field[2];
            if(bib.type!='string' && bib.type!='preamble' && bib.type!='comment') entries.push(bib);
        }
    }
    return entries;
}

config.macros.bibliography.extractField = function(field) {
    var text = "";
    var re = new RegExp('\\s*'+field+'\\s*=\\s*[\\{|"]\\s*(.+?)\\s*[\\}|"],','mi');
    var fieldText = this.match(re);
    if(fieldText){
        text = fieldText[1].replace(/\{|\}/g,'');
        text = text.replace(/-+/g,"—");
    }
    return text;
}

String.prototype.extract = config.macros.bibliography.extractField;

config.shadowTiddlers.BibTeXPluginDoc="The documentation is available [[here.|http://www.math.ist.utl.pt/~psoares/addons.html#BibTeXPluginDoc]]";
})(jQuery)
}
//}}}
!Description
Very incomplete (and personal) ~BibTeX implementation to work with bibliographic references.
!Usage
First of all, you need to dump your ~BibTeX entries in a tiddler, lets say [[Bibliography]]. The first macro that this plugin provides is {{{cite}}}. As the name suggests it is used to cite a reference such as {{{<<cite Nea:03>>}}} where {{{Nea:03}}} is a ~BibTeX key for a reference. By default it produces this: <<cite Nea:03 bibliography:Bibliography>>.

However, as this was the first citation in this tiddler you must include the name of the tiddler that contains the ~BibTeX entries like this {{{<<cite Nea:03 bibliography:Bibliography>>}}}.

The {{{cite}}} macro produces a full reference if there are at most two authors, otherwise it is abbreviated like this: <<cite Coda:97>>. If you want to force a full reference then you can use  the {{{showAll}}} parameter as in {{{<<cite Coda:97 showAll>>}}} which produces this: <<cite Coda:97 showAll>>.

You can also change the way references are displayed with the {{{format}}} parameter. A string can be passed to this parameter where {{{number}}} represents the order of the citation {{{author}}} stands for the authors and {{{year}}} represents the year of publication. So, for example, including {{{format:"([number] author, year)"}}} in a citation would produce citations formatted as <<cite Nea:03 format:"([number] author, year)">>. The format string can even include Tiddlywiki notation such as {{{format:"@@author@@, ''year''"}}} leading to <<cite Nea:03 format:"@@author@@, ''year''">>.

The {{{bibliography}}} and {{{format}}} parameters affect the reference in which they are used and all the following ones. If you need to restrict the scope to a single reference you can use the {{{thisBibliography}}} and {{{thisFormat}}} variants.
 
The production of a list of cited references is done with the {{{bibliography}}} macro. If you want to make a list of all your ~BibTeX entries then use {{{<<bibliography Bibliography showAll>>}}}.

<<bibliography>>
{{{

@article{Copolovici2005,
author = {Copolovici, Lucian O. and Niinemets, \"{U}lo},
doi = {10.1016/j.chemosphere.2005.05.003},
journal = {Chemosphere},
month = dec,
number = {10},
pages = {1390--1400},
title = {{Temperature dependencies of Henry's law constants and octanol/water partition coefficients for key plant volatile monoterpenoids}},
volume = {61},
year = {2005}
}

@BOOK{miller2000,
 title = {Statistics and Chemometrics for Analytical Chemistry},
 publisher = {Prentice Hall},
 year = {2000},
 author = {Miller, J.N. and Miller, J.C.},
 edition = {4th},
}

@ARTICLE{vlahos2009,
 title = {A generalized model for the air-sea transfer of dimethyl sulfide at high wind speeds},
 volume = {36},
 url = {http://dx.doi.org/10.1029/2009GL040695},
 number = {21},
 journal = {Geophys. Res. Lett.},
 author = {Penny Vlahos and Edward C. Monahan},
 year = {2009},
 pages = {L21605}
}

@ARTICLE{johnson2010,
 author = {Johnson, M. T.},
 title = {A numerical scheme to calculate temperature and salinity dependent air-water transfer velocities for any gas},
 journal = {Ocean Science},
 volume = {6},
 year = {2010},
 number = {4},
 pages = {913--932},
 url = {http://www.ocean-sci.net/6/913/2010/},
 doi = {10.5194/os-6-913-2010}
}

@INCOLLECTION{johnson2011,
 author = {Martin T. Johnson and Claire Hughes and Thomas G. Bell and Peter S. Liss},
 title={A Rumsfeldian analysis of uncertainties in air-sea gas exchange}, 
 booktitle={Proceedings of the 6th International Symposium on Gas Transfer at Water Surfaces, Kyoto, May 2010}, 
 editor={S. Komori and W. R. McGillis},
 publisher={Kyoto University Press}, 
 year={2011},
 pages = {in press}
 url = {http://researchpages.net/pulications/725/},
}

@ARTICLE{yool2007, 
 title={The significance of nitrification for oceanic new production.}, 
 volume={447}, 
 url={http://www.ncbi.nlm.nih.gov/pubmed/17581584}, 
 number={7147}, 
 journal={Nature}, 
 author={Yool, Andrew and Martin, Adrian P and Fernández, Camila and Clark, Darren R},  
 year={2007}, 
 pages={999-1002}
}

@article{Ginestet1998, 
 title={Estimation of Nitrifying Bacterial Activities by Measuring Oxygen Uptake in the Presence of the Metabolic Inhibitors Allylthiourea and Azide}, 
 volume={64}, 
 url={http://www.pubmedcentral.nih.gov/articlerender.fcgi?artid=106310&tool=pmcentrez&rendertype=abstract}, 
 number={6}, 
 journal={Applied and Environmental Microbiology}, 
 author={Ginestet, Philippe and Audic, Jean-Marc and Urbain, Vincent and Block, Jean-Claude}, 
 year={1998}, 
 pages={2266-2268}
}

@article{johnson2008, 
 title={Field observations of the ocean-atmosphere exchange of ammonia: Fundamental importance of temperature as revealed by a comparison of high and low latitudes}, 
 volume={22}, 
 url={http://www.agu.org/pubs/crossref/2008/2007GB003039.shtml},
 journal={Global Biogeochemical Cycles}, 
 author={Johnson, Martin T and Liss, Peter S and Bell, Thomas G and Lesworth, Timothy J and Baker, Alex R and Hind, Andrew J and Jickells, Timothy D and Biswas, Karabi F and Woodward, E Malcolm S and Gibb, Stuart W}, 
 year={2008}, 
 pages={GB1019}
}

@article{atkinson1990,
author={Atkinson, Roger and Aschmann, Sara M and Hasegawa, David},
title={Kinetics of the atmospherically important reactions of dimethyl selenide},
journal={Environ. Sci. Technol.},
volume={24},
year={1990},
pages={1326–1332},
doi={10.1021/es00079a005}
}


}}}
//{{{
var daysOrPosts = "posts";
var numOfDaysOrPosts = "20";
var restrictTag = "dontBlog";

function displayTopTiddlers()
 {
  if(window.location.hash) daysOrPosts = "";
  if(daysOrPosts == "posts")
  {
   var tiddlerNames = store.reverseLookup("tags","systemTiddlers",false,"modified");
   if (tiddlerNames.length < numOfDaysOrPosts)
    numOfDaysOrPosts = tiddlerNames.length;
    for(var t = tiddlerNames.length-numOfDaysOrPosts;t<=tiddlerNames.length-1;t++)
   if (restrictTag == "" || !tiddlerNames[t].isTagged(restrictTag))
    story.displayTiddler("top",tiddlerNames[t].title,DEFAULT_VIEW_TEMPLATE,false,false);
  }
  if (daysOrPosts == "days")
  {
   var lastDay = "";
   var tiddlerNames = store.reverseLookup("tags","systemTiddlers",false,"modified");
   var t = tiddlerNames.length -1;
   var tFollower = 0;
   for(tFollower = tFollower+1; tFollower < tiddlerNames.length;tFollower++){
    if (restrictTag == "" || !tiddlerNames[tFollower].isTagged(restrictTag))
    displayTiddler("top",tiddlerNames[tFollower].title,DEFAULT_VIEW_TEMPLATE,false,false);
   }

  }
 }

window.original_restart = window.restart;
window.restart = function()
{
window.original_restart();
displayTopTiddlers();
}
//}}}
Bit late, but here's what was actually done:

Aimed for a 300 to 500 nM spike in NH4+ due to addition of ammonium chloride, using 10mM NH4Cl solution dliuted approx 1:10

Treatments:

|!no. | !water vol / ml | !~NHx (1mM) vol / ml | !treatment | !resulting ~NHx increse / uM |
|Water overlying Tyne sediment cores|>|>|>|>|
| 1 | 40 | 0.2 | 0.3ml ATU35m.001 | 4.6 |
| 2 | 40 | 0.2 | 0.3ml ATU35m.001 | 4.6 |
| 3 | 40 | 0.2 | - | 4.6 |
| 4 | 40 | 0.2 | - | 4.6 |
|~MilliQ|>|>|>|>|
| 5 | 40 | 0.75 | - | 18.75 |
|Station 107 surface water|>|>|>|>|
| 6 | ~450 | 0.2 | - | 0.44 |
| 7 | ~450 | 0.2 | 5ml ATU35m.001 | 0.44 |
| 8 | ~450 | 0.2 | 2.5ml AZ14m.001 | 0.44 |
| 9 | ~450 | 0.2 | tyne sediment bacteria 1ml | 0.44 |
|Station 107 middle water|>|>|>|>|
| 10 | ~450 | 0.2 | - | 0.44 |
| 11 | ~450 | 0.2 | 5ml ATU35m.001 | 0.44 |
| 12 | ~450 | 0.2 | 2.5ml AZ14m.001 | 0.44 |
| 13 | ~450 | 0.2 | tyne sediment bacteria 1ml | 0.44 |
|Station 107 bottom water|>|>|>|>|
| 14 | ~450 | 0.2 | - | 0.44 |
| 15 | ~450 | 0.2 | 5ml ATU35m.001 | 0.44 |
| 16 | ~450 | 0.2 | 2.5ml AZ14m.001 | 0.44 |
| 17 | ~450 | 0.2 | tyne sediment bacteria 1ml | 0.44 |
|West Gabbard surface water|>|>|>|>|
| 18 | ~900 | 0.4 | 4ml AZ14m.001 | 0.44 |
| 19 | ~900 | 0.4 | 8ml ATU35m.001 | 0.44 |
| 20 | ~900 | 0.4 | 8ml ATU35m.001 | 0.44 |
| 21 | ~900 | 0.4 | 8ml ATU35m.001 | 0.44 |
| 22 | ~900 | 0.4 | - | 0.44 |
| 23 | ~900 | 0.4 | - | 0.44 |
| 24 | ~900 | 0.4 | - | 0.44 |
| 25 | ~900 | 0.4 | Tyne sediment bacteria 2ml | 0.44 |
| 26 | ~900 | 0.4 | Tyne sediment bacteria 2ml | 0.44 |
| 27 | ~900 | 0.4 | Tyne sediment bacteria 2ml | 0.44 |

!!!Notes

* oops - added way too much ammonium to the sediment cores. Not enough sleep!
** particularly to the ~MilliQ tracer / control
* all samples calibrated using the w.gabbard incubations: 
** the following were used for calibration by standard additions at each time point for the ammonium analysis:
** t=0 18,19,22,25
** t=4 20,23,26
** t=8 21,24,27
** t=21 18,19,22,25
** t=50 18,20,23,26
* single 12ml samples were taken from each time point and incubation for nutrient analysis and killed with 30uL of 16g/L HgCl2 solution. Stored in 4 degree room
* Incubations killed with appropriate volume of HgCl2 at t=55 hours and brought back fro future analysis if required.
What we've got:

* 10L of water from West Gabbard storage experiment (from the non toxic supply not the CTD cast), which has ~30nM NH$_4$. CTD ammoniums suggested 0±14 and 20 ±14 nM (i.e. very low throughout).
* Bottom water from Fay and Charlie's Tyne core sampling. There is maybe 150ml tops of water available. It was high in ammonium at the time of sampling and higher after resuspension experiments (up to 5uM max). I'm measuring it's current concentration at the moment: [[Tyne sediment core water and stored low ammonium water concentrations for nitrification experiment 2]].
** the ammoniums from CTD taken at the same time as the cores (just surface and bottom bottles as usual): both my and Fay's deep bottle samples (3m from bottom) show approx 0.5uM concentrations, my surface measurement shows 0.06 uM so there was a really steep gradient. Shame there's no top water anywhere..,
* 2L of top middle and bottom water from Stn 107 (10 nM surface, 80nM deep NHx) which has been stored in the dark at 4 oC.
* 150ml bacteria-rich resuspended sediment from the tyne cores (biofilms growing on the sides of the centrifuge tubes after 3 days!)

!!! Hypothesis: Ammonium released from sediment during resuspension is associated with release of nitrifiying bacteria which rapidly nitrify the release ammonia preventing accumulation in the water column

We can test this with a series of low NH4 concentration experiments (less than 500uM) with the various waters and the bacteria. We will test the following combinations and measure the following time points and analytes:

# Tyne sediment water -  aerated (and spiked if NH4 concentration is low) 
** untreated
** allylthiourea
** duplicate samples of treatement (hopefully 30ml+ in each one)
** sampled at t=0, t=24 and t=48 for ammonium ammonium
*** rely on calibration gradients from the other samples
*** just take 5ml samples

# Top, middle and bottom waters from station 107 (aerated and spiked with 300nM ammonium)
** untreated
** allylthiourea
** azide
** sediment bacteria
** single 500ml incubations of each treatment will allow high volume samples which increases precision
*** need to find some suitable containers. 1L red topped plastic bottles if nothing else
*** 30ml samples for NH4 at t=0, t=12, t=24, t=36, t=48
*** 15ml filtered HgCl2 treated samples for NO2/NO3 from t=0 t=24 and t=48

# Gabbard storage water (aerated and spiked with 300nM ammonium)
** untreated
** allylthiourea
** azide
** bacteria
** single 1 litre incubation for azide, triplicate 1 litre incubations for the others
*** NH4 calibrated by standard additions to one bottle at each time point - t = 0, t=12, t=24, t=36, t=48
*** no2/no3 samples (filtered HgCl2 treated) taken from each bottle at each timepoint (15ml)

Therefore we need:

* 164 x 50ml centrifuge tubes
* 100 x 15ml centrifuge tubes
* 12 x 500ml or greater containers for Stn 107 incubations
* 86 x filters and syringes
* 10 1L darkened bottles








N1: using water from Stn 16 (surface sample), taken at 11am and sampled into experiment treatments within 1hr
* Added 0.5ml of 10mM NH4 stock to sample bottle
* Did extra treatment of HgCl2 to water with no NH4+ spike added (by accident!)
* samples for NH4 analysis: 
** 5ml sample 
** 0,50,100,150,250 and 500uL additions of 50uM stock
** 2ml working reagent 
* t=3 was sampled between 2 and 3pm (3-4 hours after CDT went down) - sampling and calibrating all >50 samples was time consuming, and used a lot of sample tubes
** t=3  analysed 18:00 9/2/2011
** note that HgCl2 treated samples displayed about 1 o.o.m. less fluorescence than those not treated and that they appeared to have a lighter blue colour when fluorescing. Emission scanning showd a very broad emission peak with a maximum of about double the fluorescence at 420nm at about 480 nm. Nonetheless samples were run at 420 for consistency. This effect may be due to the concentration of HgCl2, or the amount of time that the samples were left to react for after innoculation with working reagent. ASAP Analysis of t=12 and t=29 will tell.
* t=12 sampled at 23:30 8/2/2011
** used used separate replicates for each member of standard addition to save on sample tubes - will see how it looks
** calibration was 6 member so one tube will have to be used twice - in this case the B tubes were use for both the 50uL and 500uL addition.
* t=29 sampled as per t=12 at 15:30 9/2/2011
** HgCl2 no NH4 bottle D had leaked and is out of the game -> calibration used 2 aliquots of E.
** Tube C used twice in calibration for each treatment

After t=29 we can't see any sigfnificant nitrification, but given the precision we're getting with the method at the moment that's not entirely surprising - +/- 10 to 20 %! We need to get this down on future experiments if we're going to constrain nitrification to any useful extent. Also, seeing some positive nitrification signal would be really good.... we'll see what t=48 brings.

update: t=48 brought much of the same. See [[CEND311 Nitrification problems]]

 
The [[previous nitrification experiment|CEND311 Nitrification experiments]] on board was a washout because we couldn't distinguish any changes in any of the treatments against the large uncertainty in the calibrated concentrations. This is essentially because the method isn't actually that good for fine scale changes in larger concentrations (>1 uM). So basically, any small nitrification signal was lost, if it was there at all; and we can't constrain that to a meaningful maximum value.

This is all compounded by the conditions, about which we've learned a lot whilst analysing samples on board (which has made for a pretty insane workload but otherwise we'd be operating blind and probably end up coming back with nothing useful from these experiments, and poorly calibrated bottle samples throughout). We now know the following:

# Ammonium concentrations have been very low for the majority of the stations - routinely <75 nM and reasonably often below the detection limit of the method (<10 nM), typically with lower concentrations at the surface than at the bottom of the water column
# Concentrations at the bottom of the CTD casts (normally 3m above the sea floor)  have often been at a similar concentration to the low surface values, sometimes even BDL; however, sometimes they have been considerably higher than at the surface. 

Specifically, from the first 10 CTD stations analysed:
*  measured ~NHx was < 0.1 uM somewhere in the water column at all but one station
*  concentrations were about the same (or below detection limit) at both top and bottom at 4 stations
*  concentrations significantly higher (more than double) at the bottom than at the surface in 6 cases (> 1 OOM in 5 cases)


What makes the OPAMethod awesome is that it's fantastic at being really sensitive and precise at low concentrations, which is mostly what we've observed, so it seems sensible that we should try nitrification experiments at much lower concentrations, possibly even at the ambient, although not where that's at 50 nM or less.

Also, based on Fay and Charlie's resuspension experiments with benthic cores, it seems clear that the sediment is very rich in ammonium (no surprises), so this is probably the source of the ammonium at the bottom in the stations where it's higher. Also, they observe spikes in ammonium which decrease quite quickly after their resuspension events, suggesting nitrification. Therefore it must be asked whether the ammonium released into the water column is more broadly nitrified. If not where does it go? Is it just diluted away, consumed by nitrogen-hungry heterotrophic bacteria or (re)adsorbed to sediment particles before they sink out? Hopefully we can design an experiment that a) will work and b) will answer some of these questions.

Unfortunately we've departed the North Sea for the English channel this afternoon, where the regime may well be completely different. Fortunately we have some CDT surface and bottom water and sediment core over-water left over from a couple of places so we should be able to make it work. We'll adapt it to our new environment as soon as we know something about it (this evening hopefully).

So, a [[new experiment plan|CEND311 Nitrification experiments 2]] is needed...

!!Deck tank #1
*Hosing and connectors for on-deck incubators
*10x 1L Nalgene Amber bottles
*2x gaffer tape
*Bin bags
*tin foil

!!Deck tank #2
*40x 300ml glass winchester bottles for DON samples

!!Deck tank #3
*40x 300ml glass winchester bottles for DON samples
 
!!Cool box
*10x 1l clear plastic bottles for 15N nitrification experiments
 
!!Small alumininum crate
*700x 15m centrifuge tubes
*3x yellow tape
*permanent markers
*autodispenser and 250ml Duran bottle
*Nutrafin Cycle
*20x 20ml disposable syringes

!!Fluorometer box
*fluorometer

!!Big ali crate (PSL12)
*Blue roll x8
*12x 1l plastic bottles
*glove liners
*nitrile gloves (bridal white!)
*pipette tips
*laptop for fluorometer
*cuvettes
*filtration stuff
*stationary
*ammonium standards
*ziplock bags
*milliQ squirter bottle
*lab coat
*safety specs
*boiler suit
*sample holder

!!!DON sampling
* KIT LIST
** 2x300ml Winchesters (stored in CT room)
** 16g/L HgCl2
** 200-1000uL HgCl2 pipette
** 200um mesh 'filter'
** marker pen

# Always wear clean gloves during sampling
# take samples from top and bottom depths at each CTD station, occasionally take triplicates from separate Niskin bottles
# sample into 300ml winchester bottles (clear glass), using 200um mesh
# Rinse bottle 3 times with small volume of fresh sample water (through mesh)
# Add 0.6ml HgCl2 solution (16 g/L) to bottle
# Fill to lip with sample (unfiltered)
# Label bottle according to following convention CEND311/<station number>/<depth>_m/
# also write operator name on bottle
# Take fresh ammonium samples corresponding to every DON sample

!!!NH4 samples from CDT
* KIT LIST
** 15ml centrifuge tubes
** Working reagent bottle with autodispenser
** 200-1000uL non-HgCl2 pipette
# Always wear clean gloves during sampling and sample processing.
# rinse 3 times and fill 3 15ml centrifuge tubes with unfiltered sample water  to the 10ml line (exactly) - this may be easiest using a 50ml centrifuge tube
# to 1 of the 3 samples, add 200uL of 50uM stock ammonium chloride standard
# To all 3 of the samples, add 1ml of ammonium working reagent using the auto-dispenser (check volume setting)
# Cap and invert tubes (to mix fully) and store in the dark in the dry lab for later analysis  

!!!Nitrification experiments

# Clean gloves etc
# sample into 1L plastic bottle, using 200um mesh
# Rinse bottle 3 times with small volume (~50ml) of fresh sample water (through mesh)
# Add sufficient 10mM ammonium chloride to increase ammonium concentration in seawater by approx 1 oom
** 0.125ml  gives ~ 1uM NH4 increase when the bottle is filled to the brim with sample
** typically expect 0.5ml (5uM increase)
# Fill bottle to brim-full with mesh-filtered sample
# Remove caps from all 25 pre-prepared centrifuge tubes and fill to 50ml line from bottle
** 5x tubes containing 150ul 16g/l HgCl2 (labelled HgCl2)
** 5 empty tubes (labelled "-")
** 5 tubes containing ~300uM allylthiourea (labelled ATU) 
*** 0.4 ml ATU35m.001
** 5 tubes containing ~50 uM sodium azide (labelled AZ)
*** 0.2ml of AZ14m.001
** 5 tubes containing 50uL nitrifying bacteria (labelled bact)
*** DON'T USE HgCl2 pipette for the bacteria!!
# incubate tubes in the dark in a tank on deck with surface seawater from the ship's pumped supply flowing through to keep T similar to surface water (typically 5 celcius at this time of year)
# sample each tube for NH4+ at 3 or ideally 4 time points over 48 hours
** calibrate by standard additions using one tube from each treatment each time
** calibrate with 50, 100, 150, 250 and 500 uL of 50uM stock NH4Cl standard to 5ml of sample
** innoculate with 2ml ammonium working reagent and analyse on fluorometer as usual.

         
!!CEND 3/11 cruise report – Martin Johnson and Douglas Hamilton, UEA Norwich

Samples were taken from CTDs and steam-throughs for ammonium (NH4+) and total nitrogen (TN). Ammonium samples were analysed on board using the 'OPA' fluorescence method with the UEA Jasco FP-750 fluorometer. TN samples were 200uM mesh screened, sampled into 300ml glass sample bottles and 'killed' with 0.6ml 16g/L mercuric chloride solution (HgCl2) for later analysis  of nitrogen species using the OPA method (for NH4+), colourimetric analysis (for nitrate and nitrite; NO3- and NO2-) and high temperature catalytic oxidation for TN. Alongside these samples we also conducted 2 incubation experiments to quantify nitrification rates in surface and bottom waters, using inhibitors of the two nitrification pathways (NH4+ to NO2- and NO2- to NO3-). NH4 concentrations were analaysed on board and samples have been collected and preserved with HgCl2 for NO2- / NO3- analysis in the laboratory on our return.  

At each SMARTBuoy station we also used 2 SMARTBuoy water samplers (one Envirotech AquaMonitor and one CEFAS-built 'E.D.U.' sampler) to take 10 or 15 water samples from a large tank (a water butt!) full of water from the ship's pumped seawater supply, from which we also took fresh and preserved bottle samples. We will analyse these over time for all of the nitrogenous analytes listed above to confirm that the SMARTBuoy samples, after preservation and storage, give a representative concentration for these analytes.

Finally, we mounted a particle impactor aerosol collector on the monkey island to collect atmospheric aerosol samples for analysis byDr Alex Baker's group at UEA. This was with mixed success as the variable wind and slow forward progress made during manta trawls meant that contamination from the ship's stack was a problem. 
Calibration of pipettes used during CEND311 at close to ship's lab ambient temperature (~15C)

density of pure water at 15 celcius (according to <<cite johnson2010 bibliography:Bibliography>>) = 999.1016 kg/m$^3$

!!!!5ml:

5.0276
5.0193
4.9841
4.9763
4.9949	mean: 5.0004g @ 15C = 4.996ml


!!!!25 ul:
.0241
.0255
.0254
.0254
.0262
.0247
.0255
.0256
.0246
.0246        mean: 0.02516g @ 15C = 25.14 uL

!!!!200ul/50:
.0501
.0520
.0510
.0505
.0509
.0500
.0507
.0507
.0507
.0512    mean = .05078g @ 15C = 50.73 uL

!!!!200ul/75:
.0759
.0774
.0757
.0773
.0754
.0765
.0754
.0767
.0766
.0754     mean = .07623 @ 15C = 76.16 uL

!!!!/100:

.1009
.1007
.1010
.0990
.1020    mean = .10072 @ 15C = 100.63 uL

!!!!/150:
.1490
.1538
.1513
.1519
.1512
.1534
.1517
.1545
.1521
.1502   mean = .15191g @ 15C = 151.77 uL

!!!!1000ul/300
.3070
.3075
.3075
.3090
.3077
.3096
.3060
.3061
.3040
.3063
.3076    mean = .307118g @ 15C = 0.30684 ml

<<bibliography>>
!! ~NH4 fresh samples

Link to google spreadsheet when uploaded

!! Glass bottle samples stored for TN, nutrients and ~NH4

Link to google spreadsheet when uploaded
SMARTBUOY ARCHIVE #1
Samples analysed already for TN

Dowsing 9,10,11,13
Celtic deep 6
Warp 82

SMARTBUOY ARCHIVE #2

Liverpool Bay 60,61,62,63,64
Oyster grounds 30
Warp 82,86,89
West Gabbard 64,66

SMARTBUOY ARCHIVE  #3
Warp 80
West Gabbard 68,70,72

4 boxes CEND 311 TN samples 4x20 300ml winchesters

1 coolbox containing SMARTYBUOY storage test samples (~120)

All of the above preserved with HgCl2!
/***
|Name|CollapseTiddlersPlugin|
|Source|http://www.TiddlyTools.com/#CollapseTiddlersPlugin|
|Version|2.0.0|
|Author|Eric Shulman|
|OriginalAuthor|Bradley Meck - http://gensoft.revhost.net/Collapse.html|
|License|unknown|
|~CoreVersion|2.1|
|Type|plugin|
|Requires|CollapsedTemplate|
|Description|show/hide content of a tiddler while leaving tiddler title visible|
This plugin provides commands to quickly switch a rendered tiddler between its current ViewTemplate display and a minimal display (title and toolbar) defined by a separate CollapsedTemplate.
!!!Usage
<<<
In [[ToolbarCommands::ViewToolbar|ToolbarCommands]], add:
{{{
collapseTiddler collapseOthers
}}}
you can also embed the following macros in tiddler content:
*{{{<<collapseAll>>}}} - adds 'collapse all' command that applies CollapsedTemplate to each displayed tiddler
*{{{<<expandAll>>}}} - adds 'expand all' command that re-applies ViewTemplate (or equivalent custom template) to each displayed tiddler
*{{{<<foldFirst>>}}} - immediately apply CollapsedTemplate to a given tiddler, as soon as it is displayed.
<<<
!!!Revisions
<<<
2009.05.04 [2.0.0] standardized documentation and added version #
2008.10.05 collapseAll() and expandAll(): added "return false" to button handlers to prevent IE page transition
2008.03.06 refactored all code for size reduction, readability, and I18N/L10N-readiness.  Also added 'folded' flag to tiddler elements (for use by other plugins that need to know if tiddler is folded (e.g., [[SinglePageModePlugin]]
2007.10.11 moved [[FoldFirst]] inline script and converted to {{{<<foldFirst>>}}} macro
2007.12.09 suspend/resume SinglePageMode (SPM/TPM/BPM) when folding/unfolding tiddlers
2007.05.06 add "return false" at the end of each command handler to prevent IE 'page transition' problem.
2007.03.30 add a shadow definition for CollapsedTemplate.  Tweak ViewTemplate shadow so "fold/unfold" and "focus" toolbar items automatically appear when using default templates.  Remove error check for "CollapsedTemplate" existence, since shadow version will now always work as a fallback.
2006.02.24 added fallback to "CollapsedTemplate" if "WebCollapsedTemplate" is not found
2006.02.06 added check for 'readOnly' flag to use alternative "WebCollapsedTemplate"
<<<
!!!Code
***/
//{{{
version.extensions.CollapseTiddlersPlugin= {major: 2, minor: 0, revision: 0, date: new Date(2009,5,4)};

config.shadowTiddlers.CollapsedTemplate=
	"<!--{{{-->\
	<div class='toolbar' macro='toolbar expandTiddler collapseOthers closeTiddler closeOthers +editTiddler permalink references jump'></div>\
	<div class='title' macro='view title'></div>\
	<!--}}}-->";

// automatically tweak shadow ViewTemplate to add "collapseTiddler collapseOthers" commands
config.shadowTiddlers.ViewTemplate=config.shadowTiddlers.ViewTemplate.replace(/closeTiddler/,"collapseTiddler collapseOthers closeTiddler");

config.commands.collapseTiddler = {
	text: "fold",
	tooltip: "Collapse this tiddler",
	collapsedTemplate: "CollapsedTemplate",
	webCollapsedTemplate: "WebCollapsedTemplate",
	handler: function(event,src,title) {
		var e = story.findContainingTiddler(src); if (!e) return false;
		// don't fold tiddlers that are being edited!
		if(story.isDirty(e.getAttribute("tiddler"))) return false;
		var t=config.commands.collapseTiddler.getCollapsedTemplate();
		config.commands.collapseTiddler.saveTemplate(e);
		config.commands.collapseTiddler.display(title,t);
		e.setAttribute("folded","true");
		return false;
	},
	getCollapsedTemplate: function() {
		if (readOnly&&store.tiddlerExists(this.webCollapsedTemplate))
			return this.webCollapsedTemplate;
		else
			return this.collapsedTemplate
	},
	saveTemplate: function(e) {
		if (e.getAttribute("savedTemplate")==undefined)
			e.setAttribute("savedTemplate",e.getAttribute("template"));

	},
	// fold/unfold tiddler with suspend/resume of single/top/bottom-of-page mode
	display: function(title,t) {
		var opt=config.options;
		var saveSPM=opt.chkSinglePageMode; opt.chkSinglePageMode=false;
		var saveTPM=opt.chkTopOfPageMode; opt.chkTopOfPageMode=false;
		var saveBPM=opt.chkBottomOfPageMode; opt.chkBottomOfPageMode=false;
		story.displayTiddler(null,title,t);
		opt.chkBottomOfPageMode=saveBPM;
		opt.chkTopOfPageMode=saveTPM;
		opt.chkSinglePageMode=saveSPM;
	}
}

config.commands.expandTiddler = {
	text: "unfold",
	tooltip: "Expand this tiddler",
	handler: function(event,src,title) {
		var e = story.findContainingTiddler(src); if (!e) return false;
		var t = e.getAttribute("savedTemplate");
		config.commands.collapseTiddler.display(title,t);
		e.setAttribute("folded","false");
		return false;
	}
}

config.macros.collapseAll = {
	text: "collapse all",
	tooltip: "Collapse all tiddlers",
	handler: function(place,macroName,params,wikifier,paramString,tiddler){
		createTiddlyButton(place,this.text,this.tooltip,function(){
			story.forEachTiddler(function(title,tiddler){
				if(story.isDirty(title)) return;
				var t=config.commands.collapseTiddler.getCollapsedTemplate();


				config.commands.collapseTiddler.saveTemplate(tiddler);
				config.commands.collapseTiddler.display(title,t);
				tiddler.folded=true;
			});
			return false;
		})
	}
}

config.macros.expandAll = {
	text: "expand all",
	tooltip: "Expand all tiddlers",
	handler: function(place,macroName,params,wikifier,paramString,tiddler){
		createTiddlyButton(place,this.text,this.tooltip,function(){
			story.forEachTiddler(function(title,tiddler){
				var t=config.commands.collapseTiddler.getCollapsedTemplate();
				if(tiddler.getAttribute("template")!=t) return; // re-display only if collapsed
				var t=tiddler.getAttribute("savedTemplate");
				config.commands.collapseTiddler.display(title,t);
				tiddler.folded=false;
			});
			return false;
		})
	}
}

config.commands.collapseOthers = {
	text: "focus",
	tooltip: "Expand this tiddler and collapse all others",
	handler: function(event,src,title) {
		var e = story.findContainingTiddler(src); if (!e) return false;
		story.forEachTiddler(function(title,tiddler) {
			if(story.isDirty(title)) return;
			var t=config.commands.collapseTiddler.getCollapsedTemplate();
			if (e==tiddler) t=e.getAttribute("savedTemplate");
			config.commands.collapseTiddler.saveTemplate(tiddler);
			config.commands.collapseTiddler.display(title,t);
			tiddler.folded=(e!=tiddler);
		})
		return false;
	}
}

// {{{<<foldFirst>>}}} macro forces tiddler to be folded when *initially* displayed.
// Subsequent re-render does NOT re-fold tiddler, but closing/re-opening tiddler DOES cause it to fold first again.
config.macros.foldFirst = {
	handler: function(place,macroName,params,wikifier,paramString,tiddler){
		var e=story.findContainingTiddler(place);
		if (e.getAttribute("foldedFirst")=="true") return; // already been folded once
		var title=e.getAttribute("tiddler")
		var t=config.commands.collapseTiddler.getCollapsedTemplate();
		config.commands.collapseTiddler.saveTemplate(e);
		config.commands.collapseTiddler.display(title,t);
		e.setAttribute("folded","true");
		e.setAttribute("foldedFirst","true"); // only when tiddler is first rendered
		return false;
	}
}
//}}}
<!--{{{-->
<!--
|Name|CollapsedTemplate|
|Source|http://www.TiddlyTools.com/#CollapsedTemplate|
|Version||
|Author|Eric Shulman|
|License|http://www.TiddlyTools.com/#LegalStatements|
|~CoreVersion|2.1|
|Type|template|
|Requires|ToolbarCommands|
|Description|alternative to ViewTemplate, used by CollapseTiddlersPlugin to display tiddler when 'folded'|
-->
<span class='toolbar' macro='toolbar [[ToolbarCommands::CollapsedToolbar]]'></span>
</span>
<span class='title'>
	<span class='floatleft' macro='tiddlerIcons' style='cursor:auto !important;'></span>
	<span macro='view title'></span>
</span>
<div class='tagClear'></div>
<!--}}}-->
/***
|Name|ColumnCalculatorPlugin|
|Source|http://www.TiddlyTools.com/#ColumnCalculatorPlugin|
|Version|0.6.2|
|Author|Eric Shulman|
|License|http://www.TiddlyTools.com/#LegalStatements|
|~CoreVersion|2.1|
|Type|plugin|
|Description|calculate values from table cells in a column|
|Status| ALPHA - USE AT YOUR OWN RISK |
!!!Usage
<<<
{{{<<columncalc function startrow endrow>>}}}
where:
*''function'' is a keyword that specifies the type of calculation to perform:
** ''total'' or ''sum'' or //no param//<br>adds up values for cells above it in the column
** ''count''<br>number of non-empty cells in column
** ''average'' or ''avg''<br>average of cells in column (i.e., total/count)
* ''all'' (optional)<br>normally, only cells containing numbers or timestamps (hh:mm:ss) are included in the calculations.  The ''all'' keyword allows text or empty cells to be processed as if they contained a "0".
* ''startrow'',''endrow'' (optional)<br>specifies a ONE-based range of rows for limiting the calculation.  Use negative numbers to specify an offset from the current row (e.g., {{{<<calc sum 3 5>>}}} adds up rows 3, 4 and 5, while {{{<<calc sum 1 -1>>}}} adds up all numbers in the column excluding the current row (i.e., the same as the default if no startrow/endrow params are specified)
<<<
!!!Examples
<<<
''with numeric values...''
{{{
| foo| 3.2 |
| bar| 1.1 |
| baz| 2.9 |
| gronk| 4.3 |
| snork| non-number |
| count| <<columncalc count all 1 -1>> |
| total| <<columncalc sum all 1 -2>> |
| avg| <<columncalc average all 1 -3>> |
}}}
| foo| 3.2 |
| bar| 1.1 |
| baz| 2.9 |
| gronk| 4.3 |
| snork| non-number |
| count| <<columncalc count all 1 -1>> |
| total| <<columncalc sum all 1 -2>> |
| avg| <<columncalc average all 1 -3>> |

''with time-formatted values (hh:mm:ss)...''
{{{
| foo| 00:22:15 |
| bar| 00:03:30 |
| baz| 00:01:45 |
| count| <<columncalc count 1 -1>> |
| total| <<columncalc sum 1 -2>> |
| avg| <<columncalc average 1 -3>> |
}}}
| foo| 00:22:15 |
| bar| 00:03:30 |
| baz| 00:01:45 |
| count| <<columncalc count 1 -1>> |
| total| <<columncalc sum 1 -2>> |
| avg| <<columncalc average 1 -3>> |
<<<
!!!Revisions
<<<
2009.02.05 [0.6.2] added 'all' param to include empty/text rows in calculations.
2007.10.26 [0.6.1] in handler(), using '.textContent' instead of '.innerHTML' when reading values from table cells.  This allows use of values that are transcluded from slices in other tiddlers using the {{{<<tiddler 'TiddlerName::slicename'>>}}} syntax.
2007.06.29 [0.6.0] added support for handling values in hh:mm:ss format
2007.04.02 [0.5.0] started
<<<
!!!!!Code
***/
//{{{
version.extensions.ColumnCalculatorPlugin= {major: 0, minor: 6, revision: 1, date: new Date(2007,10,26)};
config.macros.columncalc= {
	handler:
	function(place,macroName,params,wikifier,paramString,tiddler) {

		if (place.parentNode.nodeName.toLowerCase()!='tr') return false; // not in a table
		var tbody=place.parentNode.parentNode;
		var row=tbody.childNodes.length-1; // current row #
		var col=place.parentNode.childNodes.length-1; // current column #

		var fn=params.shift();
		var allCells=(params[0]&&params[0].toLowerCase()=='all');
		if (allCells) params.shift();
		var startrow=0; var endrow=row-1;
		if (params[0]) var startrow=params.shift();
		if (startrow<0) startrow=1*startrow+row; else startrow=startrow-1;
		if (params[0]) var endrow=params.shift();
		if (endrow<0) endrow=1*endrow+row; else endrow=endrow-1;

		var count=total=0;
		for (r=startrow; r<=endrow; r++) {
			var cell=tbody.childNodes[r].childNodes[col].textContent;
			if (!cell) cell=tbody.childNodes[r].childNodes[col].innerHTML; // fallback for older browsers
			var val=cell; var hms=cell.split(':');
			if (hms.length==3) { // an hh:mm:ss time value
				var val=(hms[0]||0)*3600+(hms[1]||0)*60+(hms[2]||0)*1;
				var showTime=true; // use time formatting for results...
			}
			else if (cell.length && !isNaN(cell)) // a numeric value
				var val=eval(cell);
			else if (allCells) // an non-numeric cell (when 'all' is used)
				var val=0;
			if (!isNaN(val)) { total+=val; count++; }
		}
		switch (fn) {
			case 'count':
				var result=count;
				break;
			case 'average':
			case 'avg':
				var result=Math.floor(total/count*100)/100; // truncate to two decimal places
				break;
			case 'total':
			case 'sum':
			default:
				var result=total;
				break;
		}
		if (showTime && fn!='count') {
			var h=Math.floor(result/3600);
			var m=Math.floor((result-h*3600)/60);
			var s=Math.floor((result-h*3600-m*60)*100)/100; // truncate to two decimal places
			result=(h<10?'0':'')+h+':'+(m<10?'0':'')+m+':'+(s<10?'0':'')+s;
		}
		createTiddlyText(place,result);
	}
}
//}}}
/***
|Name|CommentPlugin|
|Source|http://www.TiddlyTools.com/#CommentPlugin|
|Documentation|http://www.TiddlyTools.com/#CommentPluginInfo|
|Version|2.9.3|
|Author|Eric Shulman|
|License|http://www.TiddlyTools.com/#LegalStatements|
|~CoreVersion|2.1|
|Type|plugin|
|Description|automatically insert formatted comments into tiddler content|
!!!!!Documentation
>see [[CommentPluginInfo]]
!!!!!Configuration
>see [[CommentPluginInfo]]
!!!!!Revisions
<<<
2009.04.10 [2.9.3] invoke autoSaveChanges() after adding a comment
| please see [[CommentPluginInfo]] for previous revision details |
2006.04.20 [1.0.0] initial release
<<<
!!!!!Code
***/
//{{{
version.extensions.CommentPlugin= {major: 2, minor: 9, revision: 3, date: new Date(2009,4,10)};

config.macros.comment= {
	marker: '/%'+'comment'+'%/',
	fmt: "__''%subject%''__\n^^posted by %who% on %when%^^\n<<<\n%message%\n<<<\n",
	datefmt: 'DDD, MMM DDth, YYYY at hh12:0mm:0ss am',
	tags: '',
	reverse: false,
	handler: function(place,macroName,params,wikifier,paramstring,tiddler) {
		var span=createTiddlyElement(place,'span');
		var here=story.findContainingTiddler(place);
		if (here) var tid=here.getAttribute('tiddler');  // containing tiddler title
		span.setAttribute('here',tid);
		var target=(params[0]&&params[0].length&&params[0]!='here')?params[0]:tid;  // target title
		span.setAttribute('target',target);
		var overwrite=(params[1]&&params[1].toLowerCase()=='overwrite'); if (overwrite) params.shift();
		span.setAttribute('overwrite',overwrite?'true':'false');
		var reverse=(params[1]&&params[1].toLowerCase()=='reverse'); if (reverse) params.shift();
		span.setAttribute('reverse',(reverse||this.reverse)?'true':'false');
		var marker=this.marker;
		if (params[1]&&params[1].substr(0,7)=='marker:') {
			var marker='/%'+params[1].substr(7)+'%/';
			params.shift();
		}
		span.setAttribute('marker',marker);
		var tags=(params[1]&&params[1].length)?params[1]:this.tags; // target tags
		span.setAttribute('tags',tags);
		var fmt=(params[2]&&params[2].length)?params[2]:this.fmt; // output format
		span.setAttribute('fmt',fmt.unescapeLineBreaks());
		var datefmt=(params[3]&&params[3].length)?params[3]:this.datefmt; // date format
		span.setAttribute('datefmt',datefmt.unescapeLineBreaks());
		var html=this.html;
		html=html.replace(/%nosubject%/g,(fmt.indexOf('%subject%')==-1)?'none':'block');
		html=html.replace(/%nomessage%/g,(fmt.indexOf('%message%')==-1)?'none':'block');
		var subjtxt=''; var msgtxt='';
		html=html.replace(/%subjtxt%/g,subjtxt);
		html=html.replace(/%msgtxt%/g,msgtxt);
		span.innerHTML=html;
	},
	html: "<form style='display:inline;margin:0;padding:0;'>\
		<div style='display:%nosubject%'>\
		subject:<br>\
		<input type='text' name='subject' title='enter subject text' style='width:100%' value='%subjtxt%'>\
		</div>\
		<div style='display:%nomessage%'>\
		message:<br>\
		<textarea name='message' rows='7' title='enter message text' \
			style='width:100%'>%msgtxt%</textarea>\
		</div>\
		<center>\
		<i>Please enter your information and then press</i>\
		<input type='button' value='post' onclick='\
			var s=this.form.subject; var m=this.form.message;\
			if (\"%nosubject%\"!=\"none\" && !s.value.length)\
				{ alert(\"Please enter a subject\"); s.focus(); return false; }\
			if (\"%nomessage%\"!=\"none\" && !m.value.length)\
				{ alert(\"Please enter a message\"); m.focus(); return false; }\
			var here=this.form.parentNode.getAttribute(\"here\");\
			var reverse=this.form.parentNode.getAttribute(\"reverse\")==\"true\";\
			var target=this.form.parentNode.getAttribute(\"target\");\
			var marker=this.form.parentNode.getAttribute(\"marker\");\
			var tags=this.form.parentNode.getAttribute(\"tags\").readBracketedList();\
			var fmt=this.form.parentNode.getAttribute(\"fmt\");\
			var datefmt=this.form.parentNode.getAttribute(\"datefmt\");\
			var overwrite=this.form.parentNode.getAttribute(\"overwrite\")==\"true\";\
			config.macros.comment.addComment(here,reverse,target,tags,fmt,datefmt,\
				s.value,m.value,overwrite,marker);'>\
		</center>\
		</form>",
	addComment: function(here,reverse,target,newtags,fmt,datefmt,subject,message,overwrite,marker) {
		var UTC=new Date().convertToYYYYMMDDHHMMSSMMM();
		var rand=Math.random().toString();
		var who=config.options.txtUserName;
		var when=new Date().formatString(datefmt);
		target=target.replace(/%tiddler%/g,here);
		target=target.replace(/%UTC%/g,UTC);
		target=target.replace(/%random%/g,rand);
		target=target.replace(/%who%/g,who);
		target=target.replace(/%when%/g,when);
		target=target.replace(/%subject%/g,subject);
		var t=store.getTiddler(target);
		var text=t?t.text:'';
		var modifier=t?t.modifier:config.options.txtUserName;
		var modified=t?t.modified:new Date();
		var tags=t?t.tags:[];
		for(var i=0; i<newtags.length; i++) tags.pushUnique(newtags[i]);
		var fields=t?t.fields:{};
		var out=fmt;
		out=out.replace(/%tiddler%/g,here);
		out=out.replace(/%UTC%/g,UTC);
		out=out.replace(/%when%/g,when);
		out=out.replace(/%who%/g,who);
		out=out.replace(/%subject%/g,subject);
		out=out.replace(/%message%/g,message);
		var pos=text.indexOf(marker);
		if (pos==-1) pos=text.length; // no marker - insert at end
		else if (reverse) pos+=marker.length; // reverse order by inserting AFTER marker
		var newtxt=overwrite?out:(text.substr(0,pos)+out+text.substr(pos));
		store.saveTiddler(target,target,newtxt,modifier,modified,tags,fields);
		autoSaveChanges();
		if (document.getElementById(story.idPrefix+target))
			story.refreshTiddler(target,DEFAULT_VIEW_TEMPLATE,true);
		if (here!=target && document.getElementById(story.idPrefix+here))
			story.refreshTiddler(here,DEFAULT_VIEW_TEMPLATE,true);
	}
};
//}}}
/***
|Name|CommentPluginInfo|
|Source|http://www.TiddlyTools.com/#CommentPlugin|
|Documentation|http://www.TiddlyTools.com/#CommentPluginInfo|
|Version|2.9.3|
|Author|Eric Shulman|
|License|http://www.TiddlyTools.com/#LegalStatements|
|~CoreVersion|2.1|
|Type|Documentation|
|Description|Documentation for CommentPlugin|
!!!!!Usage
<<<
syntax:
{{{
<<comment TiddlerName overwrite reverse marker:... tags format dateformat>>
}}}
where:
*''~TiddlerName'' //(optional)//<br>specifies the 'target' tiddler into which comments will be written.  If you use the keyword, //{{{"here"}}}// (or omit all parameters), the current tiddler is used by default.  The ~TiddlerName can also include special //substitution markers// to construct a unique target title by dynamically inserting values, where:
**%tiddler%=containing tiddler title,
**%UTC%=UTC timestamp (YYYYMMMDD.HHMMSSMMM),
**%random%=random decimal number (.123456789),
**%who%=current TiddlyWiki username,
**%subject%=comment subject text.
*''overwrite'' //(optional)//<br>Normally, comments are //added// to a target tiddler if it already exists.  However, if you use the ''overwrite'' keyword, the new comment text //''completely replaces the previous contents of an existing tiddler''//.
*''reverse'' //(optional)//<br>By default, new comments are added to the target tiddler //following// any existing comments.  When ''reverse'' is used, new comments are inserted //before// existing comments, resulting in a reverse-chronological display (i.e, newest comments shown first).
*''marker:...'' //(optional)//<br>specifies an alternative //substitution marker// within the target tiddler (see below).
*''tags'' //(optional)//<br>adds specified space-separated tags to the target tiddler whenever a comment is written.  Note that the list of tags should be enclosed in "..." so that it is processed as a single parameter.
*''format'' //(optional)//<br>specifies a custom output format that overrides the default format defined in {{{config.macros.comment.fmt}}} (see Configuration, below), using the following //substitution markers//:
**%tiddler%=containing tiddler title,
**%UTC%=UTC timestamp (YYYYMMMDD.HHMMSSMMM),
**%when%=formatted date/time,
**%who%=username,
**%subject%=subject,
**%message%=comment body text.
*''dateformat'' //(optional)//<br>specifies a custom date/timestamp output to be inserted in place of {{{%when%}} in the comment output format above.  Overrides the default format defined in {{{config.macros.comment.datefmt}}} (see Configuration, below).

To indicate the location within the target tiddler where new comments are to be inserted, embed {{{/%comment%/}}} as a //substitution marker// //within that target tiddler's source//.  Each new comment is inserted immediately preceding the marker, resulting in a time-ordered sequence of comments.  If no marker is present, new comments are appended to the end of the tiddler.  To insert comments from different forms into separate locations in the //same target tiddler//, you can use the ''marker:...'' parameter to specify alternative marker text (e.g., use "marker:note" or "marker:memo" to specify {{{/%note%/}}} or {{{/%memo%/}}} instead of {{{/%comment%/}}})
<<<
!!!!!Configuration
<<<
To configure the behavior and formats used by [[CommentPlugin]], //''place one or more of the following javascript statements in a tiddler tagged with<<tag systemConfig>>''//: //(note: the default values for each setting are shown)//
{{{
config.macros.comment.reverse=false;
}}}
>when set to {{{true}}}, all new comments are inserted //following// the comment marker instead of preceding it, resulting in a reverse chronological display order.  If no comment marker is present in the target tiddler source, the 'reverse' option is ignored and new comments are always appended to the end of the tiddler.
{{{
config.macros.comment.fmt="__''%subject%''__\n^^posted by %who% on %when%^^\n<<<\n%message%\n<<<\n";
}}}
>defines the comment output format to be inserted into the tiddler, where: %when%=date/time, %who%=username, %subject%=subject, and %message% is the body of the comment.  //Note: if you omit %subject% from the output format, the subject input field on the comment form will be automatically suppressed.  Similarly, omitting %message% from the output format suppresses the message input field.  This can be useful when using the {{{<<comment>>}}} macro to create simple activity logs that only require a short, one-line subject rather than entering extended message content.//
{{{
config.macros.comment.datefmt="DDD, MMM DDth, YYYY at hh12:0mm:0ss am";
}}}
>defines the date/timestamp output used within the comment format above.
{{{
config.macros.comment.tags="";
}}}
>defines an optional space-separated, list of tags to be added to the target tiddler whenever a comment is written.  This is most useful when the target tiddler is different from the tiddler containing the {{{<<comment>>}}} macro, to make it easy to locate that tiddler later on.

Note: as of revision 2.0.0, direct dependency on [[NestedSlidersPlugin]], [[MoveablePanelPlugin]], [[InlineJavascriptPlugin]] and [[ToggleSliders]] has been eliminated.  As a result, the comment form and generated comment output are no longer automatically contained within sliders and the "view all/close all" command is not automatically included.  To recreate the previous output format and comment interface, use the following syntax in the tiddler in which you want to place your comments:
{{{
+++^40em^[add a note]...
<<moveablePanel>>add a note
----
<<comment here "" "+++!!!!![%when% (%who%): %subject%]>...\n%message%\n===\n">>===
 | <<tiddler ToggleSliders with: here "view all" "close all">>
}}}
<<<
!!!!!Revisions
<<<
2009.04.10 2.9.3 invoke autoSaveChanges() after adding a comment
2009.03.09 2.9.2 added marker:... macro parameter
2009.03.08 2.9.1 fix handling of nosubject/nomessage when macro param specifies output format
2008.05.17 2.9.0 optional 'overwrite' param replaces existing comment when stored as separate tiddler
2008.04.21 2.8.0 replaced use of %n markers with special 'named' markers: %tiddler%, %UTC%, %random%, %who%, %when%, %subject% and %message% to avoid conflict with TW core processing of tiddler content.  Also, added support for 'reverse' macro param.
2008.04.17 2.7.0 added support for constructing target by inserting UTC timestamp, random number, username and/or subject text into target tiddler title
2008.04.15 2.6.0 added support for custom format and dateformat parameters to override global default formats
2008.04.15 2.5.1 make sure tiddlers are displayed before attempting to refresh them
2008.04.15 2.5.0 refresh tiddler containing comment macro after adding new comment to target tiddler (if different)
2008.04.14 2.4.0 added optional tag list parameter for tagging the target tiddler when comments are written
2008.04.14 2.3.0 if %2 (subject) or %3 (message) are omitted from format string, suppress display and validation of corresponding form elements.
2008.04.13 2.2.0 added optional ~TiddlerName param to specify target tiddler for writing comments
2008.04.10 2.1.0 converted from inline script to plugin
2008.04.05 2.0.0 removed dependencies on NestedSlidersPlugin, MoveablePanelPlugin, ToggleSliders
2007.10.24 1.2.0 added config.options.txtCommentDateFormat
2007.07.05 1.1.0 added 'view all/close all' toolbar item plus code cleanup
2007.06.28 1.0.2 added tiddler.fields to saveTiddler() call (preserves custom fields)
2007.05.26 1.0.1 added support for optional 'reverse' keyword.
2006.04.20 1.0.0 initial release
<<<
Until Mendeley gets a nice entry for this stuff in the profile info, I'm going to start accumulating these here.

''M.T. Johnson'', P.S. Liss, T.G. Bell, C. Hughes and J. Woeltjen, [[Transfer velocities for a suite of trace gases of emerging biogeochemical importance: Liss and Slater (1974) revisited|http://www.slideshare.net/martwine/transfer-velocities-for-a-suite-of-trace-gases-of-emerging-biogeochemical-importance-liss-and-slater-1974-revisited]], at // 6th international symposium on gas transfer at water surfaces//, Kyoto, May 17th - 21st 2010.
Hare, J.H, D. Jackson, ''M.T. Johnson'', T.G. Bell and G. Wick, [[Development of global air-sea gas transfer products|http://ams.confex.com/ams/17Air17Sat9Coas/techprogram/paper_174791.htm]] at //17th AMS conference on air-sea interaction//, Annapolis, MD, USA, September 2010. 
''M.T. Johnson'', Constraining uncertainty in estimates of ocean-atmosphere trace gas fluxes,at  //SOFI Marine Trace Gas Workshop//, Plymouth, 18th-19th April 2011 
/%
|Name|CreateTiddlersFromCSV|
|Source|http://www.TiddlyTools.com/#CreateTiddlersFromCSV|
|Version|1.3.1|
|Author|Eric Shulman|
|License|http://www.TiddlyTools.com/#LegalStatements|
|~CoreVersion|2.1|
|Type|html|
|Description|create tiddlers from CSV data|

!FORMAT
<<<
~Comma-Separated Value (CSV) format:
{{{
title,created,modified,modifier,tags,text,customfield1,customfield2,...
MyTiddler,04/25/2009,04/25/2009,YourName,tag1 [[tag 2]] tag3,"This is ""quoted"" content, with a comma",value,value,...
}}}
{{wrap{
''The first line contains lower-case field names and must include a //"title"// field''.  Subsequent lines define //~CSV-encoded// data: any values that contain quotes or commas are surrounded by double-quotes, and quotes occuring //within// the values are doubled-up.  The ''tags'' field is entered as a //space-separated bracketed list//. Additional fieldnames ("fieldN") are added as custom tiddler fields.}}}
<<<
!end

REVISIONS:
[1.3.1] remove debugging message
[1.3.0] correct handling for embedded quotes and strip \r from input
[1.2.0] convert created/modified values from strings to date objects
[1.1.0] handle CSV-encoded embedded commas and quotes

%/<<tiddler HideTiddlerTags>>{{small smallform{
Enter/paste<<slider {{config.options['']=false;'';}}
	[[CreateTiddlersFromCSV##FORMAT]] 'CSV-formatted data...' 'view CSV format description'
>> or, read data from a tiddler: <html><nowiki>
	<form style='display:inline;margin:0;padding:0;white-space:normal;'>
	<select class='editor' name='tid' title='select a tiddler title'>
	<option>select a tiddler title...</option>
	</select>
	<input type='button' value='get data'
		onclick="this.form.src.value=store.getTiddlerText(this.form.tid.value,'')">
	<input type='button' value='create tiddlers' onclick="
		var CSV=this.form.src.value;
		// GET NAMES
		var lines=CSV.replace(/\r/g,'').split('\n');
		var names=lines.shift().replace(/\x22/g,'').split(',');
		CSV=lines.join('\n');
		// ENCODE commas and newlines within quoted values
		var comma='!~comma~!'; var commaRE=new RegExp(comma,'g');
		var newline='!~newline~!'; var newlineRE=new RegExp(newline,'g');
		CSV=CSV.replace(/\x22([^\x22]*?)\x22/g, function(x){ return x.replace(/\,/g,comma).replace(/\n/g,newline); });
		var lines=CSV.split('\n'); var count=0;
		for (var i=0; i<lines.length; i++) { if (!lines[i].length) continue;
			var values=lines[i].split(',');
			// DECODE commas, newlines, and doubled-quotes, and remove enclosing quotes (if any)
			for (var j=0; j<values.length; j++)
				values[j]=values[j].replace(commaRE,',').replace(newlineRE,'\n')
					.replace(/^\x22|\x22$/g,'').replace(/\x22\x22/g,'\x22');
			// EXTRACT tiddler values
			var title=''; var text=''; var tags=[]; var fields={};
			var created=null; var when=new Date(); var who=config.options.txtUserName;
			for (var v=0; v<values.length; v++) { var val=values[v];
				if (names[v]) switch(names[v].toLowerCase()) {
					case 'title':	title=val.replace(/\[\]\|/g,'_'); break;
					case 'created': created=new Date(val); break;
					case 'modified':when=new Date(val); break;
					case 'modifier':who=val; break;
					case 'text':	text=val; break;
					case 'tags':	tags=val.readBracketedList(); break;
					default:	fields[names[v].toLowerCase()]=val; break;
				}
			}
			if (title.length) {
				store.saveTiddler(title,title,text,who,when,tags,fields,true,created||when);
				displayMessage('Created '+title);
				count++;
			}
			else if (!confirm('invalid data on line '+i+': missing/blank TiddlerName\n\n'
				+values.join('\n')+'\n\n\OK=skip, CANCEL=stop')) break;
		}
		displayMessage('Created '+count+' tiddlers');
	"><br><textarea class='editor' name='src' style='display:inline;width:100%;height:10em;'></textarea>
	</form>
</html><<tiddler {{
	var list=place.lastChild.getElementsByTagName('form')[0].tid;
	store.forEachTiddler(function(title,tiddler){
		list.options[list.length]=new Option(title,title);
	});
'';}}>>}}}
Create a method for a T and S dependent Henry's law solubility plot for the transfer velocity scheme.

{{{
source("K_calcs_Johnson_OS.R")

TSSolPlot<-function(compound){
S_list<-c(0,17.5,32,33,34,35,36)
plot(T_LOTS,KH(compound,T_LOTS,max(S_list)),type="n",xlab="Temperature / Celcius", ylab="KH / dimensionless (gas/liquid)")
linetype<-1
legendlist<-NULL
for(S in S_list){
 lines(T_LOTS,KH(compound,T_LOTS,S),lty=linetype)
 linetype<-linetype+1
 legendlist<-c(legendlist,paste("S=",S,sep=""))
}

legend("topleft",legendlist,lty=seq(from=1,to=length(S_list),by=1))
}

TSSolPlot<-function(compound){
S_list<-c(0,17.5,32,33,34,35,36)
plot(T_LOTS,KH_Molar_per_atmosphere(compound,T_LOTS,min(S_list)),type="n",xlab="Temperature / Celcius", ylab="KH / dimensionless (gas/liquid)")
linetype<-1
legendlist<-NULL
for(S in S_list){
 lines(T_LOTS,KH_Molar_per_atmosphere(compound,T_LOTS,S),lty=linetype)
 linetype<-linetype+1
 legendlist<-c(legendlist,paste("S=",S,sep=""))
}

legend("topright",legendlist,lty=seq(from=1,to=length(S_list),by=1))
}

TSSchmidtPlot<-function(compound){
S_list<-c(0,17.5,32,33,34,35,36)
plot(T_LOTS,schmidt(compound,T_LOTS,max(S_list)),type="n",xlab="Temperature / Celcius", ylab="Schmidt number (dimensionless)")
linetype<-1
legendlist<-NULL
for(S in S_list){
 lines(T_LOTS,schmidt(compound,T_LOTS,S),lty=linetype)
 linetype<-linetype+1
 legendlist<-c(legendlist,paste("S=",S,sep=""))
}

legend("topleft",legendlist,lty=seq(from=1,to=length(S_list),by=1))
}
}}}

This code can also be found in the [[git repository|http://github.com/martwine]]
[[About]]
Have XRF composition in umol/g and aqueous (equilibrium) concentrations in umol/l

elemental solubility is aqueous concentration / XRF

-> units are g/l

Aluminium has HIGH concentration in substrate but a relatively low concentration in the aqueous phase (elemental solubility 0.009 g/l)
Calcium has LOW concentration in substrate but high concentration in aqueous phase (elemental solubility ~10 g/l)

A good description of the meaning of the quantity is the mass of substrate which would be needed to dissolve stoichiometrically in 1L of water to give the observed aqueous concentration of the analyte. I.e. a disproportionately soluble element in a substrate requires a greater amount of stoichiometric dissolution than a disproportionately insoluble one. 

Example: mineral has stoichiometry of elements X and Y: X6Y1 e.g. 6 umol/g X and 1 umol/g Y

In equilibrium with water the aqueous phase concentrations are observed to be 0.1 umol/L X and 10 umol/L Y

So elemental solubility of X is 0.1/6 = 0.017 and of Y is 10/1 = 10

This means that 10g of substrate would have to be stoichiometrically dissolved  in 1L to give 10umol/L of Y, and 0.017g for X i.e. Y is disproportionately soluble relative to X. 



/%
!info
|Name|EmbedTiddlers|
|Source|http://www.TiddlyTools.com/#EmbedTiddlers|
|Version|2.0.1|
|Author|Eric Shulman|
|License|http://www.TiddlyTools.com/#LegalStatements|
|Type|transclusion|
|Description|transclude a list of tiddlers in a specific order|
Usage
<<<
{{{
<<tiddler EmbedTiddlers with: "TiddlerName [[TiddlerName with spaces]] TiddlerName ...">>
<<tiddler EmbedTiddlers with: @TiddlerName>>
<<tiddler EmbedTiddlers with: =tagValue sortby>>
}}}
*''"~TiddlerName """[[TiddlerName with spaces]] TiddlerName ...""""''<br>specifies a list of tiddlers to embed
*''@~TiddlerName''<br>specifies a //separate// tiddler containing the space-separated, bracketed list of tiddlers to embed (e.g., like [[DefaultTiddlers]])
*''=tagValue''<br>embeds all tiddlers that are tagged with the indicated value
*''sortby'' (optional)<br> specifies a tiddler field for sorting the results (default="title").  Use "+" or "-" prefix to indicate the sort direction (ascending/descending), e.g., "-modified" sorts by tiddler modification date, most recent first.
Note: if MatchTagsPlugin is installed, you can use //compound Boolean logic expressions// in place of the "tagValue" (following the leading "=").  However, because a boolean expression will always contain spaces, it MUST be enclosed in doubled square brackets {{{[[...]]}}}, like this:
{{{
<<tiddler EmbedTiddlers with: [[=settings AND NOT systemConfig]]>>
}}}
<<<
!end
!out
$1
!end
!show
<<tiddler EmbedTiddlers##out with: {{
	var list='$1';
	var sortby='title'; if ('$2'!='$'+'2') sortby='$2';
	var tids=[];
	if (list.substr(0,1)=='=') {
		var fn=store.getMatchingTiddlers||store.getTaggedTiddlers;
		var tagged=store.sortTiddlers(fn.apply(store,[list.substr(1)]),sortby);
		for (var t=0; t<tagged.length; t++) tids.push(tagged[t].title);
	} else {
		if (list.substr(0,1)=='@') list=store.getTiddlerText(list.substr(1),'');
		var tids=list.readBracketedList();
	}
	var out='';
	for (var i=0; i<tids.length; i++) out+='<<tiddler [['+tids[i]+']]>\>';
	out;
}}>>
!end
%/<<tiddler {{var src='EmbedTiddlers'; src+(tiddler&&tiddler.title==src?'##info':'##show');}}
	with: [[$1]] [[$2]]>>
Using the method of calibration by standard additions to a sample is really useful for various reasons which I intend to outline in a [[blog|http://martwine.wordpress.com]] post some time soon, when I've got the method all worked out. In the meantime, here's the statistics required to asses the error on a sample whose concentration is quantified by addition of different volumes of a known stock standard. These are from <<cite miller2000 bibliography:Bibliography>>, a seminal tome on such things. I'm planning on automating all these calculations in my (scientific) scripting environment of choice (R) so will be dropping in handy r bits here and there while I work all this out.

So, when calculating the best fit line through the calibration using linear least squares regression, the statistic $S_{y/x}$ gives the 'residual standard error', which estimates the random errors in the y direction.

\begin{equation}
 S_{y/z} = \sqrt{\frac{\sum_i(y_i-\hat{y}_i)^2}{n-2}}
\end{equation}

where $y_i-\hat{y}_i$ are the y residuals (i.e. the difference between observed y values and regression-predicted y values).

The standard deviation, $S_{x_E}$ of the extrapolated x value intercept (i.e. the sample concentration) is:

\begin{equation}
 S_{x_E} = \frac{S_{y/x}}{b}\sqrt{\frac{1}{n}+\frac{\bar{y}^2}{b^{2}\sum_i(x_i - \bar{x})^2}}
\end{equation}

where b is the slope of the regression line, and the other stuff should be pretty obvious (those difficult-to-see symbols are $\bar{x}$ and $\bar{y}$). If not, it's back to statistics 101 for you, sorry!

Then to calculate 95% confidence intervals its the typical application of the t-statistic: $\pm t_{n-2}S_{x_E}$

The generic R code to compute regression line and intercept and do all the above, given the x (concentrations of sequential standard additions) and y ( baseline-/ blank-corrected instrument responses in arbitrary units) data might lokk something like this:

{{{
std_add_calibrate<-function(x_data,y_data){

regression<-lm(y_data~x_data)
gradient<-regression[[1]][[2]]
y_intercept<-regression[[1]][[1]]

# concentration of sample
xE<-y_intercept/gradient

n<-length(y_data)
Syoverx<-summary(regression)[[6]]
SxE<-(Syoverx/gradient)*sqrt((1/n)+((mean(y_data)^2)/(sum(sum((x_data-mean(x_data))^2))*gradient^2)))

#95% confidence interval
u_xE<-SxE*qt(0.975,n-2)
} 

}}}
<<bibliography>>
We've got datasets of seawater and gas phase concentrations over time. We could take average values of these and all ancillary parameters (temp, salinity, windspeed) and calculate an 'average' flux, but what does that really tell us? How do we know how big the uncertainty on that is, particularly when extrapolating to broader scales of time or space?

With the computing power of R and the transfer velocity scheme we can explore parameter space relatively easily, and at low computing cost, so no need to take a subsample - just crunch through the lot. Claire gave me info about the distributions of temp, salinity, wind, and CHBr3 concentration (min 25th med 75th max for each parameter) [in future will probably look to take the whole dataset and work with it]. 

The idea of this analysis is to calculate fluxes from all areas of parameter space i.e. combinations of different values of all parameters, within their representative ranges as defined by their frequency distribution in the dataset, and then calculate a new probability distribution of these fluxes by weighting the calculated fluxes by the closeness to the average values. It's something I've seen done with ensemble runs of GENIE Earth System Model (where you can explore parameter space through e.g. 400 member latin hypercube setups). 

Here's what I did with it as a first stab, and the results look rather pleasing:

(need to check the stats carefully- actually, I probably need to talk to a real statistician)

{{{
# code to calculate CHBr3 fluxes and explore parameter space

source("K_calcs_Johnson_OS.R")
library(Hmisc)
cmpnd<-"CHBr3"

#weighting to give to min 25th med 75th and max value later on
weighting<-c(5,25,100,25,5)

#arrays describing distribution functions of input parameters
 # min,25th,med,75th,max

u<-c(0.5,2.6,6.7,11.3,27.2) #windspeed in m/s
S<-c(32.8,33.2,33.4,33.7,34.0) #salinity
gasconcn<-c(0.3,1.0,1.9,3.8,15.3) #CHBr3 concentration in ppt
T<-c(-1.7,-0.8,0.2,0.9,2.3) #oC

#convert gas phase concentration
n<-101325*gasconcn*1e-12/(8.3141*(T+273.15))
gconc<-n/1e-12 #pmol/m3

#'low' and 'high' cases of sw concentration
swconc_low<-1000*c(8.4,19.8,27.9,46.4,125.9)
swconc_high<-1000*c(14.7,50.1,95.2,145.7,579.7)

#make list of every combination of values above
low_grid<-expand.grid(u,T,S,gconc,swconc_low)
high_grid<-expand.grid(u,T,S,gconc,swconc_high)

#add the swconc_high column to the low list to make one with no repetition
datagrid<-cbind(low_grid,high_grid[,5])

#give the new datagrid some sensible column headings
colnames(datagrid)<-c("u","T","S","gconc","swconc_low","swconc_high")

#make a grid of weightings
weighting_grid<-expand.grid(weighting,weighting,weighting,weighting,weighting)

#and calculate the product of each row to give the final weighting
weights<-apply(weighting_grid,1,prod)

#add the weightings to the grid
datagrid[,"weights"]<-weights

define some useful names for simplicity
sal<-datagrid[,"S"]
temp<-datagrid[,"T"]
wind<-datagrid[,"u"]
g<-datagrid["gconc"]
sw_low<-datagrid[,"swconc_low"]
sw_high<-datagrid[,"swconc_high"]
weights<-datagrid[,"weights"]

#calculate the henry's law constant for each row
datagrid[,"KH"]<-KH(cmpnd,temp,sal)
H<-datagrid[,"KH"]

#calculate the fluxes for each row in for the high and low cases
datagrid[,"F_low"]<-Kw(cmpnd,temp,wind,sal)*(-1)*((g/H)-(sw_low)) #pmol/m2/s
datagrid[,"F_high"]<-Kw(cmpnd,temp,wind,sal)*(-1)*((g/H)-(sw_high)) #pmol/m2/s

#define probabilities for calculating weighted distribution function
probs=c(.05,.25,.5,.75,.95)

#calculated weighted quantiles with wtd.quantile() [from package Hmisc]
F_low_dist<-(3600*24/1000)*wtd.quantile(datagrid[,"F_low"],weights,probs=probs)

F_high_dist<-(3600*24/1000)*wtd.quantile(datagrid[,"F_high"],weights,probs=probs)

#plot a simple boxplot for a laugh
boxplot(F_low_dist,F_high_dist,range=0)
}}}
!!! Effect of HgCl2 on OPA ammonium method

* experiment with latin hypercube sampling of parameter space in laboratory chemistry experiment
* look at effect of different HgCl2 concentrations with varying ammonium concentrations and OPA concentration
* Measurements: emission curves (excitation 380nm) and 3d excitation-emission plots to determine optimum wavelengths for a given future analysis
* conduct in different matrices? - start with milliQ
* range of HgCl2 concentrations: 0 to 0.12 mM (0 - 2 ml 16g/l HgCl2 solution per litre of sample)
* range of NH4 concentrations
** 2 ranges: 0 to 0.5 uM and 0.5 to 5 uM
* working reagent to sample volume ratio
** low ammonium: 0.02 to 0.2
** high ammonium: 0.2 to 2
* conduct in large centrifuge tubes with 20ml milliq to which 500uM NH4Cl stock standard can be added along with WR and HgCl2 solution
* HgCl2 @ 16g/L = 16/271.51 M = 5.89e-2M
** calc volume of HgCl2 to add:
*** moles HgCl2 = concn x vol = 0.06 (mM) *1e-3 * 0.02 = 1.2e-6 moles
*** vol HgCl2 solution = moles / concn = 1.2e-6/5.9e-2 = 2.03 e-5 L = 20.3 uL


LHC setup:
{{{
> low<-optimumLHS(n=10,k=3)
Beginning Optimality Criterion 7.160646 
2 full sweeps completed
Final Optimality Criterion 6.774126 
> high<-optimumLHS(n=10,k=3)
Beginning Optimality Criterion 7.280711 
2 full sweeps completed
Final Optimality Criterion 6.633021 

> HgCl2<-c(0,0.12)
> NH4_low<-c(0,0.5)
> NH4_high<-c(0.5,5)
> WR_low<-c(0.02,0.2)
> WR_high<-(0.2,2)

> colnames(low)<-c("[HgCl2]/mM","[NHx]/uM","WR:sample ratio")
> low[,1]<-(low[,1]*HgCl2[2])+HgCl2[1]
> low[,2]<-(low[,2]*NH4_low[2])+NH4_low[1]
> low[,3]<-(low[,3]*WR_low[2])+WR_low[1]
> low
       [HgCl2]/mM   [NHx]/uM WR:sample ratio
 [1,] 0.066685126 0.05296689      0.16798952
 [2,] 0.075401443 0.49535212      0.09045331
 [3,] 0.044939688 0.10574936      0.02882936
 [4,] 0.118387002 0.43080696      0.14430441
 [5,] 0.093876777 0.18090458      0.07750164
 [6,] 0.019664690 0.28952294      0.13669572
 [7,] 0.034258166 0.39708042      0.05264286
 [8,] 0.058961034 0.30310512      0.20387930
 [9,] 0.099522896 0.20470285      0.18199208
[10,] 0.000984786 0.01922447      0.10051111
> high[,1]<-(high[,1]*HgCl2[2])+HgCl2[1]
> high[,2]<-(high[,2]*NH4_high[2])+NH4_high[1]
> high[,3]<-(high[,3]*WR_high[2])+WR_high[1]
> Expt1<-rbind(low,high)
> signif(Expt1,2)
      [HgCl2]/mM [NHx]/uM WR:sample ratio
 [1,]    0.06700    0.053           0.170
 [2,]    0.07500    0.500           0.090
 [3,]    0.04500    0.110           0.029
 [4,]    0.12000    0.430           0.140
 [5,]    0.09400    0.180           0.078
 [6,]    0.02000    0.290           0.140
 [7,]    0.03400    0.400           0.053
 [8,]    0.05900    0.300           0.200
 [9,]    0.10000    0.200           0.180
[10,]    0.00098    0.019           0.100
[11,]    0.06200    0.660           0.650
[12,]    0.02600    2.200           2.100
[13,]    0.11000    3.200           0.560
[14,]    0.05500    4.800           1.800
[15,]    0.02100    4.000           1.100
[16,]    0.07900    1.300           1.700
[17,]    0.04200    4.000           0.390
[18,]    0.00560    1.700           0.810
[19,]    0.11000    2.700           1.600
[20,]    0.08400    5.000           1.400


> Expt1<-as.data.frame(Expt1) 
> Expt1[,"vol_HgCl2"]<-1e6*(Expt1[,1]*0.02*1e-3/5.89e-2)
> Expt1[,"vol_NH4"]<-1e6*(Expt1[,2]*0.02*1e-6/0.5e-3)
> Expt1[,"vol_WR"]<-20*Expt1[,3]
 # column renaming not shown here
> signif(Expt1,2)
   [HgCl2]/mM [NHx]/uM WR:sample ratio vol_HgCl2 / ul vol_NH4 / ul vol_WR / ml
1     0.06700    0.053           0.170          23.00         2.10        3.40
2     0.07500    0.500           0.090          26.00        20.00        1.80
3     0.04500    0.110           0.029          15.00         4.20        0.58
4     0.12000    0.430           0.140          40.00        17.00        2.90
5     0.09400    0.180           0.078          32.00         7.20        1.60
6     0.02000    0.290           0.140           6.70        12.00        2.70
7     0.03400    0.400           0.053          12.00        16.00        1.10
8     0.05900    0.300           0.200          20.00        12.00        4.10
9     0.10000    0.200           0.180          34.00         8.20        3.60
10    0.00098    0.019           0.100           0.33         0.77        2.00
11    0.06200    0.660           0.650          21.00        27.00       13.00
12    0.02600    2.200           2.100           8.70        90.00       42.00
13    0.11000    3.200           0.560          36.00       130.00       11.00
14    0.05500    4.800           1.800          19.00       190.00       36.00
15    0.02100    4.000           1.100           7.00       160.00       23.00
16    0.07900    1.300           1.700          27.00        54.00       34.00
17    0.04200    4.000           0.390          14.00       160.00        7.90
18    0.00560    1.700           0.810           1.90        66.00       16.00
19    0.11000    2.700           1.600          37.00       110.00       31.00
20    0.08400    5.000           1.400          29.00       200.00       27.00

> write.csv(signif(Expt1,2),file="/home/martin/Desktop/Expt1.csv",row.names=FALSE)

}}}

[[view the above matrix in google docs|https://spreadsheets.google.com/ccc?key=0AqRtHz1X9oQ6dEhLbWcwa1N4SEJVUElid3laT1F1YlE&hl=en_GB]]

Note that for sample 10 it was not possible to measure 0.33ul so 0.5 ul of HgCl2 was used instead. This has been changed on the google spreadsheet. 

Also included in the google spreadsheet are 3 'controls' - two milliQ + NH4 blanks without WR (one with and one without HgCl2) and one HgCl2-free milliQ + NH4 + WR.


Solutions used: [[HgCl2.003]] [[NH4_500u.001]] [[OPAWR.001]]

[[raw data from 3d excitation-emission analysis|https://docs.google.com/?authuser=0#folders/folder.0.0B6RtHz1X9oQ6NjMwOTk5OTYtZDc1OS00ZTVlLTk5Y2YtNDI2MTk3MTYwOWM5]]
[[data | OLNData/110111A.csv]]
* Lectires include
** modelling approaches (Corinne)
** environmental journalism (Catherine Brahic, New Sci.)
** Fisheries (Simon Jennings, CEFAS)
** GM crops (Jonathan Jones, JIC)

* Research projects
** 65% of module credit
** research and reporting on a global environmental issue
** analysis and synthesis of ideas
** individual project components (drafts) to be submitted electronically 10th March
** no advice on first draft content
** 24th March project submitted
** 1st marker for your own group and second marker for one other
test
Following the SOFI marine trace gas meeting in Plymouth last week, it seems particularly important that isoprene and the monoterpenes should be included in the compounds.dat input data to the [[transfer velocity scheme|http://www.ocean-sci.net/6/913/2010/os-6-913-2010.html]].  These weren't included originally as the temperature dependence of their solubilities is not available in [[Rolf Sander's compilation of Henry's law data|http://www.mpch-mainz.mpg.de/~sander/res/henry.html]]. 

For key monoterpenes, <<cite Copolovici2005 bibliography:Bibliography>> have measured Henry's law constants at various temperatures. These need converting to the correct units for input to the scheme as follows:

| !parameter | !Copolovici | !compounds.dat | !Conversion factor |
| Henry solubility | H$_{pc}$: Pa m$^3$ mol$^{-1}$ | H =M atm$^{-1}$ | H = 101.325/H$_{pc}$ |
| Temperature dependence | $\Delta$H$_{vol}$: KJ mol$^{-1}$ | -$\Delta{}_{soln}$H/R: K | -$\Delta_{soln}$H/R = $\Delta$H$_{vol}$x10$^3$/8.314472 |

For isoprene there is surprisingly little data. No temperature dependence of solubility appears anywhere in the literature as far as I can tell (after pretty much a whole day's worth of searching) and there is some disagreement in the value of the solubility under standard conditions between different studies. The commonly measured value is 1.3x10-2 M/atm but the most recent study cited in Rolf Sander's Henry's law compilation is 2.8x10-2 so investigation of the latter as a possible upper bound is probably useful. I assume the temperature dependence is similar to that of 1,3-butadiene (isoprene being 2-methyl-1,3-butadiene), the value of which is given as 4500 K in Sander. 

new lines for compounds.dat:

{{{
	nicename	mw	KH	tVar	C	H	N	O	S	Br	Cl	F	I	Se 	db	tb	rings	Vb
isoprene	Isoprene	68.12	1.3e-02	4500	5	8	0	0	0	0	0	0	0	0	2	0	0	0
isoprene_upper	Isoprene*	68.12	2.8e-02	4500	5	8	0	0	0	0	0	0	0	0	2	0	0	0
aPinene	alpha,-Pinene	136.24	7.47e-03	4440	10	16	0	0	0	0	0	0	0	0	1	0	1	0
bPinene	beta,-Pinene	136.24	1.47e-02	4450	10	16	0	0	0	0	0	0	0	0	1	0	1	0
aPhellandrene	alpha,-Phellandrene	136.24	1.82e-02	4450	10	16	0	0	0	0	0	0	0	0	2	0	1	0
bPhellandrene	beta,-Phellandrene	136.24	1.82e-02	5090	10	16	0	0	0	0	0	0	0	0	2	0	1	0
aTerpinene	alpha,-Terpinene	136.24	2.90e-02	4790	10	16	0	0	0	0	0	0	0	0	2	0	1	0
yTerpinene	gamma,-Terpinene	136.24	3.87e-02	4775	10	16	0	0	0	0	0	0	0	0	2	0	1	0
aTerpinolene	alpha,-Terpinonlene	136.24	3.81e-02	5450	10	16	0	0	0	0	0	0	0	0	2	0	1	0
aTerpinolene	alpha,-Terpinonlene	136.24	3.81e-02	5450	10	16	0	0	0	0	0	0	0	0	2	0	1	0
Limonene	Limonene	136.24	3.78e-02	4510	10	16	0	0	0	0	0	0	0	0	2	0	1	0
aTerpineol	alpha,-Terpineol	154.25	448	2165	10	18	0	1	0	0	0	0	0	0	1	0	1	0
}}}


<<bibliography>>

Previously I've used 100uL of saturated HgCl2 (~70 g/L) solution per litre of sample. On the cruise we're going to be working with 16 g/L HgCl2 added to give a final concentration of HgCl2 in samples of 0.17mM or thereabouts. 

rmm HgCl2 = 271.52 g/mol

16 g/L =  16/272 M = 0.059 mol/L

for 0.17mM: vol  = mol/concn = 0.17e-03 / 0.059 = 2.8 ml HgCl2 per litre



16g/L HgCl2 kill solution
16g/L HgCl2 kill solution
~16g/L HgCl2

0.827g in 50ml
1.4g/L HgCl2 for smartbuoy autosampler bags

from 16g/L solution [[HgCl2.002]]

-> dilute 11:1

60ml -> 660ml
I've been busy with job interviews, paper writing and holidays, hence the lack of content for the last couple of months. Am just off to teach on the SOLAS summer school in Corsica for a couple of weeks, then I'll be beck generating research again. I haven't abandoned my notebook, honest.
/***
|Name|InlineJavascriptPlugin|
|Source|http://www.TiddlyTools.com/#InlineJavascriptPlugin|
|Documentation|http://www.TiddlyTools.com/#InlineJavascriptPluginInfo|
|Version|1.9.6|
|Author|Eric Shulman|
|License|http://www.TiddlyTools.com/#LegalStatements|
|~CoreVersion|2.1|
|Type|plugin|
|Description|Insert Javascript executable code directly into your tiddler content.|
''Call directly into TW core utility routines, define new functions, calculate values, add dynamically-generated TiddlyWiki-formatted output'' into tiddler content, or perform any other programmatic actions each time the tiddler is rendered.
!!!!!Documentation
>see [[InlineJavascriptPluginInfo]]
!!!!!Revisions
<<<
2010.12.15 1.9.6 allow (but ignore) type="..." syntax
|please see [[InlineJavascriptPluginInfo]] for additional revision details|
2005.11.08 1.0.0 initial release
<<<
!!!!!Code
***/
//{{{
version.extensions.InlineJavascriptPlugin= {major: 1, minor: 9, revision: 6, date: new Date(2010,12,15)};

config.formatters.push( {
	name: "inlineJavascript",
	match: "\\<script",
	lookahead: "\\<script(?: type=\\\"[^\\\"]*\\\")?(?: src=\\\"([^\\\"]*)\\\")?(?: label=\\\"([^\\\"]*)\\\")?(?: title=\\\"([^\\\"]*)\\\")?(?: key=\\\"([^\\\"]*)\\\")?( show)?\\>((?:.|\\n)*?)\\</script\\>",
	handler: function(w) {
		var lookaheadRegExp = new RegExp(this.lookahead,"mg");
		lookaheadRegExp.lastIndex = w.matchStart;
		var lookaheadMatch = lookaheadRegExp.exec(w.source)
		if(lookaheadMatch && lookaheadMatch.index == w.matchStart) {
			var src=lookaheadMatch[1];
			var label=lookaheadMatch[2];
			var tip=lookaheadMatch[3];
			var key=lookaheadMatch[4];
			var show=lookaheadMatch[5];
			var code=lookaheadMatch[6];
			if (src) { // external script library
				var script = document.createElement("script"); script.src = src;
				document.body.appendChild(script); document.body.removeChild(script);
			}
			if (code) { // inline code
				if (show) // display source in tiddler
					wikify("{{{\n"+lookaheadMatch[0]+"\n}}}\n",w.output);
				if (label) { // create 'onclick' command link
					var link=createTiddlyElement(w.output,"a",null,"tiddlyLinkExisting",wikifyPlainText(label));
					var fixup=code.replace(/document.write\s*\(/gi,'place.bufferedHTML+=(');
					link.code="function _out(place,tiddler){"+fixup+"\n};_out(this,this.tiddler);"
					link.tiddler=w.tiddler;
					link.onclick=function(){
						this.bufferedHTML="";
						try{ var r=eval(this.code);
							if(this.bufferedHTML.length || (typeof(r)==="string")&&r.length)
								var s=this.parentNode.insertBefore(document.createElement("span"),this.nextSibling);
							if(this.bufferedHTML.length)
								s.innerHTML=this.bufferedHTML;
							if((typeof(r)==="string")&&r.length) {
								wikify(r,s,null,this.tiddler);
								return false;
							} else return r!==undefined?r:false;
						} catch(e){alert(e.description||e.toString());return false;}
					};
					link.setAttribute("title",tip||"");
					var URIcode='javascript:void(eval(decodeURIComponent(%22(function(){try{';
					URIcode+=encodeURIComponent(encodeURIComponent(code.replace(/\n/g,' ')));
					URIcode+='}catch(e){alert(e.description||e.toString())}})()%22)))';
					link.setAttribute("href",URIcode);
					link.style.cursor="pointer";
					if (key) link.accessKey=key.substr(0,1); // single character only
				}
				else { // run script immediately
					var fixup=code.replace(/document.write\s*\(/gi,'place.innerHTML+=(');
					var c="function _out(place,tiddler){"+fixup+"\n};_out(w.output,w.tiddler);";
					try	 { var out=eval(c); }
					catch(e) { out=e.description?e.description:e.toString(); }
					if (out && out.length) wikify(out,w.output,w.highlightRegExp,w.tiddler);
				}
			}
			w.nextMatch = lookaheadMatch.index + lookaheadMatch[0].length;
		}
	}
} )
//}}}

// // Backward-compatibility for TW2.1.x and earlier
//{{{
if (typeof(wikifyPlainText)=="undefined") window.wikifyPlainText=function(text,limit,tiddler) {
	if(limit > 0) text = text.substr(0,limit);
	var wikifier = new Wikifier(text,formatter,null,tiddler);
	return wikifier.wikifyPlain();
}
//}}}

// // GLOBAL FUNCTION: $(...) -- 'shorthand' convenience syntax for document.getElementById()
//{{{
if (typeof($)=='undefined') { function $(id) { return document.getElementById(id.replace(/^#/,'')); } }
//}}}
Trying to install EBImage manipulation package for R using the autoinstall R script on Ubuntu 9.10 and getting the following error:

{{{* Installing *source* package ‘EBImage’ ...
checking for Magick-config... no
configure: error: "ImageMagick or ImageMagick includes not found!"
ERROR: configuration failed for package ‘EBImage’}}}

However, I deinfitely have imagemagick installed...

After much searching around in the R scripts and googling stuff I fixed it by installing libmagick-dev and libmagickwand.dev:

{{{sudo apt-get install libmagick.dev libmagickwand.dev}}}




Want to explore the effect of mercuric chloride on the fluorescence of OPA-NH4 complex in the OPAMethod. 3 parameters to explore: [NHx], [HgCl2] and working reagent:sample volume ratio.

Using optimumLHS in R from the lhs package we get the following:

{{{
> a<-optimumLHS(n=20,k=3)
Beginning Optimality Criterion 15.946560 
2 full sweeps completed
Final Optimality Criterion 15.339751 
> a
             [,1]       [,2]       [,3]
 [1,] 0.872611215 0.40233543 0.39648414
 [2,] 0.356908106 0.70495256 0.62193105
 [3,] 0.258288368 0.26095833 0.96866685
 [4,] 0.905073226 0.68654736 0.20041883
 [5,] 0.477575219 0.12705760 0.80843599
 [6,] 0.088730426 0.63656361 0.31280975
 [7,] 0.171270209 0.06607352 0.50352950
 [8,] 0.007953093 0.51833621 0.55293676
 [9,] 0.740794623 0.23355189 0.69108034
[10,] 0.204492951 0.99224110 0.87810889
[11,] 0.611782776 0.18728075 0.06248161
[12,] 0.693510687 0.93191982 0.49224843
[13,] 0.587786267 0.75958032 0.19749317
[14,] 0.811042299 0.81700421 0.72283628
[15,] 0.799482881 0.01044386 0.40431608
[16,] 0.538433156 0.58861131 0.93023593
[17,] 0.114037323 0.34923514 0.01368583
[18,] 0.325322792 0.86963949 0.11534521
[19,] 0.979519763 0.46747400 0.78497127
[20,] 0.448995158 0.36345270 0.25570204
}}}

which is a 20 point latin hypercube sample exploring 3d parameter space in a cube of size 1 (i.e. all points between 0 and 1)

Sweet!

now, we can use to turn this latin cube sampling into parameter space of the variables we want to explore:

1. define the ranges of the parameter to explore (x = no. of ml per litre of 16g/l HgCl2 in sample water; y= concentration of NHx in uM; z=W.R.:sample volume ratio)
{{{
> x<-c(0,2)
> y<-c(0,5)
> z<-c(0.1,2)
}}}

2. apply these to the hypercube (a)

{{{
> a[,1]<-(a[,1]*x[2])+x[1]
> a[,2]<-(a[,2]*y[2])+y[1]
> a[,3]<-(a[,3]*z[2])+z[1]
> a
            [,1]       [,2]      [,3]
 [1,] 1.74522243 2.01167715 0.8929683
 [2,] 0.71381621 3.52476279 1.3438621
 [3,] 0.51657674 1.30479163 2.0373337
 [4,] 1.81014645 3.43273678 0.5008377
 [5,] 0.95515044 0.63528799 1.7168720
 [6,] 0.17746085 3.18281803 0.7256195
 [7,] 0.34254042 0.33036760 1.1070590
 [8,] 0.01590619 2.59168106 1.2058735
 [9,] 1.48158925 1.16775943 1.4821607
[10,] 0.40898590 4.96120548 1.8562178
[11,] 1.22356555 0.93640377 0.2249632
[12,] 1.38702137 4.65959908 1.0844969
[13,] 1.17557253 3.79790161 0.4949863
[14,] 1.62208460 4.08502107 1.5456726
[15,] 1.59896576 0.05221932 0.9086322
[16,] 1.07686631 2.94305654 1.9604719
[17,] 0.22807465 1.74617568 0.1273717
[18,] 0.65064558 4.34819746 0.3306904
[19,] 1.95903953 2.33736999 1.6699425
[20,] 0.89799032 1.81726348 0.6114041
}}}

or in a more digestible 2 sig figs:

{{{
> signif(a,2)
       [,1]  [,2] [,3]
 [1,] 1.700 2.000 0.89
 [2,] 0.710 3.500 1.30
 [3,] 0.520 1.300 2.00
 [4,] 1.800 3.400 0.50
 [5,] 0.960 0.640 1.70
 [6,] 0.180 3.200 0.73
 [7,] 0.340 0.330 1.10
 [8,] 0.016 2.600 1.20
 [9,] 1.500 1.200 1.50
[10,] 0.410 5.000 1.90
[11,] 1.200 0.940 0.22
[12,] 1.400 4.700 1.10
[13,] 1.200 3.800 0.49
[14,] 1.600 4.100 1.50
[15,] 1.600 0.052 0.91
[16,] 1.100 2.900 2.00
[17,] 0.230 1.700 0.13
[18,] 0.650 4.300 0.33
[19,] 2.000 2.300 1.70
[20,] 0.900 1.800 0.61
}}}
Based on the spreadsheet here:
http://climateprediction.net/board/viewtopic.php?f=18&t=9312#p88228

which gives the percentage ocean cover in each 30 arc-second latitdinal band, based on the Globe 1.0 database.

The below scripts will calculate the ocean area in latitdunal bands of size x (in degrees). Sea-ice coverage from http://daac.ornl.gov/ISLSCP_II/guides/sea_ice_extent_xdeg.html for 1986-1995 is used to correct for minimum sea-ice coverage (for the purposes we need it for, this is the important term, seasonal sea-ice being considered effectively part of the open-water fraction of the ocean; in the future I'll modify this script to work with min, max or average sea-ice extent).

{{{
#R script to calculate the ocean area in latitude bands of a given extent

rad<-6371007 #Earth average radius in m (such that sphere area is equivalent to oblate spheroid area of actual planet

area<-read.csv("Ocean_area.data.csv",row.names=NULL)


#convert Lats to radians:
Lat_start<-area$Latitude.Start*pi/180
Lat_end<-area$Latitude.End*pi/180

lat_band_area<-function(Lat_start,Lat_end){
	#calculate total area of latitudinal band on planet
	2*pi*(rad^2)*(sin(Lat_start)-sin(Lat_end))
}

#calculate area of each tiny band
area$band_area<-lat_band_area(Lat_start,Lat_end)

#and ocean area
area$ocean_area<-area$band_area*area$Ocean.Fraction


#for bands of latitudinal extent in degrees
band_ocean_area<-function(start_lat, end_lat){
	area_subset<-subset(area,Latitude.Start<=max(start_lat, end_lat) & Latitude.End>=min(start_lat,end_lat))
	sum(area_subset$ocean_area)
}

#get areas at latitudinal spacing of x
get_lat_band_ocean_areas<-function(x){
	lat_s<-seq(from=-90,to=90,by=x)
	#strip the 90 off the end if it's there
	if(lat_s[length(lat_s)]==90){lat_s<-lat_s[1:(length(lat_s)-1)]}
	#now make the end lat array - starting at the 2nd member of lat_s	
	lat_e<-c(lat_s[2:length(lat_s)],90)
	x<-data.frame(lat_s,lat_e)
	x[,3]<-apply(x,1,function(row){band_ocean_area(row[1],row[2])})	
	colnames(x)<-c("Latitude.Start","Latitude.End","Ocean.Area")
	x		
}

#read and process sea-ice file to get minimum annual ice coverage per bands of latitudinal range, x
get_lat_band_min_ice_cover<-function(x,ice_file="sea_ice_data_1deg/sea_ice_data_1d_1995.csv"){
	data<-read.table(ice_file,sep=",",header=TRUE)
	data2<-subset(data, LAND_MASK==0)
	data2$minice<-apply(data2[,3:14],1,min)
	data2$ice_area<-apply(data2,1,function(row){lat_band_area((row[2]+0.5)*pi/180,(row[2]-0.5)*pi/180)*0.01*row[16]/360})
	lat_s<-seq(from=-90,to=90,by=x)
	#strip the 90 off the end if it's there
	if(lat_s[length(lat_s)]==90){lat_s<-lat_s[1:(length(lat_s)-1)]}
	#now make the end lat array - starting at the 2nd member of lat_s	
	lat_e<-c(lat_s[2:length(lat_s)],90)
	x<-data.frame(lat_s,lat_e)
	x[,3]<-apply(x,1,function(row){sum(subset(data2,LAT>row[1] & LAT<row[2])[,"ice_area"])})
	colnames(x)<-c("Latitude.Start","Latitude.End","Seaice.Area")
	x
}

yearlist=seq(from=1986,to=1995,by=1)
get_average_sea_ice_cover<-function(x,years=yearlist){
	lat_s<-seq(from=-90,to=90,by=x)
	#strip the 90 off the end if it's there
	if(lat_s[length(lat_s)]==90){lat_s<-lat_s[1:(length(lat_s)-1)]}
	#now make the end lat array - starting at the 2nd member of lat_s	
	lat_e<-c(lat_s[2:length(lat_s)],90)
	y<-data.frame(lat_s,lat_e)
	for(year in years){
		filename=paste("sea_ice_data_1deg/sea_ice_data_1d_",year,".csv",sep="")
		y<-cbind(y,get_lat_band_ice_cover(x,filename)[,"Seaice.Area"])	
	}
	y$mean_sea_ice_area<-apply(y[,3:length(yearlist+2)],1,mean)
	colnames(y)<-c("long","lat",yearlist,"mean_seaice_area")
	y
}

get_ocean_area_minus_seaice<-function(x){
	lat_s<-seq(from=-90,to=90,by=x)
	#strip the 90 off the end if it's there
	if(lat_s[length(lat_s)]==90){lat_s<-lat_s[1:(length(lat_s)-1)]}
	#now make the end lat array - starting at the 2nd member of lat_s	
	lat_e<-c(lat_s[2:length(lat_s)],90)
	y<-data.frame(lat_s,lat_e)
	ocean_area<-get_lat_band_ocean_areas(x)[,"Ocean.Area"]
	Ice_area<-get_average_sea_ice_cover(x)[,"mean_seaice_area"]
	y$Water.Area<-ocean_area-Ice_area
	y
}



}}}

And Ocean_area.data.csv: https://spreadsheets.google.com/spreadsheet/ccc?key=0AqRtHz1X9oQ6dEJhU2R2akdxME9vSGtEdUJ1UmRjRXc&hl=en_GB#gid=0


}}}
Candidate compounds from the list in <<cite johnson2010 bibliography:Bibliography>> that may be subject to the effects proposed for DMS by <<cite vlahos2009 bibliography:Bibliography>>. Some of these, like the short-chain OVOCs will only be very slightly amphiphillic, so will be interesting to see if Penny's model predicts a significant effect 

Methanol
Ethanol
Phenol
Methylperoxide
Ethylperoxide
Methanal (formaldehyde)
Ethanal (acetaldehyde)
Propanal (propaldehyde)
Monomethylamine
Dimethylamine
Trimethylamine
Monoethylamine
Diethylamine
Triethylamine
Methylcyanide (acetonitrile)
Methylbromide (bromomethane)
Methyliodide (iodomethane)
Ethyliodide* (iodoethane)
Ethylbromide* (bromoethane)
Dimethlydisulfide
Diethylsulfide
Trimethylphospine*

<<bibliography>>

\* these compounds not currently in <<cite johnson2010>> - need to compile Henry's law constants for these ones too
 - looks extremely useful.

http://cran.r-project.org/web/packages/marelac/index.html

{{{install.packages("marelac")}}} worked fine for me

some useful functions from a quick first scan:

{{{
> AtomicWeight[8,]
  Number   Name Symbol     Weight Footnotes
8      8 oxygen      O 15.9994(3)        gr
>> gas_schmidt(species="CO2",t=20)
[1] 665.988
> gas_schmidt(species="N2O",t=20)
[1] 698.212
> gas_schmidt(species="NH3",t=20)
Error in match.arg(species, several.ok = TRUE) : 
  'arg' should be one of “He”, “Ne”, “N2”, “O2”, “Ar”, “Kr”, “Rn”, “CH4”, “CO2”, “N2O”, “CCl2F2”, “CCL3F”, “SF6”, “CCl4”
>
> data.frame(cbind(acronym=names(Oceans),
+ matrix(ncol=3,byrow=TRUE,data=unlist(Oceans),
+ dimnames=list(NULL,c("value","units","description")))))
     acronym    value units                                description
1       Mass 1.35e+25    kg                   total mass of the oceans
2        Vol 1.34e+18    m3                 total volume of the oceans
3    VolSurf 1.81e+16    m3        volume of the surface ocean (0-50m)
4    VolDeep 9.44e+17    m3          volume of the deep ocean (>1200m)
5       Area 3.58e+14    m2                   total area of the oceans
6     AreaIF 3.32e+14    m2    annual mean ice-free area of the oceans
7    AreaAtl  7.5e+13    m2         area of the Atlantic ocean, >45dgS
8    AreaPac 1.51e+14    m2          area of the Pacific ocean, >45dgS
9    AreaInd  5.7e+13    m2           area of the Indian ocean, >45dgS
10  AreaArct  9.6e+12    m2                   area of the Arctic ocean
11  AreaEncl  4.5e+12    m2 area of enclosed seas (e.g. Mediterranean)
12     Depth     3690     m                   mean depth of the oceans
13 RiverFlow  3.7e+13 m3/yr                           Total river flow
> 
}}}

My research is currently funded by the Natural Environment Research Council (http://nerc.ac.uk) under a project with Professor Tim Jickells, with a focus on how nitrogen, particularly organic nitrogen, is cycled in natural waters. 

This involves the following (incomplete list of) experiments, method developments and observations

[[North Sea DON cycling | NSeaDON]] with CEFAS (http://cefas.ac.uk)
[[Nutrient cycling and trace gas production in UEA broad | Broad]]
[[Measuring biogenic amines by HPLC | BiogenicAmines]]

<script type="text/javascript">

  var _gaq = _gaq || [];
  _gaq.push(['_setAccount', 'UA-1693380-2']);
  _gaq.push(['_trackPageview']);

  (function() {
    var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
    ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
    var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
  })();

</script>
<!--{{{-->
<link rel='alternate' type='application/rss+xml' title='RSS' href='index.xml' />
<!--}}}-->
[[About Me|About]]
[[martwine@twitter|http://twitter.com/#!/martwine]]
[[researchpages |http://researchpages.net/people/martin-johnson]]
[[blog |http://martwine.wordpress.com]]
[[github | https://github.com/martwine]]
[[lifestream | http://friendfeed.com/martwine]]
<html><a href="http://www.mendeley.com/profiles/martin-johnson/"><img border="0" src="http://www.mendeley.com/embed/icon/1/blue/small" alt="Martin Johnson's citations"/></a></html>
Would it be possible to measure nitrification rates merely by monitoring concentrations of ammonium, nitrate, nitrite and total N using high precision methods? We might try this on a forthcoming research cruise if so. 

<<cite yool2007 bibliography:Bibliography>> suggests that surface nitrification rates are of the order of 0.2 per day, so assuming an ammonium concentration of 200nM, that would be approx a 40 nM change in ammonium over a day. This is detectable in the OPA ammonium method, but not in the NO3 method (precision approx 100 nM). Therefore we would need to spike incubations to make strongly detectable changes in NO3 concentration over e.g. 48 or 72 hr incubations. We would also need to spike sufficiently to minimise interference from other processes and it would be good to be able to measure total N in the dissolved and particulate phases too. 

!!competing processes

Any biogeochemical process which produces or consumes ammonium, nitrite or nitrate will effect the results we observe. Here's a list of them:

* Light-driven processes (dark incubations to solve this!)
## ammonium uptake
## nitrate uptake

* other processes
## ammonium regeneration by heterotrophy
## direct ammonium release by phytoplankton
## heterotrophic ammonium uptake
## denitrification of NO3- to N2 (via NO2-)
## denitrification of NO3- to NH4 (via NO2-)
## annamox (NH4+ + NO2- -> N3 + 2H2O)
   
denitrification and annamox processes are ostensibly anaerobic and will be slow at the relatively low temperatures of the N. Sea in early February(!) so we assume that these can be neglected (but we need to keep an eye on the oxygen concentrations). Therefore, by 'switching off' the phytoplanktonic uptake by keeping cultures in the dark, things look pretty hopeful. These are the processes which are likely to be occurring in dark incubations:

# nitrification?
# ammonium production (heterotrophic or direct release)
# ammonium uptake by heterotrophs

2. and 3. have no effect on the NO3- concentration, so with sufficiently sensitive nitrate measurements we should be able to distinguish any nitrification signal.  If we can separate dissolved and particulate total N then we should be able to quantify net hetertrophic ammonium uptake. Furthermore, we can use allylthiourea and azide to specifically inhibit the ammonium to nitrite and nitrite to nitrate enzymatic pathways <<cite ginestet1998 bibliography:Bibliography>> to validate our results. We propose the following:

!!The plan

* 3 dark incubations each spiked with 2 uM of NH4
* 1 otherwise untreated
* 1 treated with 50 uM allylthiourea to inhibit ammonium oxidation
* 1 treated with 20 uM azide to inhibit nitrite oxidation
* key metric of nitrification will be NO2 / NO3 concentration
* secondary metric will be NH4
* if 15N-enriched ammonium is added then water samples could be taken and stored for future delta15N-NO3 analysis as further validation of the method.

<<bibliography>>
Sampled the 'Lenton group' mixed microbial microcosms with Ben before xmas for ARISA analysis. Cores taken from centre of each 'cosm using a glass 'coring' tube, sterilised with ethanol between each sample. Replicates taken from 4 cosms as follows:

R1, R2: column A2
R3, R4: column A9
R5: column B8
R6: column B1
[img[ONS|http://onsclaims.wikispaces.com/file/view/ONS-SCI-small.png/59715768/ONS-SCI-small.png][http://onsclaims.wikispaces.com/]]
[img[RSS|rss.png][index.xml]] [[RSS feed|index.xml]] 
Experiment: [[SMARTBuoy storage tests 10/10|SMARTBuoyStorageOct2010]]
Method: [[Fluorimetric ammonium|OPAMethod]]
Calibration: by Standard additions
Analysis date:19/11/2010

Data:
{{{
Desc        	rowflag	set	type	1		2		3		4		5
WarpBagBF 	1		1	-555	27.76		28.27		28.21
WarpBag		1		1	0	80.68		81.10		80.98
WarpBag		1		1	10	110.96	113.31	112.37
WarpBag		1		1	30	170.90	170.98
WarpBag		1		1	50	187.76	187.66
WarpBag		1		1	70	224.51	225.40	225.96
WarpBag		1		1	100	D304.84	D307.60	D281.87	290.60	290.09
GabbBagBF	1		2	-555	-0.77		-0.71		-0.89
GabbBag		0		2	0	112.74	112.78
GabbBag		1		2	10	112.74	112.56
GabbBag		1		2	30	163.00	163.18
GabbBag		1		2	50	195.26	195.08
GabbBag		0		2	70	489.20	489.55
GabbBag		1		2	100	333.88	333.60

}}}

Method:

{{{
stock_concn	sample_volume	baseline_method tracer_name	tracer_type		metadata
5e-5			1e-2			-555			-7777			-7777			"NH4 t=28 from SMARTBuoy bags using standard method"
}}}

Calibrations:

WarpBag calibration
[img[Warp calibration NH4 t=28|OLNImg/NH4_t=28_set1.png]]

GabbBag calibration
[img[Gabbard calibration NH4 t=28|OLNImg/NH4_t=28_set2.png]]

[[calibration data|OLNData/NH4_t=28.calib]]

[[concentrations|OLNData/NH4_t=28.concn]]
New master ~NH4Cl standard (0.1M).

mm ~NH4Cl 53.49 g/mol

In 500ml: 5.349/2 = 2.6745g

actual mass added = 2.7001g

->  concentration = 2 x 2.7001/53.49 = 0.10096 M
5 ml NH4ClStd100m.001 in 500ml 

density of pure water at 18 celcius (according to <<cite johnson2010 bibliography:Bibliography>>) = 998.5976 kg/m$^3$

5ml pipette @18 oC:

4.9202
4.9475
4.9509
4.9420
4.9518
mean = 4.94788g @18C = 4.9548 ml

-> actual concentration = 0.10096 x 4.9548/500 = 1.00045 mM
New 50uM stock standard

25ml of NH4ClStd1m.001 in 500ml

5x 5ml pipette @18 oC

density of pure water at 18 celcius (according to <<cite johnson2010 bibliography:Bibliography>>) = 998.5976 kg/m$^3$

5.0118
5.0297
5.0213
5.0079
4.9402
4.9790
4.9840
4.9840
4.9451
4.9424 
mean = 4.98454g @18C = 4.9915ml

-> actual concentration = 1.00045 x 4.9915 x 5/500 = 49.937 uM

Prepared various samples for OPA analysis:

cross calibrated old 50uM NH4 stock standard (as used on CEND311) and NH4ClStd50u.001

Dowsing11 samples for NH4

standard additions to 5ml sample

[[data|https://spreadsheets.google.com/ccc?key=0AqRtHz1X9oQ6dDRRZURWT2dTQnczTEJFUDhack9Ta1E&hl=en_GB#gid=0]]
Ammonium analysis of Dowsing deployments other than Dowsing 11 (see [[NH4_100311]]).

Also comparison of [[Test 50uM stock NH4Cl]] and [[NH4ClStd50u.001]]

Standard additions to 5ml of sample

[[data|https://spreadsheets.google.com/ccc?key=0AqRtHz1X9oQ6dG9wUE0xWUREUDdta1ctaWl3bUJYRWc&hl=en_GB#gid=0]]
Ammonium analysis of Dowsing deployments 11(2) and re-runs of some questionable looking data from [[NH4_140311]].


Standard additions of [[NH4ClStd50u.001]] to 1ml of sample, using Hamilton syringes - in an attempt to reduce volume requirement.

[[data|https://spreadsheets.google.com/ccc?key=0AqRtHz1X9oQ6dDJfS2VxRnY4aEZhX3RwZW13N0thYmc&hl=en_GB#gid=0]]
2.5ml of 10mM NH4Cl stock standard in 50ml of UPW
Samples collected by CEFAS SMARTBuoys

[[THV Alert sampling 22/10/2010 | AlertOct2010 ]]
[[SMARTBuoy storage tests | SMARTBuoyStorage ]]

In this experiment (initiated 31/1/10) different treatments were tried to determine the optimum concentration of ATU for inhibiting bacterial ammonium oxidation (nitrification). 

After 36 hours all samples were treated with 100uM HgCl2 kill solution (~10 g/L), except those which were treated as killed controls at the beginning. no t=0 points were taken due to time constraints and no calibrations were conducted (raw fluorescence is directly related ammonium concentration; added nh4 was approx. 2uM)

Raw data here:
https://spreadsheets.google.com/pub?key=0AqRtHz1X9oQ6dEk1MkZNNzlOYWxxbFVkbHIzV3pPWnc&hl=en_GB&single=true&gid=0&output=html

What this appears to show is that i) adding ATU increases the amount of ammonium left over after the incubation (i.e. that is inhibiting nitrification - phew!) and ii) that up to a point, adding ATU leads to more inhibition. At higher ATU concentrations, the total NH4 remaining appears to be reduced - possibly because production processes are being stopped due to a broader poisoning effect from the ATU? 

Also note that The HgCl2 treatment appears to have been inneffective with the nitrifier-enhacned treatments (the most effective ATU treatment being considerably higher). 

Another strange result is that the HgCl2 treated controls with no added NH4 have substantially more ammonium in than the seawater only treatments do (about 5 vs about 1 fluorometer unit). This may have been due to cross contamination when adding the working reagent as I was hurrying and there was a bit of splashing! Something to keep an eye on though.

Finally, the non-nitrifier treated seawater again appears to be able to nitrify nearly as effectively as the bacterially enhanced treatments - golly!!
We're going to try the nitrification experiments using UEA broad water this week. Here's the planned protocol.

# Take 10x1L samples of of water
# Treat as discussed [[here |Measuring nitrification rates without isotopic analysis?]], in triplicate
** all bottles spiked with 2 umol/l of NH4Cl
** 1 bottle 'killed' with 100uL of saturated mercuric chloride 
** 3 bottles otherwise untreated
** 3 bottles treated with 50 uM allylthiourea to inhibit ammonium oxidation
** 3 bottles treated with 20 uM azide to inhibit nitrite oxidation
# sample each bottle for ammonium and nitrate / nitrite daily (for 1 week).
** take 20 ml samples from each bottle at each time point, kill with 50uL of saturated mercuric chloride (except the control bottle, whcih is already dead)
** filter and store in 2x15ml centrifuge tubes
** At end of experiment analyse all samples:
*** Ammonium analysis - [[OPAmethod]] 
*** Nitrate / nitrite - standard colourimetric analysis on the nutrient autoanalyser.
Innoculation 15:00

Standard additions of 0,0.5,1,2,and 3ml of 50uM stock ammonium chloride to 10ml of A1, B1 and C1 and control samples.

Also same calibration to milliq for Heather's samples	
Unfortunately it seems that the ammonium concentration in UEA broad was very high (in excess of 20 uM), which was unexpected. This means that I underestimated the working reagent to sample volume and all the concentrations were way out of the linear range of the method at a ration of 2:10. 50:50 would have been better :-( All part of the process.

But why was the broad so high in ammonium? We've never noticed that before...
Ran uncalibrated ammonium measurements using the OPAMethod from [[Nitrification incubation experiment #1]] to compare concentrations in the different treatments after 5 days. Fluorescence was extremely high, suggesting that ammonium concentration was high to start with (so the 2uM increse in concentration by spiking will probably have been small - will do calibrated tests today to confirm). Concentrations didn't appear to be significantly different between treatments, but at the high fluorescence values the precision of the method might well be a few uM either way, so substantial nitrification could be occurring that we cannot resolve. 

The control incubation (HgCl2 treated at t=0) gave a fluorescence value which was about 20% lower, however in previous experiments I've seen HgCl2 inhibit OPA fluorescence by up to 20% at the concentrations we have here (100uL of saturate HgCl2 solution per litre of sample), so it's not clear if ammonium has increased in all treatments vs the control or if there's been no detectable change at all. All will be revealed later with calibrated measurements - watch this space!

If nothing at all has gone on that begs the question i) is there anything alive in there and ii) is there just not very much nitrification. We tackled the first one by returning to the lake to get some more water (1 week on, so not the greatest test). Using the PhytoPAM flourescence machine we found a moderate amount of active photosynthesisers with reasonable photosynthetic health. Under the microscope both fresh samples and samples from the control water show healthy populations of concentric diatoms and some other algae. So the spring bloom has already begun to begin! But if there are algal cells, there must surely be heterotrophic bacteria around to consume their waste products and dead cells and remineralise ammonium...

We'll know more when the calibrated ammonium data is in, but this makes me think that what we can usefully do with this approach is constrain the maximimum nitrification value by reducing the uncertainty in out ammonium measurements to a minimum so we can reduce the error bars and then if a change is undetectable we can better constrain the rate above which nitrification cannot be. To check that the method works at all I'm trying to get hold of come nitrifying bacteria so we can run a 'control' experiment, where we know there are nitrifyers that will work. This will test the inhibitors and the general experimental design. 	
In order to test that nitrification is detectable, and that the inhibitors work in our experimental set-up, we've started a new experiment where we're actually adding nitrifying bacteria to filtered seawater. Nitrifiying bacteria are available from aquarium shops because they're used for nitrifying away toxic ammonia and nitrite (that's nitrite, not nitrate) in fish tanks. We got a bottle of NutrFin Cycle for just over a tenner. This contains nitrosomonas (ammonium to nitrite) and nitrobacter (nitrite to nitrate) communities.

This new experiment, being done in test tube is to test these bacteria and, if they work, to test effectiveness of allylthiourea and azide as inhibitors. It is anticipated that in future field / lab culture experiments we will run a 'positive control' where we add some of these bacteria to confirm that we can detect nitrification if it's happening.

This experiment runs 5 treatments in parallel, each in duplicate with a calibration tube too (calibration by standard additions and separately for each treatment - we know that HgCl2 affects gradient of fluorometer response - maybe allylthiourea or azide will have an affect too...) 

The five treatments are:

i)   Filtered seawater + 2uM NH4 spike (passive control)
ii)  Filtered seawater + 2uM NH4 + HgCl2 + nitrifiers (killed control)
iii) Filtered seawater + 2uM NH4 + nitrifiers
iv) Filtered seawater + 2uM NH4 + 50uM [[allylthiourea|at035m.001]] + nitrifiers
v)  Filtered seawater + 2uM NH4 + 25uM [[sodium azide|az14m.001]] + nitrifiers
Not so much luck here!

here's the raw data:

https://spreadsheets.google.com/pub?key=0AqRtHz1X9oQ6dDNRbHluSDJRdEVNUmRUcW53c2xBWGc&output=html

Thanks to Claire Hughes for making the ammonium measurements whilst I was busy preparing for the forthcoming cruise.

What does this data tell us? The most interesting things are i) that the non-bacterially enhanced filtered seawater (which had been sitting in a cupboard for a number of years!) shows a similar crash in NH4 concentrations at the end of the experiment as the bacterially 'enhanced' treatments - is this because the ambient nitrifier community was able to grow rapidly to consume the added ammonium?. ii) Even the HgCl2 treated incubations showed a decrease - presumably we didn't kill all the masses of bacteria we added. iii) The addition of different chemicals such as azide, HgCl2 and Allylthiourea, substantially modifies the response of the method to NH4. This is not a surprise as I've been keeping an eye on this of late. However, it is a bit of a worry when making measurements in the field...!

And there are some unanswered questions, particularly i) why didn't the ATU inhibitor work (presumably because we swamped it with aquarium nitrifying bacteria) [we don't know from the NH4 data whether the azide worked to inhibit NO2 oxidation] ii) this being the case, what concentration of ATU is required? and iii) how did I fail to add any standard to the calibration for seawater + bacteria!

Next experiment: Different amounts of ATU in seawater with and without nitrifiers added. Started this afternoon
t=0 12/1/11 14:00

12L water sample taken in carboy from [[UEA broad |http://goo.gl/maps/xfYQ]]

see: [[experiment plan|Nitrification experiment design]]

decanted (700ml each) into 10 1L light-proof polycarbonate bottles:

* Control: treated with 70uL saturated ~HgCl2 solution
* ~A1-A3: treated with 1ml 35mM [[Allulthiourea solution|ATU35m.001]] to inhibit ammonium oxidation
* ~B1-B3: treated with 1ml 14mM [[Azide solution|AZ14m.001]] to inhibit nitrite oxidation
* ~C1-C3: untreated

Each bottle was then spiked with 0.14 ml of 10mM NH$_4$Cl (a concentration increase in the 700ml samples of ~2uM). Immediately after spiking samples were taken up in disposable plastic syringes and filtered through 47mm ashed gff filters into 15ml centrifuge tubes to which 1uL of saturated HgCl$_2$ solution has previously been added (except control which already contained HgCl$_2$ so was sampled into fresh tubes). 

Incubations are being kept in the cold room at 4 Celsius, samples kept in the fridge for analysis on the final day of the experiment. Fingers crossed!
In preparation for my lectureship interview in a couple of weeks I've been thinking about the connections between the N and O cycles during the rise of oxygenic photosynthesis. This has been though about before, see the papers by Fennel et al (2005) and followers, and there are some reasonably obvious potential effects, not all of which appear to have been put together into a single model. This might be an interesting thing to have a bash at in advance of the interview and talk that I have to give at the end of the month.

Here are the processes which I think would be interesting to include:

*Reduced iron supply, cycling by anoxygenic photosynthesis, sedimentation or oxidation
*Oxygenic photosynthesis
*Nitrogen fixation and the oxygen / reduced iron requirements thereof
*Nitrification and denitrification and the oxygen dependencies of both 
*Dissimilatory nitrate reduction (denitrification) to ammonium
*Annamox and N2O production?
*NO3 / NH4 uptake.
*remineralisation of organic N to NH4.
*burial of organic material and associated net increase in O2
*atmospheric O2

We'll use the model to asses which of the two nitrogen-oxygen feedbacks are likely to have kicked in first and therefore been dominant in the delaying of the rise of oxygen in the 'great oxidation' - i) nitrification in the presence of oxygen leading to subsequent denitrification and loss of N (which depends on the threshold values of oxygen for the availability of nitrification and the inhibition of denitrification) and ii) the inhibition of nitrogen fixation by either the lack of reduced iron or the presence of oxygen (are these two directly linked in terms of Nfixation inhibition?). 
t=3 25/1/2011 15:00

Also, t=5 17/1/2011 12:00
t=2 14/1/2011 13:00
 
All bottles samples. A2 samples and A3 ~NH4 sample possibly didn't get sufficient ~HgCl2
Using Ocean Data View at the moment: 

http://odv.awi.de/

Useful to have a quick spreadsheet template with basic standard column headings:

https://docs.google.com/spreadsheet/pub?hl=en_GB&hl=en_GB&key=0AqRtHz1X9oQ6dElfU3RseTVmWkNyQ0VVWTZkVlFaeEE&output=html
Fluorimetric ammonium method as described in <<cite johnson2008 bibliography:Bibliography>> (http://www.mendeley.com/research/field-observations-oceanatmosphere-exchange-ammonia-fundamental-importance-temperature-revealed-comparison-high-low-latitudes/)

<<bibliography>>
40g/l Na2B4O7
5% ethanol
2.5 g/L orthophalaldehyde
0.1 g/L NaS	
( systemConfig systemServer transclusion TaskPackage DiscoveryPackage DiscussionPackage MediaPackage RinTheme TaskPackage excludeLists excludeMissing pluginInfo NavigationPackage systemTiddlers dontBlog lewcidExtension systemConfigDisable TidIDEPackage ScrollbarPackage systemTiddler template IconPackage )
!Philosophy

The idea of this project is to investigate how people in research (especially in Environmental Science) are beginning to use online technologies to improve their research, research profiles, collaborations, openness and public engagement. There are a huge range of web technologies out there and they are 'open' in different ways and to different degrees. That's something you can read and think about. Also some of them are very research (or even science or even domain e.g. biotech) specific, some are general public tools that some open scientists have embraced (Twitter, Friendfeed, Flickr (for images), Slideshare).

What seems important to me is that to conduct a study of these technologies and how people are using them can only really be done in one way - by getting stuck in to these technologies and communities of people yourselves. So one part of your work will be to identify tools and applications that people are using, and to sign up to them i) to evaluate what they do, both technically and in the way people are harnessing their potential for research work and ii) to connect with the people who are already using them to discover their experiences - this might be through a survey or by individual interviews (ideally both).  

!Links (in no particular order)

* [[science in the open|http://cameronneylon.net]]
* [[science 3.0|http://science3point0.com]]
* [[mendeley|mendeley.com]]
* [[researchpages.net|http://researchpages.net]]
* [[PLoS on open access|http://www.plos.org/oa/index.php]]
* [[Open source science project|http://www.theopensourcescienceproject.com/]]
* [[DataCite blog|http://datacite.wordpress.com/]]

!Ideas

* Get online!
** Keep a collaborative open notebook (probably using a wordpress blog for minimum set-up time) of the research work you do for the project
** Find other people's blogs covering the subject area
** Use Twitter and follow the movers and shakers in the field of open science / open access and related topics to quickly get your finger on the pulse. Tweet and Retweet links to interesting stuff you find. 
** Sign up for lots of free research related and other services and stitch them together e.g. using friendfeed to 'aggregate' all your online activity for the project. 
** I suggest you make up a username that you can use for all of these (and maybe a new email account too) so that this doesn't all get mixed up with your personal online activities. 
* set up a survey to asses attitudes to and current use of online scientific tools (from the public and other 'stakeholders' as well as researchers)
** Around UEA
** Comparing environmental science with different fields
** Use your (and my) Twitter and other contacts to get the survey out there to a maximum number of people. 
** One of our early meetings should be to discuss and plan what questions to ask and how to ask them.
* As a result of analysis of the survey data conduct interviews with Environmental and non-environmental researchers to target specific questions you might have developed.
These [[InterfaceOptions]] for customising [[TiddlyWiki]] are saved in your browser

Your username for signing your edits. Write it as a [[WikiWord]] (eg [[JoeBloggs]])

<<option txtUserName>>
<<option chkSaveBackups>> [[SaveBackups]]
<<option chkAutoSave>> [[AutoSave]]
<<option chkRegExpSearch>> [[RegExpSearch]]
<<option chkCaseSensitiveSearch>> [[CaseSensitiveSearch]]
<<option chkAnimate>> [[EnableAnimations]]

----
Also see [[AdvancedOptions]]
<!--{{{-->
<div class='titleLine'>
 <span class='siteTitle' refresh='content' tiddler='SiteTitle'></span>&nbsp;
 <span class='siteSubtitle' refresh='content' tiddler='SiteSubtitle'></span>

 <div class="headerOptions">
 <span macro="search"></span>
 <span macro="slider chkSliderOptionsPanel OptionsPanel options 'Change TiddlyWiki advanced options'"></span>
 </div>
</div>

<div class='header'>
 <div id='rinTopMenu' refresh='content' tiddler='RinTopMenu'></div>
</div>

<div id='messageArea'></div>

<div id='bodyWrapper'>
 <div id='rinSidebar'>
 

<div class='sidebarBlock'>
 <div refresh='content' tiddler='MyMenu'></div>
 </div>

<div class='sidebarBlock'>
 <h3>Me</h3>
 <div refresh='content' tiddler='MeSidebar'></div>
 </div>

 <div class='sidebarBlock'>
 <h3>Tag Cloud</h3>
 <div refresh='content' tiddler='Tags'></div>
 </div>

<div class='sidebarBlock'>
 <h3>Tiddlywiki</h3>
 <div refresh='content' tiddler='RinTools'></div>
 </div>
 
 <div class='sidebarBlock'>
 <div id='sidebarTabs' refresh='content' force='true' tiddler='SideBarTabs'></div>
 </div>
 </div>

 <div id='displayArea'>
 <div id='tiddlerDisplay'></div>
 </div>
 <div id='contentFooter'><p>TiddlyWiki was created by <a href="http://www.tidlywiki.com" title="TiddlyWiki">Jeremy Ruston</a> and TiddlyRin was created by <a href="http://www.checkettsweb.com" title="Checketts Web">Clint Checketts</a></p></div>
</div>
<!--}}}-->
/***
|Name|PlayerPlugin|
|Source|http://www.TiddlyTools.com/#PlayerPlugin|
|Version|1.1.4|
|Author|Eric Shulman|
|License|http://www.TiddlyTools.com/#LegalStatements|
|~CoreVersion|2.1|
|Type|plugin|
|Description|Embed a media player in a tiddler|
!!!!!Usage
<<<
{{{<<player [id=xxx] [type] [URL] [width] [height] [autoplay|true|false] [showcontrols|true|false] [extras]>>}}}

''id=xxx'' is optional, and specifies a unique identifier for each embedded player.  note: this is required if you intend to display more than one player at the same time.

''type'' is optional, and is one of the following: ''windows'', ''realone'', ''quicktime'', ''flash'', ''image'' or ''iframe''.  If the media type is not specified, the plugin automatically detects Windows, Real, QuickTime, Flash video or JPG/GIF images by matching known file extensions and/or specialized streaming-media transfer protocols (such as RTSP:).  For unrecognized media types, the plugin displays an error message.

''URL'' is the location of the media content

''width'' and ''height'' are the dimensions of the video display area (in pixels)

''autoplay'' or ''true'' or ''false'' is optional, and specifies whether the media content should begin playing as soon as it is loaded, or wait for the user to press the "play" button.  Default is //not// to autoplay.

''showcontrols'' or ''true'' or ''false'' is optional, and specifies whether the embedded media player should display its built-in control panel (e.g., play, pause, stop, rewind, etc), if any.  Default is to display the player controls.

''extras'' are optional //pairs// of parameters that can be passed to the embedded player, using the {{{<param name=xxx value=yyy>}}} HTML syntax.

''If you use [[AttachFilePlugin]] to encode and store a media file within your document, you can play embedded media content by using the title of the //attachment tiddler//'' as a parameter in place of the usual reference to an external URL.  When playing an attached media content, you should always explicitly specify the media type parameter, because the name used for the attachment tiddler may not contain a known file extension from which a default media type can be readily determined.
<<<
!!!!!Configuration
<<<
Default player size:
width: <<option txtPlayerDefaultWidth>> height: <<option txtPlayerDefaultHeight>>
<<<
!!!!!Examples
<<<
+++[Windows Media]...
Times Square Live Webcam
{{{<<player id=1 http://www.earthcam.com/usa/newyork/timessquare/asx/tsq_stream.asx>>}}}
<<player id=1 http://www.earthcam.com/usa/newyork/timessquare/asx/tsq_stream.asx>>
===
+++[RealOne]...
BBC London: Live and Recorded news
{{{<<player id=2 http://www.bbc.co.uk/london/realmedia/news/tvnews.ram>>}}}
<<player id=2 http://www.bbc.co.uk/london/realmedia/news/tvnews.ram>>
===
+++[Quicktime]...
America Free TV: Classic Comedy
{{{<<player id=3 http://www.americafree.tv/unicast_mov/AmericaFreeTVComedy.mov>>}}}
<<player id=3 http://www.americafree.tv/unicast_mov/AmericaFreeTVComedy.mov>>
===
+++[Flash]...
Asteroids arcade game
{{{<<player id=4 http://www.80smusiclyrics.com/games/asteroids/asteroids.swf 400 300>>}}}
<<player id=4 http://www.80smusiclyrics.com/games/asteroids/asteroids.swf 400 300>>
Google Video
{{{<<player id=5 flash http://video.google.com/googleplayer.swf?videoUrl=http%3A%2F%2Fvp.video.google.com%2Fvideodownload%3Fversion%3D0%26secureurl%3DoQAAAIVnUNP6GYRY8YnIRNPe4Uk5-j1q1MVpJIW4uyEFpq5Si0hcSDuig_JZcB9nNpAhbScm9W_8y_vDJQBw1DRdCVbXl-wwm5dyUiiStl_rXt0ATlstVzrUNC4fkgK_j7nmse7kxojRj1M3eo3jXKm2V8pQjWk97GcksMFFwg7BRAXmRSERexR210Amar5LYzlo9_k2AGUWPLyRhMJS4v5KtDSvNK0neL83ZjlHlSECYXyk%26sigh%3Dmpt2EOr86OAUNnPQ3b9Tr0wnDms%26begin%3D0%26len%3D429700%26docid%3D-914679554478687740&thumbnailUrl=http%3A%2F%2Fvideo.google.com%2FThumbnailServer%3Fcontentid%3De7e77162deb04c42%26second%3D5%26itag%3Dw320%26urlcreated%3D1144620753%26sigh%3DC3fqXPPS1tFiUqLzmkX3pdgYc2Y&playerId=-91467955447868774               400 326>>}}}
<<player id=5 flash http://video.google.com/googleplayer.swf?videoUrl=http%3A%2F%2Fvp.video.google.com%2Fvideodownload%3Fversion%3D0%26secureurl%3DoQAAAIVnUNP6GYRY8YnIRNPe4Uk5-j1q1MVpJIW4uyEFpq5Si0hcSDuig_JZcB9nNpAhbScm9W_8y_vDJQBw1DRdCVbXl-wwm5dyUiiStl_rXt0ATlstVzrUNC4fkgK_j7nmse7kxojRj1M3eo3jXKm2V8pQjWk97GcksMFFwg7BRAXmRSERexR210Amar5LYzlo9_k2AGUWPLyRhMJS4v5KtDSvNK0neL83ZjlHlSECYXyk%26sigh%3Dmpt2EOr86OAUNnPQ3b9Tr0wnDms%26begin%3D0%26len%3D429700%26docid%3D-914679554478687740&thumbnailUrl=http%3A%2F%2Fvideo.google.com%2FThumbnailServer%3Fcontentid%3De7e77162deb04c42%26second%3D5%26itag%3Dw320%26urlcreated%3D1144620753%26sigh%3DC3fqXPPS1tFiUqLzmkX3pdgYc2Y&playerId=-91467955447868774               400 326>>
YouTube Video
{{{<<player id=6 flash http://www.youtube.com/v/OdT9z-JjtJk 400 300>>}}}
<<player id=6 flash http://www.youtube.com/v/OdT9z-JjtJk 400 300>>
===
+++[Still Images]...
GIF (best for illustrations, animations, diagrams, etc.)
{{{<<player id=7 image images/meow.gif auto auto>>}}}
<<player id=7 image images/meow.gif auto auto>>
JPG (best for photographs, scanned images, etc.)
{{{<<player id=8 image images/meow2.jpg 200 150>>}}}
<<player id=8 image images/meow2.jpg 200 150>>
===
<<<
!!!!!Revisions
<<<
2008.05.10 [1.1.4] in handlers(), immediately return if no params (prevents error in macro).  Also, refactored auto-detect code to make type mapping configurable.
2007.10.15 [1.1.3] in loadURL(), add recognition for .PNG (still image), fallback to iframe for unrecognized media types
2007.08.31 [1.1.2] added 'click-through' link for JPG/GIF images
2007.06.21 [1.1.1] changed "hidecontrols" param to "showcontrols" and recognize true/false values in addition to 'showcontrols', added "autoplay" param (also recognize true/false values), allow "auto" as value for type param
2007.05.22 [1.1.0] added support for type=="iframe" (displays src URL in an IFRAME)
2006.12.06 [1.0.1] in handler(), corrected check for config.macros.attach (instead of config.macros.attach.getAttachment) so that player plugin will work when AttachFilePlugin is NOT installed.  (Thanks to Phillip Ehses for bug report)
2006.11.30 [1.0.0] support embedded media content using getAttachment() API defined by AttachFilePlugin or AttachFilePluginFormatters.  Also added support for 'image' type to render JPG/GIF still images
2006.02.26 [0.7.0] major re-write.  handles default params better.  create/recreate player objects via loadURL() API for use with interactive forms and scripts.
2006.01.27 [0.6.0] added support for 'extra' macro params to pass through to object parameters
2006.01.19 [0.5.0] Initial ALPHA release
2005.12.23 [0.0.0] Started
<<<
!!!!!Code
***/
//{{{
version.extensions.PlayerPlugin= {major: 1, minor: 1, revision: 4, date: new Date(2008,5,10)};

config.macros.player = {};
config.macros.player.html = {};
config.macros.player.handler= function(place,macroName,params) {
	if (!params.length) return; // missing parameters - do nothing
	var id=null;
	if (params[0].substr(0,3)=="id=") id=params.shift().substr(3);
	var type="";
	if (!params.length) return; // missing parameters - do nothing
	var p=params[0].toLowerCase();
	if (p=="auto" || p=="windows" || p=="realone" || p=="quicktime" || p=="flash" || p=="image" || p=="iframe")
		type=params.shift().toLowerCase();
	var url=params.shift(); if (!url || !url.trim().length) url="";
	if (url.length && config.macros.attach!=undefined) // if AttachFilePlugin is installed
		if ((tid=store.getTiddler(url))!=null && tid.isTagged("attachment")) // if URL is attachment
			url=config.macros.attach.getAttachment(url); // replace TiddlerTitle with URL
	var width=params.shift();
	var height=params.shift();
	var autoplay=false;
	if (params[0]=='autoplay'||params[0]=='true'||params[0]=='false')
		autoplay=(params.shift()!='false');
	var show=true;
	if (params[0]=='showcontrols'||params[0]=='true'||params[0]=='false')
		show=(params.shift()!='false');
	var extras="";
	while (params[0]!=undefined)
		extras+="<param name='"+params.shift()+"' value='"+params.shift()+"'> ";
	this.loadURL(place,id,type,url,width,height,autoplay,show,extras);
}

if (config.options.txtPlayerDefaultWidth==undefined) config.options.txtPlayerDefaultWidth="100%";
if (config.options.txtPlayerDefaultHeight==undefined) config.options.txtPlayerDefaultHeight="480"; // can't use "100%"... player height doesn't stretch right :-(

config.macros.player.typeMap={
	windows: ['mms', '.asx', '.wvx', '.wmv', '.mp3'],
	realone: ['rtsp', '.ram', '.rpm', '.rm', '.ra'],
	quicktime: ['.mov', '.qt'],
	flash: ['.swf', '.flv'],
	image: ['.jpg', '.gif', '.png'],
	iframe: ['.htm', '.html', '.shtml', '.php']
};

config.macros.player.loadURL=function(place,id,type,url,width,height,autoplay,show,extras) {

	if (id==undefined) id="tiddlyPlayer";
	if (!width) var width=config.options.txtPlayerDefaultWidth;
	if (!height) var height=config.options.txtPlayerDefaultHeight;
	if (url && (!type || !type.length || type=="auto")) { // determine type from URL
		u=url.toLowerCase();
		var map=config.macros.player.typeMap;
		for (var t in map) for (var i=0; i<map[t].length; i++)
			if (u.indexOf(map[t][i])!=-1) var type=t;
	}
	if (!type || !config.macros.player.html[type]) var type="none";
	if (!url) var url="";
	if (show===undefined) var show=true;
	if (!extras) var extras="";
	if (type=="none" && url.trim().length) type="iframe"; // fallback to iframe for unrecognized media types

	// adjust parameter values for player-specific embedded HTML
	switch (type) {
		case "windows":
			autoplay=autoplay?"1":"0"; // player-specific param value
			show=show?"1":"0"; // player-specific param value
			break;
		case "realone":
			autoplay=autoplay?"true":"false";
			show=show?"block":"none";
			height-=show?60:0; // leave room for controls
			break;
		case "quicktime":
			autoplay=autoplay?"true":"false";
			show=show?"true":"false";
			break;
		case "image":
			show=show?"block":"none";
			break;
		case "iframe":
			show=show?"block":"none";
			break;
	}

	// create containing div for player HTML
	// and add or replace player in TW DOM structure
	var newplayer = document.createElement("div");
	newplayer.playerType=type;
	newplayer.setAttribute("id",id+"_div");
	var existing = document.getElementById(id+"_div");
	if (existing && !place) place=existing.parentNode;
	if (!existing)
		place.appendChild(newplayer);
	else {
		if (place==existing.parentNode) place.replaceChild(newplayer,existing)
		else { existing.parentNode.removeChild(existing); place.appendChild(newplayer); }
	}

	var html=config.macros.player.html[type];
	html=html.replace(/%i%/mg,id);
	html=html.replace(/%w%/mg,width);
	html=html.replace(/%h%/mg,height);
	html=html.replace(/%u%/mg,url);
	html=html.replace(/%a%/mg,autoplay);
	html=html.replace(/%s%/mg,show);
	html=html.replace(/%x%/mg,extras);
	newplayer.innerHTML=html;
}
//}}}

// // Player-specific API functions: isReady(id), isPlaying(id), toggleControls(id), showControls(id,flag)

//{{{
// status values:
// Windows: 0=Undefined, 1=Stopped, 2=Paused, 3=Playing, 4=ScanForward, 5=ScanReverse
//          6=Buffering, 7=Waiting, 8=MediaEnded, 9=Transitioning, 10=Ready, 11=Reconnecting
// RealOne: 0=Stopped, 1=Contacting, 2=Buffering, 3=Playing, 4=Paused, 5=Seeking
// QuickTime: 'Waiting', 'Loading', 'Playable', 'Complete', 'Error:###'
// Flash: 0=Loading, 1=Uninitialized, 2=Loaded, 3=Interactive, 4=Complete
config.macros.player.isReady=function(id)
{
	var d=document.getElementById(id+"_div"); if (!d) return false;
	var p=document.getElementById(id); if (!p) return false;
	if (d.playerType=='windows') return !((p.playState==0)||(p.playState==7)||(p.playState==9)||(p.playState==11));
	if (d.playerType=='realone') return (p.GetPlayState()>1);
	if (d.playerType=='quicktime') return !((p.getPluginStatus()=='Waiting')||(p.getPluginStatus()=='Loading'));
	if (d.playerType=='flash') return (p.ReadyState>2);
	return true;
}
config.macros.player.isPlaying=function(id)
{
	var d=document.getElementById(id+"_div"); if (!d) return false;
	var p=document.getElementById(id); if (!p) return false;
	if (d.playerType=='windows') return (p.playState==3);
	if (d.playerType=='realone') return (p.GetPlayState()==3);
	if (d.playerType=='quicktime') return (p.getPluginStatus()=='Complete');
	if (d.playerType=='flash') return (p.ReadyState<4);
	return false;
}
config.macros.player.showControls=function(id,flag) {
	var d=document.getElementById(id+"_div"); if (!d) return false;
	var p=document.getElementById(id); if (!p) return false;
	if (d.playerType=='windows') { p.ShowControls=flag; p.ShowStatusBar=flag; }
	if (d.playerType=='realone') { alert('show/hide controls not available'); }
	if (d.playerType=='quicktime')      // if player not ready, retry in one second
		{ if (this.isReady(id)) p.setControllerVisible(flag); else setTimeout('config.macros.player.showControls("'+id+'",'+flag+')',1000); }
	if (d.playerType=='flash') { alert('show/hide controls not available'); }
}
config.macros.player.toggleControls=function(id) {
	var d=document.getElementById(id+"_div"); if (!d) return false;
	var p=document.getElementById(id); if (!p) return false;
	if (d.playerType=='windows') var flag=!p.ShowControls;
	if (d.playerType=='realone') var flag=true; // TBD
	if (d.playerType=='quicktime') var flag=!p.getControllerVisible();
	if (d.playerType=='flash') var flag=true; // TBD
	this.showControls(id,flag);
}
config.macros.player.fullScreen=function(id) {
	var d=document.getElementById(id+"_div"); if (!d) return false;
	var p=document.getElementById(id); if (!p) return false;
	if (d.playerType=='windows') p.DisplaySize=3;
	if (d.playerType=='realone') p.SetFullScreen();
	if (d.playerType=='quicktime') { alert('full screen not available'); }
	if (d.playerType=='flash') { alert('full screen not available'); }
}
//}}}

// // Player HTML

//{{{
// placeholder (no player)
config.macros.player.html.none=' \
	<table id="%i%" width="%w%" height="%h%" style="background-color:#111;border:0;margin:0;padding:0;"> \
	<tr style="background-color:#111;border:0;margin:0;padding:0;"> \
	<td width="%w%" height="%h%" style="background-color:#111;color:#ccc;border:0;margin:0;padding:0;text-align:center;"> \
	&nbsp; \
	%u% \
	&nbsp; \
	</td></tr></table>';
//}}}

//{{{
// JPG/GIF/PNG still images
config.macros.player.html.image='\
	<a href="%u%" target="_blank"><img width="%w%" height="%h%" style="display:%s%;" src="%u%"></a>';
//}}}

//{{{
// IFRAME web page viewer
config.macros.player.html.iframe='\
	<iframe id="%i%" width="%w%" height="%h%" style="display:%s%;background:#fff;" src="%u%"></iframe>';
//}}}

//{{{
// Windows Media Player
// v7.1 ID: classid=CLSID:6BF52A52-394A-11d3-B153-00C04F79FAA6
// v9	ID: classid=CLSID:22d6f312-b0f6-11d0-94ab-0080c74c7e95
config.macros.player.html.windows=' \
	<object id="%i%" width="%w%" height="%h%" style="margin:0;padding:0;width:%w%;height:%h%px;" \
		classid="CLSID:22d6f312-b0f6-11d0-94ab-0080c74c7e95" \
		codebase="http://activex.microsoft.com/activex/controls/mplayer/en/nsmp2inf.cab#Version=6,4,5,715" \
		align="baseline" border="0" \
		standby="Loading Microsoft Windows Media Player components..." \
		type="application/x-oleobject"> \
		<param name="FileName" value="%u%"> <param name="ShowControls" value="%s%"> \
		<param name="ShowPositionControls" value="1"> <param name="ShowAudioControls" value="1"> \
		<param name="ShowTracker" value="1"> <param name="ShowDisplay" value="0"> \
		<param name="ShowStatusBar" value="1"> <param name="AutoSize" value="1"> \
		<param name="ShowGotoBar" value="0"> <param name="ShowCaptioning" value="0"> \
		<param name="AutoStart" value="%a%"> <param name="AnimationAtStart" value="1"> \
		<param name="TransparentAtStart" value="0"> <param name="AllowScan" value="1"> \
		<param name="EnableContextMenu" value="1"> <param name="ClickToPlay" value="1"> \
		<param name="InvokeURLs" value="1"> <param name="DefaultFrame" value="datawindow"> \
		%x% \
		<embed src="%u%" style="margin:0;padding:0;width:%w%;height:%h%px;" \
			align="baseline" border="0" width="%w%" height="%h%" \
			type="application/x-mplayer2" \
			pluginspage="http://www.microsoft.com/windows/windowsmedia/download/default.asp" \
			name="%i%" showcontrols="%s%" showpositioncontrols="1" \
			showaudiocontrols="1" showtracker="1" showdisplay="0" \
			showstatusbar="%s%" autosize="1" showgotobar="0" showcaptioning="0" \
			autostart="%a%" autorewind="0" animationatstart="1" transparentatstart="0" \
			allowscan="1" enablecontextmenu="1" clicktoplay="0" invokeurls="1" \
			defaultframe="datawindow"> \
		</embed> \
	</object>';
//}}}

//{{{
// RealNetworks' RealOne Player
config.macros.player.html.realone=' \
	<table width="%w%" style="border:0;margin:0;padding:0;"><tr style="border:0;margin:0;padding:0;"><td style="border:0;margin:0;padding:0;"> \
	<object id="%i%" width="%w%" height="%h%" style="margin:0;padding:0;" \
		CLASSID="clsid:CFCDAA03-8BE4-11cf-B84B-0020AFBBCCFA"> \
		<PARAM NAME="CONSOLE" VALUE="player"> \
		<PARAM NAME="CONTROLS" VALUE="ImageWindow"> \
		<PARAM NAME="AUTOSTART" Value="%a%"> \
		<PARAM NAME="MAINTAINASPECT" Value="true"> \
		<PARAM NAME="NOLOGO" Value="true"> \
		<PARAM name="BACKGROUNDCOLOR" VALUE="#333333"> \
		<PARAM NAME="SRC" VALUE="%u%"> \
		%x% \
		<EMBED width="%w%" height="%h%" controls="ImageWindow" type="audio/x-pn-realaudio-plugin" style="margin:0;padding:0;" \
			name="%i%" \
			src="%u%" \
			console=player \
			maintainaspect=true \
			nologo=true \
			backgroundcolor=#333333 \
			autostart=%a%> \
		</OBJECT> \
	</td></tr><tr style="border:0;margin:0;padding:0;"><td style="border:0;margin:0;padding:0;"> \
	<object id="%i%_controls" width="%w%" height="60" style="margin:0;padding:0;display:%s%" \
		CLASSID="clsid:CFCDAA03-8BE4-11cf-B84B-0020AFBBCCFA"> \
		<PARAM NAME="CONSOLE" VALUE="player"> \
		<PARAM NAME="CONTROLS" VALUE="All"> \
		<PARAM NAME="NOJAVA" Value="true"> \
		<PARAM NAME="MAINTAINASPECT" Value="true"> \
		<PARAM NAME="NOLOGO" Value="true"> \
		<PARAM name="BACKGROUNDCOLOR" VALUE="#333333"> \
		<PARAM NAME="SRC" VALUE="%u%"> \
		%x% \
		<EMBED WIDTH="%w%" HEIGHT="60" NOJAVA="true" type="audio/x-pn-realaudio-plugin" style="margin:0;padding:0;display:%s%" \
			controls="All" \
			name="%i%_controls" \
			src="%u%" \
			console=player \
			maintainaspect=true \
			nologo=true \
			backgroundcolor=#333333> \
		</OBJECT> \
	</td></tr></table>';
//}}}

//{{{
// QuickTime Player
config.macros.player.html.quicktime=' \
	<OBJECT ID="%i%" WIDTH="%w%" HEIGHT="%h%" style="margin:0;padding:0;" \
		CLASSID="clsid:02BF25D5-8C17-4B23-BC80-D3488ABDDC6B" \
		CODEBASE="http://www.apple.com/qtactivex/qtplugin.cab"> \
		<PARAM name="SRC" VALUE="%u%"> \
		<PARAM name="AUTOPLAY" VALUE="%a%"> \
		<PARAM name="CONTROLLER" VALUE="%s%"> \
		<PARAM name="BGCOLOR" VALUE="#333333"> \
		<PARAM name="SCALE" VALUE="aspect"> \
		<PARAM name="SAVEEMBEDTAGS" VALUE="true"> \
		%x% \
		<EMBED name="%i%" WIDTH="%w%" HEIGHT="%h%" style="margin:0;padding:0;" \
			SRC="%u%" \
			AUTOPLAY="%a%" \
			SCALE="aspect" \
			CONTROLLER="%s%" \
			BGCOLOR="#333333" \
			EnableJavaSript="true" \
			PLUGINSPAGE="http://www.apple.com/quicktime/download/"> \
		</EMBED> \
	</OBJECT>';
//}}}

//{{{
// Flash Player
config.macros.player.html.flash='\
	<object id="%i%" width="%w%" height="%h%" style="margin:0;padding:0;" \
		classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" \
		codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,29,0"> \
		<param name="movie" value="%u%"> \
		<param name="quality" value="high"> \
		<param name="SCALE" value="exactfit"> \
		<param name="bgcolor" value="333333"> \
		%x% \
		<embed name="%i%" src="%u%" style="margin:0;padding:0;" \
			height="%h%" width="%w%" quality="high" \
			pluginspage="http://www.macromedia.com/go/getflashplayer" \
			type="application/x-shockwave-flash" scale="exactfit"> \
		</embed> \
	</object>';
//}}}
/***
|Name|Plugin: Scientific Notation|
|Created by|BobMcElrath|
|Email|my first name at my last name dot org|
|Location|http://bob.mcelrath.org/tiddlyjsmath-2.0.3.html|
|Version|1.0|
|Requires|[[TiddlyWiki|http://www.tiddlywiki.com]] &ge; 2.0.3, [[jsMath|http://www.math.union.edu/~dpvc/jsMath/]] &ge; 3.0, [[Plugin: jsMath]]|
!Description
This plugin will render numbers expressed in scientific notation, such as {{{3.5483e12}}} using the jsMath plugin to display it in an intuitive way such as 3.5483e12.  You may customize the number of significant figures displayed, as well as "normalize" numbers so that {{{47392.387e9}}} is displayed as 47392.387e9.
!Installation
Install the Requirements, above, add this tiddler to your tiddlywiki, and give it the {{{systemConfig}}} tag.
!History
* 1-Feb-06, version 1.0, Initial release
!Code
***/
//{{{
config.formatters.push({
  name: "scientificNotation",
  match: "\\b[0-9]+\\.[0-9]+[eE][+-]?[0-9]+\\b",
  element: "span",
  className: "math",
  normalize: true,                          // set to 'true' to convert numbers to X.XXX \times 10^{y}
  sigfigs: 3,                               // with this many digits in the mantissa
  handler: function(w) {
    var snRegExp = new RegExp("\\b([0-9]+(?:\\.[0-9]+)?)[eE]([-0-9+]+)\\b");
    var mymatch = snRegExp.exec(w.matchText);
    var mantissa = mymatch[1];
    var exponent = parseInt(mymatch[2]);
    // normalize the number.
    if(this.normalize) {
      mantissa = parseFloat(mantissa);
      while(mantissa > 10.0) {
        mantissa = mantissa / 10.0;
        exponent++; 
      }
      while(mantissa < 1.0) {
        mantissa = mantissa * 10.0;
        exponent--;
      }
      var sigfigsleft = this.sigfigs;
      mantissa = parseInt(mantissa) + "." + (Math.round(Math.pow(10,this.sigfigs-1)*mantissa)+"").substr(1,this.sigfigs-1);
    }
    var e = document.createElement(this.element);
    e.className = this.className;
    if(exponent == 0) {
      e.appendChild(document.createTextNode(mantissa));
    } else {
      e.appendChild(document.createTextNode(mantissa + "\\times 10^{" + exponent + "}"));
    }
    w.output.appendChild(e);
  }
});
//}}}
/***
|''Name:''|Plugin: Syntaxify|
|''Description:''|Performs syntax highlighting on CSS, JavaScript, and HTML/XML|
|''Version:''|1.2|
|''Date:''|January 27, 2007|
|''Source:''|http://bob.mcelrath.org/syntaxify.html|
|''Author:''|BobMcElrath|
|''Email:''|my first name at my last name dot org|
|''License:''|[[GPL open source license|http://www.gnu.org/licenses/gpl.html]]|
|''~CoreVersion:''|2.0.0|
!Description
This plugin will syntax highlight ("pretty-print") source code used by TiddlyWiki.  To activate CSS markup, enclose the code in the CSS code in the delimiters 
<html><code>
/&#42;{{{&#42;/<br/>
/&#42; CSS code here &#42/<br/>
/&#42;}}}&#42;/<br/>
</code></html>
To activate XML markup, enclose your HTML/XML in the delimiters
<html><code>
&lt;!--{{{--&gt;<br/>
&lt;!-- XML/HTML code here --&gt;<br/>
&lt;!--}}}--&gt;<br/>
</code></html>
And to activate JavaScript markup, enclose your code in the delimiters
<html><code>
//{{{<br/>
// JavaScript code here.<br/>
//}}}<br/>
</code></html>

In addition, all of the above languages can be syntaxified by using the custom class formatter
<html><code>
{{foo{<br/>
    code for language "foo" here<br/>
}}}<br/>
</code></html>
where {{{foo}}} is the name of the language: {{{css}}}, {{{javascript}}}, or {{{xml}}}.  This plugin can be extended with new languages by creating a data structure like those below (in {{{syntaxify.languages}}} and then calling {{{syntaxify.addLanguages}}}.
!History
* 1.2 Release
** Now syntaxifies in-line style code (thanks [[Conal Elliott|http://conal.net]]).
** Fix multi-line comments in CSS.
** Consolidate customClassesHelper and monospacedByLineHelper which had lots of duplicated code.
** Fix autoLinkWikiWords bug when using custom classes and the tag formatter.
** Fix compatability problems between 2.1 and 2.0 (termRegExp vs. terminator)
* 1.1 Release
** Rewrite things to make it easier to add new languages.
** Override customClasses to syntaxify when the class corresponds to a known language.
** TiddlyWiki 2.1 beta compatibility
* 1.0.2 Release
** Don't use {{{class}}} as a variable name, dummy.
* 1.0.1 Release
** Simplified stylesheet and removed line numbering.
** Fixed highlighting when <html><code>&#42;/</code></html> appeared at the beginning of a line.
** Fixed blank lines not being shown if {{{list-style-type: none}}} was turned on.
** Small speedups
* 1.0.0 Initial Release
!Code
***/
//{{{
version.extensions.Syntaxify = { major: 1, minor: 2, revision: 0, date: new Date("2007","01","27"),
	source: "http://bob.mcelrath.org/syntaxify.html"
};

var syntaxify = {};

syntaxify.regexpSpace = new RegExp(" ", "mg");
syntaxify.regexpTab = new RegExp("\t", "mg");
syntaxify.regexpAmp = new RegExp("&","mg");
syntaxify.regexpLessThan = new RegExp("<","mg");
syntaxify.regexpGreaterThan = new RegExp(">","mg");
syntaxify.regexpQuote = new RegExp("\"","mg");
syntaxify.regexpDoubleQuotedString = new RegExp("\"(?:\\\\.|[^\\\\\"])*?\"", "mg");
syntaxify.regexpSingleQuotedString = new RegExp("'(?:\\\\.|[^\\\\'])*?'", "mg");
syntaxify.regexpCSingleLineComment = new RegExp('//.*$', "g");
syntaxify.regexpCMultiLineComment 
    = new RegExp('/\\*(?:(?:.|(?:\\r)?\\n)(?!\\*/))*(?:.|(?:\\r)?\\n)?\\*/',"mg");
String.prototype.htmlListMono = function() {
    return(this.replace(syntaxify.regexpAmp,"&amp;")
               .replace(syntaxify.regexpLessThan,"&lt;")
               .replace(syntaxify.regexpGreaterThan,"&gt;")
               .replace(syntaxify.regexpQuote,"&quot;")
               .replace(syntaxify.regexpSpace,"&nbsp;")
               .replace(syntaxify.regexpTab,"&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"));
}

syntaxify.handleSpanClass = function(w) {
    var match, lastPos=0;
    if(this.lookahead) {
        var lookaheadRegExp = new RegExp(this.lookahead,"mg");  
        lookaheadRegExp.lastIndex = w.matchStart;  
        var lookaheadMatch = lookaheadRegExp.exec(w.source);  
        if(lookaheadMatch && lookaheadMatch.index == w.matchStart) {  
            createTiddlyText(w.output, lookaheadMatch[1]);
            var e = createTiddlyElement(w.output, "span", null, this.name);
            e.innerHTML = this.hasSpaces?lookaheadMatch[2].htmlListMono():lookaheadMatch[2];
        }
    } else {
        while((match = regexpNewLine.exec(w.matchText)) != null) {  // multi-line
            var alt = "";
            var e = createTiddlyElement(w.output, "span", null, this.name);
            e.innerHTML = this.hasSpaces?w.matchText.substr(lastPos,match.index-lastPos).htmlListMono()
                            :w.matchText.substr(lastPos,match.index-lastPos);
            if(w.output.className != "alt") alt = "alt";
            w.output = createTiddlyElement(w.output.parentNode, "li", null, alt);
            lastPos = match.index;
        } 
        var e = createTiddlyElement(w.output, "span", null, this.name);
        e.innerHTML = this.hasSpaces?w.matchText.substr(lastPos, w.matchText.length-lastPos).htmlListMono()
                        :w.matchText.substr(lastPos, w.matchText.length-lastPos)
    }
}

/* This is a shadow tiddler.  Do not edit it here.  Instead, open the tiddler StyleSheetSyntaxify 
 * and edit it instead.  (go to the toolbar on the right and select "More"->"Shadowed") */
config.shadowTiddlers.StyleSheetSyntaxify = "/*{{{*/\n"
+".viewer .syntaxify {\n"
+"         font-family: monospace;\n"
+"}\n"
+".viewer div.syntaxify {\n"
+"         background-color: #ffc;\n"
+"         border: 1px solid #fe8;\n"
+"         padding: 0.5em;\n"
+"         margin: 0 0 1em 0.5em;\n"
+"         font-size: 1.2em;\n"
+"         overflow: auto;\n"
+"}\n\n"
+".syntaxify ol {\n"
+"        margin: 0;\n"
+"        padding: 1px;\n"
+"        color: #2B91AF;\n"
+"}\n\n"
+".syntaxify ol li {\n"
+"       background-color: #ffc;\n"
+"       color: black;\n"
+"       list-style-type: none;\n"
+"/* An alternate style to enable line numbering -- remove the line above and uncomment below if desired */\n"
+"/*\n"
+"       list-style-type: 1;\n"
+"       border-left: 3px solid #fe8;\n"
+"       margin-left: 3.5em;\n"
+"*/\n"
+"}\n\n"
+"/* To disable alternating lines having a different colors, comment out the following line. */\n"
+".syntaxify ol li.alt { background-color: #ffe; }\n\n"
+".syntaxify ol li span { color: black; }\n"
+".syntaxify .singleLineComments { color: green; }\n"
+".syntaxify .multiLineComments { color: green; }\n"
+".syntaxify .multiLineComments1 { color: red; }\n"
+".syntaxify .tag { font-weight: bold; color: blue; }\n"
+".syntaxify .tagname { font-weight: bold; color: black; }\n"
+".syntaxify .attribute { color: rgb(127,0,85); }\n"
+".syntaxify .value { color: rgb(42,0,255); }\n"
+".syntaxify .keywords { color: #006699; }\n"
+".syntaxify .keywords1 { color: red; }\n"
+".syntaxify .delimiters { color: maroon; }\n"
+".syntaxify .delimiters1 { color: olive; }\n"
+".syntaxify .literals { color: maroon; }\n"
+".syntaxify .literals1 { color: blue; }\n"
+".syntaxify .literals2 { color: blue; }\n"
+".syntaxify .literals3 { color: #129; }\n"
+".syntaxify .identifiers { font-weight: bold; color: blue; }\n"
+".syntaxify .identifiers1 { font-weight: bold; color: black; }\n"
+"/*}}}*/";

store.addNotification("StyleSheetSyntaxify",refreshStyles);
config.shadowTiddlers.ViewTemplate = "<!--{{{-->\n"+config.shadowTiddlers.ViewTemplate+"\n<!--}}}-->";
config.shadowTiddlers.EditTemplate = "<!--{{{-->\n"+config.shadowTiddlers.EditTemplate+"\n<!--}}}-->";
config.shadowTiddlers.PageTemplate = "<!--{{{-->\n"+config.shadowTiddlers.PageTemplate+"\n<!--}}}-->";
config.shadowTiddlers.StyleSheetPrint = "/*{{{*/\n"+config.shadowTiddlers.StyleSheetPrint+"\n/*}}}*/";

syntaxify.commonFormatters = [
{   name: "spaces",
    match: "[ \\t]+",
    handler: function(w) {
        w.output.innerHTML += w.matchText.htmlListMono();
    }
},{ name: "newline",
    match: "\\n",
    handler: function(w) {
        var alt = ""
        if(w.output.className != "alt") alt = "alt";
        if(!w.output.hasChildNodes()) w.output.innerHTML = "&nbsp;";
        w.output = createTiddlyElement(w.output.parentNode, "li", null, alt);
    }
}];

syntaxify.xmlTagFormatters = syntaxify.commonFormatters;
syntaxify.xmlTagFormatters = syntaxify.xmlTagFormatters.concat([
{   name: "tagname",
    match: '<[/\\?]?\\s*(?:[\\w-\\.]+)',
    lookahead: '(<[/\\?]?\\s*)([\\w-\\.]+)',
    handler: syntaxify.handleSpanClass
},{
    name: "attribute-value",
    match: '[\\w-\.]+(?:\\s*=\\s*"[^"]*?"|\'[^\']*?\'|\\w+)?',
    lookahead: '([\\w-\.]+)(?:(\\s*=\\s*)("[^"]*?"|\'[^\']*?\'|\\w+))?',
    handler: function(w) {
        var lookaheadRegExp = new RegExp(this.lookahead,"mg");  
        lookaheadRegExp.lastIndex = w.matchStart;  
        var lookaheadMatch = lookaheadRegExp.exec(w.source);  
        if(lookaheadMatch && lookaheadMatch.index == w.matchStart) {  
            var e = createTiddlyElement(w.output, "span", null, "attribute");
            e.innerHTML = lookaheadMatch[1];
            if(lookaheadMatch[2]) {
                var e = createTiddlyElement(w.output, "span");
                e.innerHTML = lookaheadMatch[2].htmlListMono();
                e = createTiddlyElement(w.output, "span", null, "value");
                e.innerHTML = lookaheadMatch[3].htmlListMono();
            }
        }
        w.nextMatch = lookaheadMatch.index + lookaheadMatch[0].length;  
    }
}]);


// A rather huge data structure to store languages.  Add to it!
syntaxify.languages = {
javascript: {
    singleLineComments: [[syntaxify.regexpCSingleLineComment.source]],
    multiLineComments: [[syntaxify.regexpCMultiLineComment.source]],
    keywords: [['abstract', 'boolean', 'break', 'byte', 'case', 'catch', 'char',
        'class', 'const', 'continue', 'debugger', 'default', 'delete', 'do',
        'double', 'else', 'enum', 'export', 'extends', 'false', 'final',
        'finally', 'float', 'for', 'function', 'goto', 'if', 'implements',
        'import', 'in', 'instanceof', 'int', 'interface', 'long', 'native',
        'new', 'null', 'package', 'private', 'protected', 'public', 'return',
        'short', 'static', 'super', 'switch', 'synchronized', 'this', 'throw',
        'throws', 'transient', 'true', 'try', 'typeof', 'var', 'void',
        'volatile', 'while', 'with']
    ],
    literals: [
        [syntaxify.regexpSingleQuotedString.source],
        [syntaxify.regexpDoubleQuotedString.source],
        ["\\b\\d+(?:\\.\\d+(?:[eE][\\+-]\\d+)?)?\\b"] // Numbers
    ],
    delimiters: [["[\\{\\}]"],["[\\(\\)]"],["[\\[\\]]"]]
}, 
css: {
    multiLineComments: [[syntaxify.regexpCMultiLineComment.source]],
    keywords: [
        // Keywords appearing on the LHS of expressions
        ['ascent', 'azimuth', 'background-attachment', 'background-color',
        'background-image', 'background-position',  'background-repeat',
        'background', 'baseline', 'bbox', 'border-collapse', 'border-color',
        'border-spacing', 'border-style', 'border-top',  'border-right',
        'border-bottom', 'border-left', 'border-top-color',
        'border-right-color', 'border-bottom-color', 'border-left-color',
        'border-top-style', 'border-right-style', 'border-bottom-style',
        'border-left-style', 'border-top-width', 'border-right-width',
        'border-bottom-width', 'border-left-width', 'border-width', 'border',
        'bottom', 'cap-height', 'caption-side', 'centerline', 'clear', 'clip',
        'color',  'content', 'counter-increment', 'counter-reset', 'cue-after',
        'cue-before', 'cue', 'cursor', 'definition-src', 'descent',
        'direction', 'display', 'elevation', 'empty-cells', 'float',
        'font-size-adjust', 'font-family', 'font-size', 'font-stretch',
        'font-style', 'font-variant', 'font-weight', 'font',  'height', 'left',
        'letter-spacing', 'line-height', 'list-style-image',
        'list-style-position', 'list-style-type', 'list-style', 'margin-top',
        'margin-right', 'margin-bottom', 'margin-left', 'margin',
        'marker-offset', 'marks', 'mathline', 'max-height', 'max-width',
        'min-height', 'min-width', 'orphans',  'outline-color',
        'outline-style', 'outline-width', 'outline', 'overflow', 'padding-top',
        'padding-right', 'padding-bottom', 'padding-left', 'padding', 'page',
        'page-break-after', 'page-break-before', 'page-break-inside', 'pause',
        'pause-after', 'pause-before', 'pitch', 'pitch-range', 'play-during',
        'position', 'quotes', 'richness', 'right', 'size', 'slope', 'src',
        'speak-header', 'speak-numeral', 'speak-punctuation', 'speak',
        'speech-rate', 'stemh', 'stemv', 'stress', 'table-layout',
        'text-align', 'text-decoration', 'text-indent', 'text-shadow',
        'text-transform', 'unicode-bidi', 'unicode-range', 'units-per-em',
        'vertical-align', 'visibility', 'voice-family', 'volume',
        'white-space', 'widows', 'width', 'widths', 'word-spacing', 'x-height',
        'z-index'],
        // Treat !important as a different kind of keyword
        ["important"]
    ],
    literals: [
        // Literals appearing on the RHS of expressions
        ['above', 'absolute', 'all', 'always', 'aqua', 'armenian', 'attr',
        'aural', 'auto', 'avoid', 'baseline', 'behind', 'below',
        'bidi-override', 'black', 'blink', 'block', 'blue', 'bold', 'bolder',
        'both', 'bottom', 'braille', 'capitalize', 'caption', 'center',
        'center-left', 'center-right', 'circle', 'close-quote', 'code',
        'collapse', 'compact', 'condensed', 'continuous', 'counter',
        'counters', 'crop', 'cross', 'crosshair', 'cursive', 'dashed',
        'decimal', 'decimal-leading-zero', 'default', 'digits', 'disc',
        'dotted', 'double', 'embed', 'embossed', 'e-resize', 'expanded',
        'extra-condensed', 'extra-expanded', 'fantasy', 'far-left',
        'far-right', 'fast', 'faster', 'fixed', 'format', 'fuchsia', 'gray',
        'green', 'groove', 'handheld', 'hebrew', 'help', 'hidden', 'hide',
        'high', 'higher', 'icon', 'inline-table', 'inline', 'inset', 'inside',
        'invert', 'italic', 'justify', 'landscape', 'large', 'larger',
        'left-side', 'left', 'leftwards', 'level', 'lighter', 'lime',
        'line-through', 'list-item', 'local', 'loud', 'lower-alpha',
        'lowercase', 'lower-greek', 'lower-latin', 'lower-roman', 'lower',
        'low', 'ltr', 'marker', 'maroon', 'medium', 'message-box', 'middle',
        'mix', 'move', 'narrower', 'navy', 'ne-resize', 'no-close-quote',
        'none', 'no-open-quote', 'no-repeat', 'normal', 'nowrap', 'n-resize',
        'nw-resize', 'oblique', 'olive', 'once', 'open-quote', 'outset',
        'outside', 'overline', 'pointer', 'portrait', 'pre', 'print',
        'projection', 'purple', 'red', 'relative', 'repeat', 'repeat-x',
        'repeat-y', 'ridge', 'right', 'right-side', 'rightwards', 'rtl',
        'run-in', 'screen', 'scroll', 'semi-condensed', 'semi-expanded',
        'separate', 'se-resize', 'show', 'silent', 'silver', 'slower', 'slow',
        'small', 'small-caps', 'small-caption', 'smaller', 'soft', 'solid',
        'speech', 'spell-out', 'square', 's-resize', 'static', 'status-bar',
        'sub', 'super', 'sw-resize', 'table-caption', 'table-cell',
        'table-column', 'table-column-group', 'table-footer-group',
        'table-header-group', 'table-row', 'table-row-group', 'teal',
        'text-bottom', 'text-top', 'thick', 'thin', 'top', 'transparent',
        'tty', 'tv', 'ultra-condensed', 'ultra-expanded', 'underline',
        'upper-alpha', 'uppercase', 'upper-latin', 'upper-roman', 'url',
        'visible', 'wait', 'white', 'wider', 'w-resize', 'x-fast', 'x-high',
        'x-large', 'x-loud', 'x-low', 'x-slow', 'x-small', 'x-soft',
        'xx-large', 'xx-small', 'yellow'],
        // Font literals
        ['[mM]ono(?:space)?', '[tT]ahoma', '[vV]erdana', '[aA]rial',
        '[hH]elvetica', '[sS]ans(?:-serif)?', '[sS]erif', '[Cc]ourier'],
        // Measurement literals
        ["\\b\\d+(?:\\.\\d+)?(?:em|pt|px|cm|in|pc|mm)\\b"],
        // Color literals
        ['(?:\\#[a-fA-F0-9]{6}\\b|\\#[a-fA-F0-9]{3}\\b|rgb\\(\\s*\\d+\\s*,\\s*\\d+\\s*,\\s*\\d+\\s*\\))']
    ],
    identifiers: [["\\.[a-zA-Z_]\\w*"],["\\#[a-zA-Z_]\\w*"]],
    delimiters: [["[\\{\\}]"]]
}, 
xml: {
    multiLineComments: [
        ["<[^!>]*!--\\s*(?:(?:.|(?:\\r)?\\n)(?!--))*?(?:(?:.|(?:\\r)?\\n)(?=--))?\\s*--[^>]*?>"],
        ['<\\!\\[[\\w\\s]*?\\[(?:(?:.|(?:\\r)?\\n)(?!\\]\\]>))*?(?:(?:.|(?:\\r)?\\n)(?=\\]\\]>))?\\]\\]>']
    ],
    customFormatters: [{
        name: "tag",
        match: "<[/\\?]?[^>]*?>",
        handler: function(w) {
            var formatter = new Formatter(syntaxify.xmlTagFormatters);
            var wikifier = new Wikifier(w.matchText, formatter, w.highlightRegExp, w.tiddler);
            wikifier.subWikify(w.output, null);
        }
    }]
}};

config.formatterHelpers.customClassesHelper = function(w) {
    var lookaheadRegExp = (typeof(this.lookaheadRegExp) == "undefined")?(new RegExp(this.lookahead,"mg")):this.lookaheadRegExp;
    lookaheadRegExp.lastIndex = w.matchStart;
    var lookaheadMatch = lookaheadRegExp.exec(w.source);
    var language = (typeof(this.language) == "undefined")?lookaheadMatch[1]:this.language;
    if(lookaheadMatch && lookaheadMatch.index == w.matchStart)
    {
        var isByLine = (typeof(this.byLine) == "undefined")?(lookaheadMatch[2] == "\n"):this.byLine;
        var p = createTiddlyElement(w.output,isByLine ? "div" : "span",null,language);
        w.nextMatch = lookaheadMatch.index + lookaheadMatch[0].length;
        if(typeof(syntaxify.formatters[language]) != "undefined") {
            var d = createTiddlyElement(w.output,isByLine?"div":"span",
				        null,"syntaxify "+language);
            var formatter = new Formatter(syntaxify.formatters[language]);
            if(typeof(this.termRegExp) == "undefined") {
                var text = lookaheadMatch[1];  
            } else {
                this.termRegExp.lastIndex = w.nextMatch;
                var terminatorMatch = this.termRegExp.exec(w.source);
                var text = w.source.substr(w.nextMatch, terminatorMatch.index-w.nextMatch);
            }
            if(config.browser.isIE) text = text.replace(/\n/g,"\r");  
            if (isByLine) {
                var l = createTiddlyElement(d,"ol");
                var li = createTiddlyElement(l,"li");
                var wikifier = new Wikifier(text, formatter, w.highlightRegExp, w.tiddler);
                wikifier.subWikify(li, null);
                if(!l.childNodes[l.childNodes.length-1].hasChildNodes())
                    l.removeChild(l.childNodes[l.childNodes.length-1]);
            } else {
	      var wikifier = new Wikifier(text,formatter,w.highlightRegExp,w.tiddler);
	      wikifier.subWikify(d, null);
            }
            if(typeof(this.termRegExp) != "undefined")
                w.nextMatch = terminatorMatch.index + terminatorMatch[0].length;
            else
                w.nextMatch = lookaheadMatch.index + lookaheadMatch[0].length;  
        } else {
            if(isByLine)
                var e = createTiddlyElement(w.output,"code",null,null,text);  
            else
                var e = createTiddlyElement(w.output,"pre",null,null,text);  
        }
    }
}

syntaxify.formatters = {};

syntaxify.addLanguages = function(languages) {
    for(lang in languages) {
        syntaxify.formatters[lang] = new Array();
        for(var i=0;i<syntaxify.commonFormatters.length;i++)
            syntaxify.formatters[lang].push(syntaxify.commonFormatters[i]);
        var addSpanClass = function(rule, spaces, wordbreak) {
            if(typeof(languages[lang][rule]) != "undefined") {
                for(var j=0;j<languages[lang][rule].length;j++) {
                    syntaxify.formatters[lang].push({
                        name: rule+((j==0)?"":j),
                        match: wordbreak?("(?:\\b"+languages[lang][rule][j].join("\\b|\\b")+"\\b)")
                                        :("(?:"+languages[lang][rule][j].join("|")+")"),
                        hasSpaces: spaces,
                        handler: syntaxify.handleSpanClass
                    });
                }
            }
        };
        addSpanClass("singleLineComments", true, false);
        addSpanClass("multiLineComments", true, false);
        addSpanClass("keywords", false, true);
        addSpanClass("literals", true, false);
        addSpanClass("delimiters", false, false);
        addSpanClass("identifiers", false, false);
        if(typeof(languages[lang].customFormatters) != "undefined") 
            syntaxify.formatters[lang] = syntaxify.formatters[lang].concat(languages[lang].customFormatters);
    }
}

syntaxify.addLanguages(syntaxify.languages);

// Override the several built-in TiddlyWiki language-specific <pre> formatters
for(var i=0;i<config.formatters.length;i++) {  
  if(config.formatters[i].name == "monospacedByLineForPlugin") {  
    config.formatters[i].language = "javascript";
    config.formatters[i].byLine = true;
    config.formatters[i].handler = config.formatterHelpers.customClassesHelper;  
  }  
  if(config.formatters[i].name == "monospacedByLineForCSS") {  
    config.formatters[i].language = "css";
    config.formatters[i].byLine = true;
    config.formatters[i].handler = config.formatterHelpers.customClassesHelper;  
  }  
  if(config.formatters[i].name == "monospacedByLineForTemplate") {  
    config.formatters[i].language = "xml";
    config.formatters[i].byLine = true;
    config.formatters[i].handler = config.formatterHelpers.customClassesHelper;  
  }  
  if(config.formatters[i].name == "customClasses") {
    config.formatters[i].handler = config.formatterHelpers.customClassesHelper;  
    if(typeof(config.formatters[i].termRegExp) == "undefined")
        config.formatters[i].termRegExp = new RegExp(config.formatters[i].terminator, "mg");
  }
}

// make syntaxify reliably accessible from dependent plugins even under IE.
config.macros.syntaxify = syntaxify;
//}}}
/***
|Name|Plugin: arXiv Links|
|Created by|BobMcElrath|
|Email|my first name at my last name dot org|
|Location|http://bob.mcelrath.org/tiddlyjsmath-2.0.3.html|
|Version|1.0|
|Requires|[[TiddlyWiki|http://www.tiddlywiki.com]] &ge; 2.0.3|
!Description
This formatting plugin will render links to the [[arXiv|http://www.arxiv.org]] preprint system.  If you type a paper reference such as hep-ph/0509024, it will be rendered as an external link to the abstract of that paper.
!Installation
Add this tiddler to your tiddlywiki, and give it the {{{systemConfig}}} tag.
!History
* 1-Feb-06, version 1.0, Initial release
!Code
***/
//{{{
config.formatters.push({
  name: "arXivLinks",
  match: "\\b(?:astro-ph|cond-mat|hep-ph|hep-th|hep-lat|gr-qc|nucl-ex|nucl-th|quant-ph|(?:cs|math|nlin|physics|q-bio)(?:\\.[A-Z]{2})?)/[0-9]{7}\\b",
  element: "a",
  handler: function(w) {
    var e = createExternalLink(w.output, "http://arxiv.org/abs/"+w.matchText);
    e.target = "_blank"; // open in new window
    w.outputText(e,w.matchStart,w.nextMatch);
  }
});
//}}}

/***
|Name|Plugin: jsMath|
|Created by|BobMcElrath|
|Email|my first name at my last name dot org|
|Location|http://bob.mcelrath.org/tiddlyjsmath.html|
|Version|1.5.1|
|Requires|[[TiddlyWiki|http://www.tiddlywiki.com]] &ge; 2.0.3, [[jsMath|http://www.math.union.edu/~dpvc/jsMath/]] &ge; 3.0|
!Description
LaTeX is the world standard for specifying, typesetting, and communicating mathematics among scientists, engineers, and mathematicians.  For more information about LaTeX itself, visit the [[LaTeX Project|http://www.latex-project.org/]].  This plugin typesets math using [[jsMath|http://www.math.union.edu/~dpvc/jsMath/]], which is an implementation of the TeX math rules and typesetting in javascript, for your browser.  Notice the small button in the lower right corner which opens its control panel.
!Installation
In addition to this plugin, you must also [[install jsMath|http://www.math.union.edu/~dpvc/jsMath/download/jsMath.html]] on the same server as your TiddlyWiki html file.  If you're using TiddlyWiki without a web server, then the jsMath directory must be placed in the same location as the TiddlyWiki html file.

I also recommend modifying your StyleSheet use serif fonts that are slightly larger than normal, so that the math matches surrounding text, and \\small fonts are not unreadable (as in exponents and subscripts).
{{{
.viewer {
  line-height: 125%;
  font-family: serif;
  font-size: 12pt;
}
}}}

If you had used a previous version of [[Plugin: jsMath]], it is no longer necessary to edit the main tiddlywiki.html file to add the jsMath <script> tag.  [[Plugin: jsMath]] now uses ajax to load jsMath.
!History
* 11-Nov-05, version 1.0, Initial release
* 22-Jan-06, version 1.1, updated for ~TW2.0, tested with jsMath 3.1, editing tiddlywiki.html by hand is no longer necessary.
* 24-Jan-06, version 1.2, fixes for Safari, Konqueror
* 27-Jan-06, version 1.3, improved error handling, detect if ajax was already defined (used by ZiddlyWiki)
* 12-Jul-06, version 1.4, fixed problem with not finding image fonts
* 26-Feb-07, version 1.5, fixed problem with Mozilla "unterminated character class".
* 27-Feb-07, version 1.5.1, Runs compatibly with TW 2.1.0+, by Bram Chen
!Examples
|!Source|!Output|h
|{{{The variable $x$ is real.}}}|The variable $x$ is real.|
|{{{The variable \(y\) is complex.}}}|The variable \(y\) is complex.|
|{{{This \[\int_a^b x = \frac{1}{2}(b^2-a^2)\] is an easy integral.}}}|This \[\int_a^b x = \frac{1}{2}(b^2-a^2)\] is an easy integral.|
|{{{This $$\int_a^b \sin x = -(\cos b - \cos a)$$ is another easy integral.}}}|This $$\int_a^b \sin x = -(\cos b - \cos a)$$ is another easy integral.|
|{{{Block formatted equations may also use the 'equation' environment \begin{equation}  \int \tan x = -\ln \cos x \end{equation} }}}|Block formatted equations may also use the 'equation' environment \begin{equation}  \int \tan x = -\ln \cos x \end{equation}|
|{{{Equation arrays are also supported \begin{eqnarray} a &=& b \\ c &=& d \end{eqnarray} }}}|Equation arrays are also supported \begin{eqnarray} a &=& b \\ c &=& d \end{eqnarray} |
|{{{I spent \$7.38 on lunch.}}}|I spent \$7.38 on lunch.|
|{{{I had to insert a backslash (\\) into my document}}}|I had to insert a backslash (\\) into my document|
!Code
***/
//{{{

// AJAX code adapted from http://timmorgan.org/mini
// This is already loaded by ziddlywiki...
if(typeof(window["ajax"]) == "undefined") {
  ajax = {
      x: function(){try{return new ActiveXObject('Msxml2.XMLHTTP')}catch(e){try{return new ActiveXObject('Microsoft.XMLHTTP')}catch(e){return new XMLHttpRequest()}}},
      gets: function(url){var x=ajax.x();x.open('GET',url,false);x.send(null);return x.responseText}
  }
}

// Load jsMath
jsMath = {
  Setup: {inited: 1},          // don't run jsMath.Setup.Body() yet
  Autoload: {root: new String(document.location).replace(/[^\/]*$/,'jsMath/')}  // URL to jsMath directory, change if necessary
};
var jsMathstr;
try {
  jsMathstr = ajax.gets(jsMath.Autoload.root+"jsMath.js");
} catch(e) {
  alert("jsMath was not found: you must place the 'jsMath' directory in the same place as this file.  "
       +"The error was:\n"+e.name+": "+e.message);
  throw(e);  // abort eval
}
try {
  window.eval(jsMathstr);
} catch(e) {
  alert("jsMath failed to load.  The error was:\n"+e.name + ": " + e.message + " on line " + e.lineNumber);
}
jsMath.Setup.inited=0;  //  allow jsMath.Setup.Body() to run again

// Define wikifers for latex
config.formatterHelpers.mathFormatHelper = function(w) {
    var e = document.createElement(this.element);
    e.className = this.className;
    var endRegExp = new RegExp(this.terminator, "mg");
    endRegExp.lastIndex = w.matchStart+w.matchLength;
    var matched = endRegExp.exec(w.source);
    if(matched) {
        var txt = w.source.substr(w.matchStart+w.matchLength, 
            matched.index-w.matchStart-w.matchLength);
        if(this.keepdelim) {
          txt = w.source.substr(w.matchStart, matched.index+matched[0].length-w.matchStart);
        }
        e.appendChild(document.createTextNode(txt));
        w.output.appendChild(e);
        w.nextMatch = endRegExp.lastIndex;
    }
}

config.formatters.push({
  name: "displayMath1",
  match: "\\\$\\\$",
  terminator: "\\\$\\\$\\n?", // 2.0 compatibility
  termRegExp: "\\\$\\\$\\n?",
  element: "div",
  className: "math",
  handler: config.formatterHelpers.mathFormatHelper
});

config.formatters.push({
  name: "inlineMath1",
  match: "\\\$", 
  terminator: "\\\$", // 2.0 compatibility
  termRegExp: "\\\$",
  element: "span",
  className: "math",
  handler: config.formatterHelpers.mathFormatHelper
});

var backslashformatters = new Array(0);

backslashformatters.push({
  name: "inlineMath2",
  match: "\\\\\\\(",
  terminator: "\\\\\\\)", // 2.0 compatibility
  termRegExp: "\\\\\\\)",
  element: "span",
  className: "math",
  handler: config.formatterHelpers.mathFormatHelper
});

backslashformatters.push({
  name: "displayMath2",
  match: "\\\\\\\[",
  terminator: "\\\\\\\]\\n?", // 2.0 compatibility
  termRegExp: "\\\\\\\]\\n?",
  element: "div",
  className: "math",
  handler: config.formatterHelpers.mathFormatHelper
});

backslashformatters.push({
  name: "displayMath3",
  match: "\\\\begin\\{equation\\}",
  terminator: "\\\\end\\{equation\\}\\n?", // 2.0 compatibility
  termRegExp: "\\\\end\\{equation\\}\\n?",
  element: "div",
  className: "math",
  handler: config.formatterHelpers.mathFormatHelper
});

// These can be nested.  e.g. \begin{equation} \begin{array}{ccc} \begin{array}{ccc} ...
backslashformatters.push({
  name: "displayMath4",
  match: "\\\\begin\\{eqnarray\\}",
  terminator: "\\\\end\\{eqnarray\\}\\n?", // 2.0 compatibility
  termRegExp: "\\\\end\\{eqnarray\\}\\n?",
  element: "div",
  className: "math",
  keepdelim: true,
  handler: config.formatterHelpers.mathFormatHelper
});

// The escape must come between backslash formatters and regular ones.
// So any latex-like \commands must be added to the beginning of
// backslashformatters here.
backslashformatters.push({
    name: "escape",
    match: "\\\\.",
    handler: function(w) {
        w.output.appendChild(document.createTextNode(w.source.substr(w.matchStart+1,1)));
        w.nextMatch = w.matchStart+2;
    }
});

config.formatters=backslashformatters.concat(config.formatters);

window.wikify = function(source,output,highlightRegExp,tiddler)
{
    if(source && source != "") {
        if(version.major == 2 && version.minor > 0) {
            var wikifier = new Wikifier(source,getParser(tiddler),highlightRegExp,tiddler);
            wikifier.subWikifyUnterm(output);
        } else {
            var wikifier = new Wikifier(source,formatter,highlightRegExp,tiddler);
            wikifier.subWikify(output,null);
        }
        jsMath.ProcessBeforeShowing();
    }
}
//}}}
<<plugins>>
This was written last week but I've been so busy with proposal writing that I haven't had chance to document it just yet. Will get onto that asap. In the meantime, here it is, in all its hacky glory.

Basically it's designed to work with datasets where the calibration has been conducted by standard additions of the analyte to replicate samples. The script requires a .method file and a .data file in specific formats which I'll document later. Examples can be found [[below|NH4 t=28]]

10/1/11: Now available on github: https://github.com/martwine/Analytical-data-processing-scripts

{{{
# R program to calculate concentrations for raw data using calibration by standard additions. See README.txt for summary of .dat and .method files which are required inputs.
# Martin Johnson 11/2010 martin.johnson@uea.ac.uk
# Released under creative commons license. Please use and distribute freely. But please acknowledge the originator (me).

#dataname gives name of subdirectory, .method and .data files
standard_additions<-function(dataname){
	
	data_filename<-paste(dataname,"/",dataname,".data",sep="")
	method_filename<-paste(dataname,"/",dataname,".method",sep="")

	rawdata<-read.table(data_filename,header=TRUE,fill=TRUE)

	#filter out lines flagged as bad (rowflag==0)
	rawdata<-subset(rawdata,rawdata$rowflag==1)
	
	#calculate a mean from all 'good' instrument readings (bad ones should be strings not numerics e.g. D13.23 not 13.23)
	rawdata$mean<-apply(rawdata,1,function(row){mean(as.numeric(row[5:14]),na.rm=T)})

	methoddata<-read.table(method_filename,header=TRUE)
	sample_vol<-methoddata$sample_volume #voulme in l
	stock_concn<-methoddata$stock_concn #concn in mol/l
	
	# if there's a tracer is assumed to be a member of one calibration (normally the largest addition to a particular set)
	# these variables used to get tracer which is member of calibration
	# the other (repeat) tracer measurements will be identified by type=-333
	tracer_name<-as.character(methoddata$tracer_name) #name of sample used for tracer
	tracer_type<-methoddata$tracer_type #vol of standard addition for tracer instance

	#which 'type' to be used as baseline?
	bl_method<-methoddata$baseline_method

	#start a blank list for the calibration data
	calib_out<-list()
	
	#for each calibration 'set' in the file...
	for(seti in unique(rawdata$set)){
		
		rows<-rawdata[which(rawdata$set==seti),]
		
		#calculate a baseline value if required 
		# (some intruments effectivel provide baseline-corrected raw data so this isn't needed
		# - if so, set baseline_method to -7777 in method file
		if(bl_method==-7777){baseline<-0}else{
			baselinerows<-rows[which(rows$type==bl_method),]
			baseline<-mean(baselinerows$mean)}
		#get the rows which are actua standard additions
		additions_rows<-rows[which(rows$type>=0),]
		
		# add a column giving the concentration due to the addition of standard
		#  addition vol is in ul so need to conver to l by *1e-6
		additions_rows$add_concn<-(additions_rows$type*1e-6*stock_concn)/(sample_vol+additions_rows$type*1e-6)

		#calculate a regression line and get the gradient and intercept
		regression<-lm(additions_rows$mean-baseline~additions_rows$add_concn)
		gradient<-regression[[1]][[2]]
		y_intercept<-regression[[1]][[1]]

		# calculate the concentration in the sample
		xE<-y_intercept/gradient

		# do some statistics to get the undertainty 
		#  - see http://www.uea.ac.uk/~e356/#[[Error%20analysis%20in%20standard%20additions]]
		n<-length(additions_rows$mean)
		Syoverx<-summary(regression)[[6]]
		SxE<-(Syoverx/gradient)*sqrt((1/n)+((mean(additions_rows$mean)^2)/(sum(sum((additions_rows$add_concn-mean(additions_rows$add_concn))^2))*gradient^2)))
		#95% confidence interval
		u_xE<-SxE*qt(0.975,n-2)

		#add the calibration stats for each set to the calib list
		templist<-list()
		templist["sample_id"]<-as.character(additions_rows$Desc[1])
		templist["extrapolated concentration"]<-xE
		templist$gradient<-gradient
		templist$confidence<-u_xE
		templist$baseline<-baseline
		key<-paste(dataname,"_set",seti,sep="")
		calib_out[[key]]<-templist	

		#plot calibration data and fit line
		filename<-paste(dataname,"/",key,".png",sep="")
		linedatax<-c(-xE,1.3*max(additions_rows$add_concn))
		linedatay<-(gradient*linedatax)+y_intercept		
		png(filename)
			plot(linedatax,linedatay,type="l",xlab="concentration from standard addition",ylab="instrument response",main=key,xaxs="i",yaxs="i")			
			points(additions_rows$add_concn,additions_rows$mean-baseline)
			abline(v=0)
		dev.off()	
	}

	#now for all 'sets'


	#add in a hacky extra column to correct tracer values with the correct baseline set
	# can't figure out a way to get the value of the previous row in apply in the concentration
	# calculation, otherwise this wouldn't be necessary
	bl_set_column_hack<-NULL
	for (index in 1:nrow(rawdata)){
		row<-rawdata[index,]
		ifelse(row[,"type"]==-333&&!index==1, newcolval<-rawdata[(index-1),"set"], newcolval<-0)
		bl_set_column_hack<-c(bl_set_column_hack,newcolval)
	}
	#ugly ugly ugly *must get better at R*
	rawdata<-cbind(rawdata,bl_set_column_hack)
	

	# get all the non-baseline data  (in a  roundabout way in case there are multiple baseline types)
	data_out<-subset(rawdata,rawdata$type==-999|rawdata$type==-333|rawdata$type>=0,select=c("Desc","set","type","mean","bl_set_column_hack"))
	
	#select only single element of calibration - the lowest in concentration (probably 0 added unless that row discarded with roflag) 
	# to represent sample that's been calibrated
	# don't discard calibration rows which are equal to tracers
	data_out<-data_out[-which((duplicated(data_out$Desc)&data_out$type>=0)&!(data_out$Desc==tracer_name&data_out$type==tracer_type)),]



	#calculate concentration - by value-baseline/gradient for unknowns and tracers, 
	# and by getting relevant extrpolated concentrations from calib_out for directly calibrated samples
	data_out$concentration<-apply(data_out,1,function(row){
		key<-paste(dataname,"_set",row[2],sep="")
		ifelse(as.numeric(row[3])==-333&!row[[5]]==0,bl_key<-paste(dataname,"_set",row[5],sep=""),bl_key<-key)	
		ifelse((as.numeric(row[3])>=0)&&!(as.character(row[1])==tracer_name&&as.numeric(row[3])==tracer_type),calib_out[[key]][[2]],(as.numeric(row[4])-calib_out[[bl_key]][[5]])/calib_out[[key]][[3]])
		})

	#apply uncertainty - at the moment this is just the extrapolation uncertainty for direclty calibrated - need to do better stats on unknowns
	data_out$u<-apply(data_out,1,function(row){
		key<-paste(dataname,"_set",row[2],sep="")
		calib_out[[key]][[4]]
	})

	#change type of tracer-equivalent calibration point to -333 to be clearly a tracer in the output
	data_out$type<-apply(data_out,1,function(row){
		ifelse(as.character(row[1])==tracer_name&&as.numeric(row[3])==tracer_type,row[3]<--333,row[3])
	})	

		
	data_out<-subset(data_out,select=c("Desc","set","type","mean","concentration","u"))
	#write out the calibration data and the results file
	dput(calib_out,file=paste(dataname,"/",dataname,".calib",sep=""))
	write.table(as.data.frame(data_out),file=paste(dataname,"/",dataname,".concn",sep=""),sep=",")

}
}}}
/***
|Name|RecentChangesPlugin|
|Source|http://www.TiddlyTools.com/#RecentChangesPlugin|
|Version|2.2.1|
|Author|Eric Shulman|
|License|http://www.TiddlyTools.com/#LegalStatements|
|~CoreVersion|2.1|
|Type|plugin|
|Description|display droplist of recently changed tiddlers with goto, edit, and preview buttons|
!!!!!Usage
<<<
The {{{<<recentChanges>>}}} macro displays a droplist of all tiddlers that have been changed within the last N days (default=10 days).  
{{{
<<recentChanges>>
<<recentChanges #ofdays summary noEdit previewheight previewclass>>
}}}
where:
* #ofdays specifies the time limit for listing changed tiddlers.  Use 0 (zero) to list all tiddlers in the document.
* ''summary'' is an optional keyword that outputs only the summary text (without the droplist or buttons)
* ''noEdit'' is an optional keyword that hides the 'edit' button
* previewheight is a CSS height measurement and sets the FIXED height of the tiddler preview area (default is 15em)
* previewclass is any CSS classname, and can be used to apply custom styles to the preview area (default is to use the standard 'viewer' class)
<<<
!!!!!Examples
<<<
{{smallform{
{{{<<recentChanges>>}}}
<<recentChanges>>
{{{<<recentChanges 30 summary>>}}}
<<recentChanges 30 summary>>

{{{<<recentChanges 30 noedit 10em groupbox>>}}}
<<recentChanges 30 noedit 10em groupbox>>
}}}
<<<
!!!!!Revisions
<<<
2009.09.07 [2.2.1] fixed typo in shadow definition
2009.07.02 [2.2.0] added optional 'noedit' keyword to hide 'edit' button
2008.07.01 [2.1.0] added optional 'summary' keyword for simple text output
2008.05.01 [2.0.1] fixup for titles with double-quotes
2007.07.26 [2.0.0] re-written as plugin
2006.10.02 [1.0.0] initial release (as inline script ShowRecentChanges)
<<<
!!!!!Code
***/
//{{{
version.extensions.RecentChangesPlugin= {major: 2, minor: 2, revision: 1, date: new Date(2009,9,7)};

config.shadowTiddlers.RecentChanges='<<recentChanges>>';

config.macros.recentChanges = {
	handler: function(place,macroName,params,wikifier,paramString,tiddler) {
		var days=10; if (!isNaN(params[0])) days=parseInt(params[0]); // time limit in days (use 0 for all tiddlers)
		var summary=params[1]&&params[1].toLowerCase()=='summary'; if (summary) params.shift();
		var noedit=params[1]&&params[1].toLowerCase()=='noedit'; if (noedit) params.shift();
		var height='15em'; if (params[1]) height=params[1]; // preview area fixed height
		var previewclass='viewer'; if (params[2]) previewclass=params[2]; // preview area CSS class
		var tiddlers=store.getTiddlers('modified','excludeLists').reverse();
		var count=tiddlers.length;
		if (days) {
			var timelimit=(new Date()).getTime()-86400000*days;
			for (var count=0; count<tiddlers.length && tiddlers[count].modified>timelimit; count++);
		}
		var s=count+' tiddlers have changed since ';
		s+=new Date(timelimit).formatString('DDD, MMM DDth YYYY 0hh:0mm');
		s+=' ('+days+' days ago)';
		if (summary)
			{ wikify(s,place); return; }
		var opts='<option value="">'+s+'</option>';
		for (var i=0; i<count; i++) { var t=tiddlers[i];
			opts+='<option value="'+t.title.replace(/"/g,"&#x22;")+'">';
			opts+=t.modified.formatString('YYYY.0MM.0DD 0hh:0mm')+' - '+t.title;
			opts+='</option>';
		}
		var h=store.getTiddlerText('RecentChangesPlugin##html')
		h=h.replace(/%options%/,opts);
		h=h.replace(/%listwidth%/,noedit?79.5:69.5);
		h=h.replace(/%noedit%/,noedit?'none':'inline');
		createTiddlyElement(place,'div').innerHTML=h;
		var preview=createTiddlyElement(place,'div',null,previewclass);
		preview.style.display='none';
		preview.style.whiteSpace='normal';
		preview.style.overflow='auto';
		preview.style.height=height;
	}
}
//}}}
/***
//{{{
!html
<form><select size=1 name="list" style="width:%listwidth%%"
	onchange="this.form.goto.disabled=this.form.edit.disabled=this.form.preview.disabled=!this.value.length;
		var target=this.parentNode.parentNode.nextSibling; removeChildren(target);
		if (!this.value.length)
			{ target.style.display='none'; this.form.preview.value='preview'; }
		else if (target.style.display=='block') {
			wikify('<'+'<tiddler [['+this.value+']]>'+'>',target);
			target.style.display='block';
			this.form.preview.value='done';
		}
">%options%</select><!--
--><input type="button" name="goto" value="goto" disabled title="view selected tiddler" style="width:10%"
	onclick="var target=this.parentNode.parentNode.nextSibling; removeChildren(target);
		target.style.display='none'; this.form.preview.value='preview';
		story.displayTiddler(story.findContainingTiddler(this),this.form.list.value);
"><input type="button" name="edit" value="edit" disabled title="edit selected tiddler" style="width:10%;display:%noedit%"
	onclick="var target=this.parentNode.parentNode.nextSibling; removeChildren(target);
		target.style.display='none'; this.form.preview.value='preview';
		story.displayTiddler(story.findContainingTiddler(this),this.form.list.value,DEFAULT_EDIT_TEMPLATE);
"><input type="button" name="preview" value="preview" disabled title="show/hide tiddler preview" style="width:10%"
	onclick="var target=this.parentNode.parentNode.nextSibling;
		if (this.value=='preview') {
			removeChildren(target);
			wikify('<'+'<tiddler [['+this.form.list.value+']]>'+'>',target);
			target.style.display=this.form.list.value.length?'block':'none'; this.value='done';
		} else {
			removeChildren(target);
			target.style.display='none'; this.value='preview';
		}
"></form>
!end
//}}}
***/
 
*<<closeAll>>
*<<permaview>>
*<<saveChanges>>
*<<newTiddler>>
*[[About]]
*[[Air-sea gas exchange |AirSea]]
*[[Marine Biogeochemistry |MarineBiogeochemistry]]
*[[Uncertainty]]
*[[Bibliography]]
Back in September I managed to run some seawater samples through the new Skalar Formacs TC/TN analyser to measure dissolved organic nitrogen (by difference with inorganic N measured elsewhere). The results looked lovely but each time I ran some samples, at some point afterwards the high temperature Co/Cr/CeO3 catalyst blocked with crystals and the glass tube which contained it exploded.

As mission-critical commercial samples are being run 3 days a week on the machine it's imperative that I don't break it any more so I'm beginning some very tentative tests to see what I can do to make seawater analysis possible. In theory there shouldn't be a problem - Skalar are surprised that it doesn't just work. The catalyst maybe shouldn't last as long and may need renewing every few hundred samples, but exploding tubes after 50 samples is a mystery...

Today I'm running 3 seawater samples for TN and TC and will then, at Skalar's suggestion, reduce combustion tube T to 150 Celcius (from 850) and run 20 distilled water samples through. While this is happening I'm also going to RTFM! 
[[Yesterday's experiment|Running seawater samples without breaking the TN machine #1]] appears to have worked! - at least the combustion tube (the glass tube that contains the catalyst) isn't blocked or broken - I can tell this because the carrier gas flow is still OK. We don't know whether the catalyst is spent - getting the tube out to have a look at it is a big job.

Instead I'm going to press on with a bigger batch of seawater samples - 20 in all. So that some vaguely useful data comes out I've homogenized 20 of our out of date vials of TC/TN standard reference water of known (low) concentration (can be taken as approximate only, as they're 6 years out of date, although I'm sure they're fine...) and will run these today. If the machine doesn't break this will give us a good estimate of the precision of the instrument at low concentrations. Following analysis I'll cool the combustion chamber to 150 celcius and run through 20 DIW samples. Yesterday we left the carrier gas flowing after the analysis (i.e. flow 'on' in standby mode). Jasper at Skalar says that this isn't necessary, but to avoid changing too many variables at once, we'll leave it on again today. 

If this works then the next steps are: 
# try with carrier flow off in standby 
# try 50 sample seawater run
# try samples spiked with mercuric chloride 
I returned to the machine this morning and... it ISN'T broken! AT least the carrier flow is unchanged which is the only metric of 'working' with respect to the combustion tube other than taking it out for visual inspection. That can't be done today as other people need to run samples. 

What we think was happening is that the salt from the samples was precipitating out right at the narrow entrance to the catalyst tube and causing it to block. By cooling the chamber down and running lots of distilled water samples through we're spreading the salt crystals out over the column and removing potential blockage before it occurs. I suspect we're substantially shortening the life of the catalyst by smearing salt all over it, but a visual inspection will tell us more- that's scheduled for next Monday.

The injection volume is 200uL, and each sample gets run through an average of 3 times (the machine re-runs samples until it gets 2 peaks within some threshold value of each other - set to 5% at the moment), so for 50 samples (the size of a typical run) thats 0.2*3*50 = 30ml of seawater. At ~35g/L salt in seawater that's about 1g of salt added to the column for a day's set of seawater samples (it can't go anywhere else). Total mass of catalyst in colume is probably less that 100g, so that's pretty significant. 

I'll work up the precision estimate from the repeat seawater measurements shortly.
After running a batch of seawater samples ([[SMARTBuoyTNanalysis.180111]]) containing HgCl2 and following the washing / cooling protocol outlined below i.e. running a set of 40 distilled water samples through with the column cooling to 150 celcius, the machine seemed to be working fine - with really good reproducibility at the end of the run, no loss of flow etc. However, the catalyst had turned blue [[see pic here|http://moblog.net/view/947389/catalyst-from-tn-machine-after-70-seawater-samples]] and looked just like the picture of a 'spent' catalyst in the instruction manual for the machine! As it seemed to be working fine I decided to press on and ran more samples yesterday ([[SMARTBuoyTNanalysis.250111]]), which also have come out fine. So it seems like a bit of blueness on the outside of the tube isn't too serious - as long as it's not all the way through the catalyst... Will keep an eye on it.

Also, I think my argument for what the freshwater washes were doing was wrong - the narrow bit of the combustion tube, at the bottom, is actually the outlet, so hopefully repeated washes will actually be removing the salt from the catalyst entirely...
Ammonium samples were taken and fixed in the field from [[Warp]] and [[Gabbard stations]] on [[THV Alert cruise (22/10/10) | AlertOct2010]] using the standard fluorimetric ammonium method (see Johnson et al 2008) and the standard [[working reagent mix | OPAReagent]], callibrated by standard additions of a 50uM NH4Cl stock standard solution by autopipettes. Standard additions are ideal because the fluroimetric response is modified by matrix effects (salinity, particulate loading) and also seemingly by the presence of HgCl2.

Raw Data:

|Station| Treatment | Vol standard added / uL | reading1 | reading2 | reading3 | reading4 |
| [[Warp]] | No HgCl2 | BF | 10.27 | 12.61 | 11.60 |  |
| [[Warp]] | No HgCl2 | BF/WR | 31.8 | 27.3 | 38.2 |  |
| [[Warp]] | No HgCl2 | 0 | 52.66 | 52.78 |  |  |
| [[Warp]] | No HgCl2 | 50 | 70.26 | 73.65 | 74.25 |  |
| [[Warp]] | No HgCl2 | 100 | 101.91 | 101.63 |  |  |
| [[Warp]] | No HgCl2 | 250 | 154.12 | 163.22 | 164.62 |  |
| [[Warp]] | No HgCl2 | 500 | 289.63 | 289.93 |  |  |
| [[Warp]] | No HgCl2 | 1000 | 540.12 | 561.51 | 550.68 |  |
| [[Warp]] | HgCl2 | BF | 7.49 | 7.43 | 7.97 |  |
| [[Warp]] | HgCl2 | BF/WR | 28.96 | 27.97 | 29.62 |  |
| [[Warp]] | HgCl2 | 0 | 78.07 | 78.28 | 80.30 |  |
| [[Warp]] | HgCl2 | 50 | 73.73 | 74.74 | 75.12 |  |
| [[Warp]] | HgCl2 | 100 | 103.8 | 103.91 | 104.62 |  |
| [[Warp]] | HgCl2 | 250 | 172.91 | 175.00 | 173.79 |  |
| [[Warp]] | HgCl2 | 500 | 331.00 | 327.43 | 327.81 |  |
| [[Warp]] | HgCl2 | 1000 | 574.71 | 577.15 | 580.02 | 568.25 |
| [[Gabbard]] | No HgCl2 | BF | -0.08 | 0.21 | 0.56 |  |
| [[Gabbard]] | No HgCl2 | BF/WR | 0.67 | 0.68 | 0.69 |  |
| [[Gabbard]] | No HgCl2 | 0 | -2.23 | -2.17 | -2.24 |  |
| [[Gabbard]] | No HgCl2 | 50 | 49.09 | 49.27 |  |  |
| [[Gabbard]] | No HgCl2 | 100 | 71.81 | 70.13 | 71.13 |  |
| [[Gabbard]] | No HgCl2 | 250 | 149.08 | 151.65 |  |  |
| [[Gabbard]] | No HgCl2 | 500 | 278.68 | 287.09 | 284.43 |  |
| [[Gabbard]] | No HgCl2 | 1000 | 536.34 | 541.78 |  |  |
| [[Gabbard]] | HgCl2 | BF | -2.49 | -2.46 |  |  |
| [[Gabbard]] | HgCl2 | BF/WR | 6.49 | 5.38 | 3.99 | 3.50 3.01 WTF? |
| [[Gabbard]] | HgCl2 | 0 | 29.28 | 28.74 |  |  |
| [[Gabbard]] | HgCl2 | 50 | 53.11 | 53.89 |  |  |
| [[Gabbard]] | HgCl2 | 100* | 29.10 | 29.41 |  |  |
| [[Gabbard]] | HgCl2 | 250* | 205.56 | 207.41 |  |  |
| [[Gabbard]] | HgCl2 | 500 | 302.75 | 304.98 |  |  |
| [[Gabbard]] | HgCl2 | 1000 | 579.3 | 575.4 |  |  |

* additions incorrectly added - both 100 and 250uL added to 250 addition, so calibration actually 0, 50, 0, 350, 500 oops. Nothing like being on the back deck of a ship with a stinking cold to make you screw up fiddly tasks...
!!! ~ST1
*Dowsing site 8/02/11
* Between Stn11 and Stn15 (CTDs, both at Dowsing) 
* ST1.EDU: EDU sampler bags 4-15 fired from single water sample in tank
* ST1.Aqua: Aquamonitor sampler bags 1-4 fired from same as above. Refilled for bags 5-15. Same location so shouldn't be a big effect anyway

!!! ~ST2
*West Gabbard site 18:00-20:30 10/2/11
* filled large (~100L) water butt from pumped seawater supply, allowed to drain and refilled whilst on station
* ST2.EDU: EDU sampler, 10 bags fired 18:10 - 18:30 (was programmed to fire at 18:30!)
* ST2.Aqua: Aquamonitor 10 bags fired, 19:20 - 20:30 (programmed to start at 18:30!!!)
* stupid machines
* ST2.TN: 3 mesh screened and 1 unscreened sample taken from approximately the same depth in the water butt as the inlets to the EDU sampler and Aquamonitor into three-times rinsedglass 300ml winchester bottles, treated with 0.6ml HgCl2.001 as per CTD samples
* ST2.NH4: 6 samples taken for calibration by standard additions: 
** 30ml sample, 
** 50,100,150,200,400 uL additions of 50uM stock standard
** 1ml W.R. - reduce w.r.:sample volume ratio to try to improve precision. Used to have sensitivity of +/-2% when I did this method back in the PhD days! Also, already looking low on working reagent...  

!!! ~ST3
* WARP Anchorage site  07:15-08:30 12/2/11
* filled large (~100L) water butt from pumped seawater supply, allowed to drain and refilled whilst on station
* ST3.EDU: EDU sampler, 10 bags fired 07:45 - 08:15 (as programmed)
* ST3.Aqua: Aquamonitor 10 bags fired, 07:15 - 08:30 (as programmed)
* clever machines!
* ST3.TN as ST2.TN
* ST3.NH4: 8 samples taken for calibration by standard additions: 
** 30ml sample, 

!!!~ST4
* Celtic Deep site 10:00-11:30 14/2/11
* filled large (~100L) water butt from pumped seawater supply, allowed to drain and refilled whilst on station
* ST4.Aqua: 15 bags fired 10:00-11:30
* ST4.EDU 15 bags fired 10:30 - 11:00
* ST4.TN as ST3.TN
* ST4.NH4 as above
Run info:

Sample volume for standard additions: 5ml. Standard: TNTCMixedstock1. Std add. volumes: 0, 15,30,45,60,75,150 uL.

CRMs: LCW10.09, DSR05.10

Tracer: 5ml LCW05.04 + 300uL TN standard

Samples run: Warp 80,84 West Gabbard 68,70,72

[[Raw data|https://spreadsheets.google.com/ccc?key=0AqRtHz1X9oQ6dHNTNUR4bmJ3QTBpNFJMc1VyX3cwQVE&hl=en_GB]]

Corrections to raw data:

1. sample 52 - W. Gabbard 70 bag 2 didn't exist so duplicate W. Gabbard 70 bag 1 put in its place.
2. second calibration conducted with Bag 11 not 17 due to loss of sample.
Sample volume for standard additions: 5ml. Standard: TNTCMixedstock1. Std add. volumes: 0, 15,30,45,60,75,150 uL.

CRMs: LCW10.09, DSR05.10

Tracer: 5ml LCW05.04 + 300uL TN standard

Samples run: West Gabbard 64,66, 69(1), 71(1,2,4)

corrections to raw data

W. Gabbard 71 bag 4
->replaced milliQ with LCW0504+300

[[raw data|https://spreadsheets.google.com/ccc?key=0AqRtHz1X9oQ6dDFHLXRkVXBFcHozaUU1S29IczhiZVE&hl=en_GB#gid=0]]
Sample volume for standard additions: 5ml. Standard: TNTCMixedstock1. Std add. volumes: 0, 15,30,45,60,75,150 uL.

CRMs: LCW10.09, DSR05.10

Tracer: 5ml LCW05.04 + 300uL TN standard

Samples run: Dowsing 10, Warp 82,86,88,89 

corrections to raw data

position 5 -> replaced LCW0504 with Dowsing10_Bag16.

[[raw data|https://spreadsheets.google.com/ccc?key=0AqRtHz1X9oQ6dFQzVnQ2bG9tR2xDaEJfcjdZOEZxcnc&hl=en_GB#gid=0]]
First run of SMARTBuoy archived samples on the SkalarFormacs for TN after the tests seemed to work without breaking the catalyst. 

Sample volume for standard additions: 6ml. Standard: TNTCMixedstock1. Std add. volumes: 0, 15,30,45,60,150,300 uL.

CRMs: [LCW10.09], [[DSR05.10]]

Tracer: 6ml LCW 05.04 + 300uL TN standard

Samples run: Dowsing 11, Celtic Deep 6

notes: Dowsing 11 bag 14 had particle in it (looked like plastic of some sort - poss from pots?)

[[Raw data|https://docs.google.com/leaf?id=0AqRtHz1X9oQ6dGpCdUU5cmFtYWEwUUdNU244ZVVnb0E&sort=name&layout=list&pid=0B6RtHz1X9oQ6MDNmZjViNmMtMTgyZi00YWE4LWI1NmItYjJkNmE5YzM1MmJh]]
Run to finish analysis of Dowsing SMARTBuoy archive to date (including samples retrieved during CEND311). Two false starts due to unidentified problem - turned out to be switch at back of N analyser set at low sensitivity - had been knocked when instrument moved up to accommodate an old HPLC that needed a home. As a result samples 1-11 except Dowsing 13 Bag 1 have failed due to lack of sample volume. This was the first tracer, CRM and calibration - all of which were duplicated at the end of the run so all is not lost.

Data looks OK at first glance, need to work it up. However, when I returned to the instrument this morning the catalyst was blocked, so at some point overnight, hopefully after the samples were done, it all went wrong. 

Run info:

Sample volume for standard additions: 5ml. Standard: TNTCMixedstock1. Std add. volumes: 0, 15,30,45,60,120,240 uL.

~CRMs: [[LCW10.09]], [[DSR05.10]]

Tracer: 5ml LCW05.04 + 300uL TN standard

Samples run: Dowsing 10, Dowsing 13

[[Raw data|https://docs.google.com/leaf?id=0AqRtHz1X9oQ6dHdkdDQwQ3M3dmxhZ2pCd2RPeFA2OWc&sort=name&layout=list&pid=0B6RtHz1X9oQ6MDNmZjViNmMtMTgyZi00YWE4LWI1NmItYjJkNmE5YzM1MmJh&cindex=2]]

note: due to time constraints (was the end of the day by the time the successfgul run was started) and the fact that the first 10 samples were pretty much guaranteed to fail due to insufficient sample volume, the run was started when the catalyst wasn't fully up to temperature (772 C). It would have reached 850 within the first 2 or 3 samples as it heats up rather rapidly. 
Sample volume for standard additions: 5ml. Standard: TNTCMixedstock1. Std add. volumes: 0, 15,30,45,60,75,150 uL.

CRMs: LCW10.09, DSR05.10

Tracer: 5ml LCW05.04 + 300uL TN standard

Samples run: Dowsing 10(EDU sampler), 11(2) 

[[raw data|https://spreadsheets.google.com/ccc?key=0AqRtHz1X9oQ6dGpXaGlMLVR3LWxsMWFxdWlCVnhFT3c&hl=en_GB#gid=0]]
Sample volume for standard additions: 5ml. Standard: TNTCMixedstock1. Std add. volumes: 0, 15,30,45,60,200 uL.

CRMs: LCW10.09, DSR05.10

Tracer: 5ml LCW 05.04 + 300uL TN standard

Samples run: Dowsing 8,9, Warp82
From the following runs:

[[SMARTBuoyTNanalysis.180111]] 
[[SMARTBuoyTNanalysis.250111]] 
[[SMARTBuoyTNanalysis.210211]] 
[[SMARTBuoyTNanalysis.080311]] 

The following values (in uM) for the CRMs and tracers were measured:

[[data|https://spreadsheets.google.com/ccc?key=0AqRtHz1X9oQ6dERYTG03ZEttaVFMTXk0WVlYaE5uZ1E&hl=en_GB#gid=0]]

Consensus values for the DSR0510 CRM is 31-33 uM, so we scale these data so that the mean value of DSR0510 in each run in 32. This tends to bring the values of LCW0504+300 closer together between runs although there is still significant variability (108 - 121 uM). However these samples (out of date low N CRMs spiked with 300uL of standard) are used as tracers within each run (where their variance is very small). This is achieved by taking multiple vials of the LCW0504 CRM and mixing them together in a beaker to ensure homogeneity across samples, before pipetting 5ml into each vial and adding the 300uL of standard. Therefore contamination is highly likely and it would not be expected that they should be the same between runs. 


/***
|Name|SinglePageModePlugin|
|Source|http://www.TiddlyTools.com/#SinglePageModePlugin|
|Documentation|http://www.TiddlyTools.com/#SinglePageModePluginInfo|
|Version|2.9.7|
|Author|Eric Shulman|
|License|http://www.TiddlyTools.com/#LegalStatements|
|~CoreVersion|2.1|
|Type|plugin|
|Description|Show tiddlers one at a time with automatic permalink, or always open tiddlers at top/bottom of page.|
This plugin allows you to configure TiddlyWiki to navigate more like a traditional multipage web site with only one tiddler displayed at a time.
!!!!!Documentation
>see [[SinglePageModePluginInfo]]
!!!!!Configuration
<<<
<<option chkSinglePageMode>> Display one tiddler at a time
><<option chkSinglePagePermalink>> Automatically permalink current tiddler
><<option chkSinglePageKeepFoldedTiddlers>> Don't close tiddlers that are folded
><<option chkSinglePageKeepEditedTiddlers>> Don't close tiddlers that are being edited
<<option chkTopOfPageMode>> Open tiddlers at the top of the page
<<option chkBottomOfPageMode>> Open tiddlers at the bottom of the page
<<option chkSinglePageAutoScroll>> Automatically scroll tiddler into view (if needed)

Notes:
* The "display one tiddler at a time" option can also be //temporarily// set/reset by including a 'paramifier' in the document URL: {{{#SPM:true}}} or {{{#SPM:false}}}.
* If more than one display mode is selected, 'one at a time' display takes precedence over both 'top' and 'bottom' settings, and if 'one at a time' setting is not used, 'top of page' takes precedence over 'bottom of page'.
* When using Apple's Safari browser, automatically setting the permalink causes an error and is disabled.
<<<
!!!!!Revisions
<<<
2010.11.30 2.9.7 use story.getTiddler()
2008.10.17 2.9.6 changed chkSinglePageAutoScroll default to false
| Please see [[SinglePageModePluginInfo]] for previous revision details |
2005.08.15 1.0.0 Initial Release.  Support for BACK/FORWARD buttons adapted from code developed by Clint Checketts.
<<<
!!!!!Code
***/
//{{{
version.extensions.SinglePageModePlugin= {major: 2, minor: 9, revision: 7, date: new Date(2010,11,30)};
//}}}
//{{{
config.paramifiers.SPM = { onstart: function(v) {
	config.options.chkSinglePageMode=eval(v);
	if (config.options.chkSinglePageMode && config.options.chkSinglePagePermalink && !config.browser.isSafari) {
		config.lastURL = window.location.hash;
		if (!config.SPMTimer) config.SPMTimer=window.setInterval(function() {checkLastURL();},1000);
	}
} };
//}}}
//{{{
if (config.options.chkSinglePageMode==undefined)
	config.options.chkSinglePageMode=false;
if (config.options.chkSinglePagePermalink==undefined)
	config.options.chkSinglePagePermalink=true;
if (config.options.chkSinglePageKeepFoldedTiddlers==undefined)
	config.options.chkSinglePageKeepFoldedTiddlers=false;
if (config.options.chkSinglePageKeepEditedTiddlers==undefined)
	config.options.chkSinglePageKeepEditedTiddlers=false;
if (config.options.chkTopOfPageMode==undefined)
	config.options.chkTopOfPageMode=false;
if (config.options.chkBottomOfPageMode==undefined)
	config.options.chkBottomOfPageMode=false;
if (config.options.chkSinglePageAutoScroll==undefined)
	config.options.chkSinglePageAutoScroll=false;
//}}}
//{{{
config.SPMTimer = 0;
config.lastURL = window.location.hash;
function checkLastURL()
{
	if (!config.options.chkSinglePageMode)
		{ window.clearInterval(config.SPMTimer); config.SPMTimer=0; return; }
	if (config.lastURL == window.location.hash) return; // no change in hash
	var tids=decodeURIComponent(window.location.hash.substr(1)).readBracketedList();
	if (tids.length==1) // permalink (single tiddler in URL)
		story.displayTiddler(null,tids[0]);
	else { // restore permaview or default view
		config.lastURL = window.location.hash;
		if (!tids.length) tids=store.getTiddlerText("DefaultTiddlers").readBracketedList();
		story.closeAllTiddlers();
		story.displayTiddlers(null,tids);
	}
}


if (Story.prototype.SPM_coreDisplayTiddler==undefined)
	Story.prototype.SPM_coreDisplayTiddler=Story.prototype.displayTiddler;
Story.prototype.displayTiddler = function(srcElement,tiddler,template,animate,slowly)
{
	var title=(tiddler instanceof Tiddler)?tiddler.title:tiddler;
	var tiddlerElem=story.getTiddler(title); // ==null unless tiddler is already displayed
	var opt=config.options;
	var single=opt.chkSinglePageMode && !startingUp;
	var top=opt.chkTopOfPageMode && !startingUp;
	var bottom=opt.chkBottomOfPageMode && !startingUp;
	if (single) {
		story.forEachTiddler(function(tid,elem) {
			// skip current tiddler and, optionally, tiddlers that are folded.
			if (	tid==title
				|| (opt.chkSinglePageKeepFoldedTiddlers && elem.getAttribute("folded")=="true"))
				return;
			// if a tiddler is being edited, ask before closing
			if (elem.getAttribute("dirty")=="true") {
				if (opt.chkSinglePageKeepEditedTiddlers) return;
				// if tiddler to be displayed is already shown, then leave active tiddler editor as is
				// (occurs when switching between view and edit modes)
				if (tiddlerElem) return;
				// otherwise, ask for permission
				var msg="'"+tid+"' is currently being edited.\n\n";
				msg+="Press OK to save and close this tiddler\nor press Cancel to leave it opened";
				if (!confirm(msg)) return; else story.saveTiddler(tid);
			}
			story.closeTiddler(tid);
		});
	}
	else if (top)
		arguments[0]=null;
	else if (bottom)
		arguments[0]="bottom";
	if (single && opt.chkSinglePagePermalink && !config.browser.isSafari) {
		window.location.hash = encodeURIComponent(String.encodeTiddlyLink(title));
		config.lastURL = window.location.hash;
		document.title = wikifyPlain("SiteTitle") + " - " + title;
		if (!config.SPMTimer) config.SPMTimer=window.setInterval(function() {checkLastURL();},1000);
	}
	if (tiddlerElem && tiddlerElem.getAttribute("dirty")=="true") { // editing... move tiddler without re-rendering
		var isTopTiddler=(tiddlerElem.previousSibling==null);
		if (!isTopTiddler && (single || top))
			tiddlerElem.parentNode.insertBefore(tiddlerElem,tiddlerElem.parentNode.firstChild);
		else if (bottom)
			tiddlerElem.parentNode.insertBefore(tiddlerElem,null);
		else this.SPM_coreDisplayTiddler.apply(this,arguments); // let CORE render tiddler
	} else
		this.SPM_coreDisplayTiddler.apply(this,arguments); // let CORE render tiddler
	var tiddlerElem=story.getTiddler(title);
	if (tiddlerElem&&opt.chkSinglePageAutoScroll) {
		// scroll to top of page or top of tiddler
		var isTopTiddler=(tiddlerElem.previousSibling==null);
		var yPos=isTopTiddler?0:ensureVisible(tiddlerElem);
		// if animating, defer scroll until after animation completes
		var delay=opt.chkAnimate?config.animDuration+10:0;
		setTimeout("window.scrollTo(0,"+yPos+")",delay); 
	}
}

if (Story.prototype.SPM_coreDisplayTiddlers==undefined)
	Story.prototype.SPM_coreDisplayTiddlers=Story.prototype.displayTiddlers;
Story.prototype.displayTiddlers = function() {
	// suspend single/top/bottom modes when showing multiple tiddlers
	var opt=config.options;
	var saveSPM=opt.chkSinglePageMode; opt.chkSinglePageMode=false;
	var saveTPM=opt.chkTopOfPageMode; opt.chkTopOfPageMode=false;
	var saveBPM=opt.chkBottomOfPageMode; opt.chkBottomOfPageMode=false;
	this.SPM_coreDisplayTiddlers.apply(this,arguments);
	opt.chkBottomOfPageMode=saveBPM;
	opt.chkTopOfPageMode=saveTPM;
	opt.chkSinglePageMode=saveSPM;
}
//}}}
Dr. Martin Johnson
Open Notebook
http://www.uea.ac.uk/~e356/index.html
https://spreadsheets.google.com/spreadsheet/ccc?key=0AqRtHz1X9oQ6dHhUMW1jUXF1N2VLX2ZVcVNPS3ZnY0E&hl=en_GB
/***
/%[[StyleSheetLayout]]
[[StyleSheetColors]]%/
!Rin (Beta!!!!) for TiddlyWiki 2.0
inspired by Broken Kode and implemented by Clint Checketts
http://tiddlystyles.com/#theme:Rin

!General Styles /% ============================================================ %/
***/
/*{{{*/
a,
a.tiddlyLink,
a.button,
a.externalLink{
 color: #005d93;
 text-decoration: none;
 background: transparent;
 border: 0;
}

a:hover,
a.tiddlyLink:hover,
a.button:hover,
a.externalLink:hover{
 border: 0;
 color: #900;
 text-decoration: underline;
}

body {
 background-color: #fff;
 font-family: Verdana, Arial, Helvetica, sans-serif;
}

#contentWrapper{
 border: 0;
 margin: .5em 1em;

}

/*}}}*/
/***
!Header Styles /% ============================================================ %/
***/
/*{{{*/
.header {
 height: 150px;
 background: url('rinback.jpg') repeat-x bottom left;
 position: relative;
}

.titleLine{
 background: #ccc url('ringradient.jpg') repeat-x top center;
 padding: 0 5px;
}

.siteTitle, .siteSubtitle{
 display: inline;
 font-size: 11px;
 line-height: 25px;
 font-weight: bold;
 color: #000;
}

.siteTitle a{
 color: #000;
}

.siteTitle a:hover, .siteSubtitle a:hover,.header .headerOptions a:hover{
 color: #cdcecf;
 text-decoration: none;
 background: transparent;
}

.siteSubtitle, #siteSubtitle a{
 font-weight: normal;
 color: #8b9198;
}

.headerOptions{
 position: absolute;
 z-index: 10;
 top: 4px;
 right: 17px;
 text-align: right;
 font-size: .9em;
}

.headerOptions a{
 position: relative;
 top: -2px;
 color: #8b9190;
}

.headerOptions .sliderPanel{
 color: #000;
 background: #fff;
 border-right: 2px solid #999;
 border-bottom: 2px solid #999;
 border-left: 1px solid #ccc;
 font-size: 10px;
 text-align: left;
 line-height: 1.2em;
 padding: .5em 1em;
 margin: -3px -2px 0 0;
 width: 180px; 
}

.headerOptions input{
 margin: 0em 1em 0 .5em;
 font-size: 9px;
}
/*}}}*/
/***
!Top menu styles /% =========================================================== %/
***/
/*{{{*/
#rinTopMenu{
 position: absolute;
 bottom: 0;
 left: 0;
 width: auto;
 padding: 0;
 margin: 0;
 color: #fff;
}
#rinTopMenu br{
 display: none;
}

#rinTopMenu a{
color: #e6e6e6;
}

#rinTopMenu ul{
 margin: 0 0 2px 2px;
 padding: 0;
}

#rinTopMenu li{
 display: inline;

}

#rinTopMenu li a.tiddlyLink,#rinTopMenu li a.button,#rinTopMenu li a.externalLink{
 padding: 2px 10px;
 color: #e6e6e6;
 text-decoration: none;
}

#rinTopMenu li a.tiddlyLink:hover,#rinTopMenu li a.button:hover,#rinTopMenu li a.externalLink:hover{
 background: #97ced5;
 color: #19729e;
}
/*}}}*/
/***
!Sidebar styles /% =========================================================== %/
***/
/*{{{*/
#rinSidebar{
 float: left;
 margin: 9px 0 0 15px;
 width: 220px;
}

#sidebarOptions a.button{
 display: inline;
}

.sidebarBlock{
 display: block;
 margin: 0 0 .5em 0;
 background: #fff;
 padding-bottom: 5px;
}

.sidebarBlock h1, .sidebarBlock h2, .sidebarBlock h3, .sidebarBlock .tabset{
 background: #ccc url('ringradient.jpg') repeat-x top left;
 font-size: 11px;
 line-height: 23px;
 font-weight: bold;
 color: #000; 
 padding-left: 5px ;
}

.sidebarBlock .tabset{
 padding: 0;
}

#rinSidebar .sidebarBlock .tabContents,
#displayArea .sidebarBlock .tabContents .tabContents, 
#displayArea .viewer .tabUnselected,
#displayArea .viewer .tabContents .tabSelected{
 background: #fff;
 border: 0;
 width: 205px;
}


#sidebar .sidebarBlock .tabContents .tabContents,
#displayArea .sidebarBlock .tabContents,
#displayArea .viewer .tabSelected,
#displayArea .viewer .tabContents .tabUnselected{
 background: #f5f6f7;
}

#sidebar .sidebarBlock .tabContents .tab{
 background: #f5f6f8;
}


#sidebar .sidebarBlock .tabContents .tabUnselected{
 background: #f0f0f0;
}

#sidebar .sidebarBlock .tabContents .tabUnselected:hover{
 text-decoration: underline;
}


#contentWrapper .tab{
 position: relative;
 padding-bottom: 2px;
 font-weight: normal;
 top: 3px;
 background: #f5f6f8;
 color: #000;
 text-decoration: none;
}

#contentWrapper .tabSelected{
 border: 0;
 top: 1px;
 padding-bottom: 4px !important;
 background: #fff;
 font-weight: bold;
 cursor: default;
}

#sidebarTabs .tabContents li.listTitle,#sidebarTabs .tabContents li.listTitle:hover{
 padding: 0 0 0 .5em;
 margin: 0;
 background: transparent;
}

#sidebarTabs .tabContents li.listLink{
 margin-left: 1em; 
}

#sidebarTabs .sidebarBlock li{
 list-style: none;
 margin-left: 1em;
 padding: 1px 0 1px 1.5em;
 background: transparent url('rinbulletOver.gif') no-repeat left center;
}

#sidebarTabs .sidebarBlock li:hover{
 background: transparent url('rinbullet.gif') no-repeat left center;
}

#contentWrapper .tabContents a.tiddlyLink,#contentWrapper .tabContents a.button{
 display: block;
 color: #005d93;
 border: 0;
}

#contentWrapper .tabContents a.tiddlyLink:hover,#contentWrapper .tabContents a.button:hover{
 color: #900;
 background: #f0f0f0;
 text-decoration: none;
}

#rinSidebar ul,
#rinSidebar li{
 list-style: none;
 padding: 0;
 margin: 0;
}

#rinSidebar li a{
 display: block;
 margin: 0 0 0 .5em;
 padding: 0 0 0 1.5em;
 background: transparent url('rinbullet.gif') no-repeat 5px -22px;
}

#rinSidebar li a:hover,
#rinSidebar #sidebarTabs li a:hover{
 background: transparent url('rinbullet.gif') no-repeat 5px 0;
 text-decoration: underline;
}

#rinSidebar #sidebarTabs li{
 margin: 0;
 padding: 0;
}

/*}}}*/
/***
!Message area styles /% =========================================================== %/
***/
/*{{{*/
#messageArea{
 background: #cdced2 url('ringradient.jpg') repeat-x left top;
 color: #000;
 position: absolute;
 top: 135px;
 right: 10px;
}

#messageArea a:link{
 color: #000;
}

#messageArea a:hover{
 text-decoration: none;
}
/*}}}*/
/***
!Display styles /% =========================================================== %/
***/
/*{{{*/
#bodyWrapper{
 border: 1px solid #d5d7db;
 border-width: 15px 1px 3px 1px;
 margin: 10px 0;
 background: #f5f6f7;
}



#displayArea{
 margin: 0 0 0 20em;
}

#contentFooter{
 clear: both;
 background: #d5d7db;
 text-align: center;
}

#contentFooter p{
 margin: 0;
}

.tiddler{
 background: #fff;
 margin: 10px 0;
}

.tiddler .toolbar a.button,.tiddler .footer a.button,.tiddler .editorFooter a.button{
 padding: 2px 5px;
 color: #19729e;
 text-decoration: none;
}

.tiddler .toolbar a.button:hover,.tiddler .footer a.button:hover,.tiddler .editorFooter a.button:hover{
 background: #97ced5;
 color: #19729e;
}

.title{
 font-size: 16px;
}

.tagClear{
 clear: none;
}

.viewer h1,
.viewer h2,
.viewer h3,
.viewer h4,
.viewer h5,
.viewer h6{
 background: transparent;
}

.viewer h1{
 border-bottom: 1px dotted #97ced5;
}

.viewer th,
.viewer thead td{
 background: #2b7ea6
}

#popup{
 color: #000;
 background: #d5d7db;
}

#popup hr{
 color: #999;
 border-top: 1px solid #999;
 width: 96%;
}

#popup a{
 display: block;
 color: #005d93;
}

#popup a:hover{
 color: #900;
 background: #f0f0f0;
 text-decoration: none;
 }
/*}}}*/
C 22.6,56.4,112.3,167.6,330.2,641.8,936.2,1214 uM
N 6.8,17,34,50,99,193,281,364 uM
Testing Warp and Gabbard samples for storage with ~HgCl$_2$ in SMARTBuoy sample bags. Collected during AlertOct2010. 

Method:

Sample volume 8ml. Stock TN standard: TNTCMixedstock1. Std add. volumes: 0, 15,30,45,60,150,300 uL.

~CRMs: LCW10.09, DSR05.10

Instrument: SkalarFormacs
/***
|Name|TableOfContentsPlugin|
|Source|http://www.TiddlyTools.com/#TableOfContentsPlugin|
|Documentation|http://www.TiddlyTools.com/#TableOfContentsPluginInfo|
|Version|2.4.3|
|Author|Eric Shulman|
|License|http://www.TiddlyTools.com/#LegalStatements|
|~CoreVersion|2.1|
|Type|plugin|
|Description|replace the standard tabbed contents list with a scrolling listbox|
When there are many tiddlers in a document, the standard 'tabbed list of tiddlers' in the right-hand sidebar can become very long, occupying a lot of page space and requiring a lot scrolling in order to locate and select a tiddler.  The TableOfContentsPlugin addresses this problem by replacing the standard tabbed list display with a single listbox/droplist control that uses a very small amount of page space, regardless of the number of tiddlers in the document.
!!!!!Documentation
>see [[TableOfContentsPluginInfo]]
!!!!!Configuration
<<option chkTOCShow>> display table of contents listbox
<<option chkTOCIncludeHidden>> include tiddlers tagged with <<tag excludeLists>> in listbox
listbox shows <<option txtTOCListSize>> lines, sorted by <<option txtTOCSortBy>>
!!!!!Revisions
<<<
2008.04.09 [2.4.3] restored config.options.chkTOCShow and onClickTOCMenu() handler
|please see [[TableOfContentsPluginInfo]] for additional revision details|
2005.06.13 [1.0.0] Initial Release (as adaptation - predates TiddlyWiki plugin architecture!!)
<<<
!!!!!Code
***/
//{{{
version.extensions.TableOfContentsPlugin= {major: 2, minor: 4, revision: 3, date: new Date(2008,4,9)};
//}}}

// // 1.2.x compatibility
//{{{
if (!window.story) window.story=window;
if (!store.getTiddler) store.getTiddler=function(title){return store.tiddlers[title]}
if (!store.addTiddler) store.addTiddler=function(tiddler){store.tiddlers[tiddler.title]=tiddler}
if (!store.deleteTiddler) store.deleteTiddler=function(title){delete store.tiddlers[title]}
//}}}

//{{{
// define defaults for cookie-based option values
if (config.options.txtTOCSortBy==undefined)	config.options.txtTOCSortBy="modified";
if (config.options.txtTOCListSize==undefined)	config.options.txtTOCListSize=19;
if (config.options.chkTOCShow==undefined)	config.options.chkTOCShow=true;
if (config.options.chkTOCIncludeHidden==undefined)	config.options.chkTOCIncludeHidden=false;

// define macro "tableOfContents" to render controls
config.macros.tableOfContents = { label: "contents" };
config.macros.tableOfContents.cmdMax=8; // index of maximum command item

config.macros.tableOfContents.css = '\
.TOC { padding:0.5em 1em 0.5em 1em; }\
.TOC a { padding:0em 0.25em 0em 0.25em; color:inherit; }\
.TOCList { width: 100%; font-size:8pt; margin:0em; }\
';

config.macros.tableOfContents.html = '\
<div style="text-align:right">\
	<span style="float:left">\
	<a href="JavaScript:;" id="TOCMenu" style="padding: 0em;"\
		onclick="onClickTOCMenu(this)" title="show/hide table of contents">%label%</a>\
	</span>\
	<a href="JavaScript:;" id="TOCSmaller" style="display:inline"\
		onclick="resizeTOC(this)" title="reduce list size">&#150;</a>\
	<a href="JavaScript:;" id="TOCLarger"style="display:inline"\
		onclick="resizeTOC(this)" title="increase list size">+</a>\
	<a href="JavaScript:;" id="TOCMaximize"style="display:inline"\
		onclick="resizeTOC(this)" title="maximize/restore list size">=</a>\
</div>\
';

config.macros.tableOfContents.handler = function(place,macroName,params) { 
	var parsedParams = new Array();
	parsedParams['label']=this.label;
	parsedParams['inline']=false;
	while (params.length>0) {
		if (params[0]=="label:none") parsedParams['label']="";
		else if (params[0].substr(0,6)=="label:") parsedParams['label']=params[0].substr(6);
		if (params[0].substr(0,7)=="prompt:") parsedParams['prompt']=params[0].substr(7);
		if (params[0].substr(0,8)=="padding:")parsedParams['padding']=params[0].substr(8);
		if (params[0].substr(0,7)=="margin:") parsedParams['margin']=params[0].substr(7);
		if (params[0].substr(0,5)=="sort:")   parsedParams['sortby']=params[0].substr(5);
		if (params[0].substr(0,5)=="date:")   parsedParams['date']=params[0].substr(5);
		if ((params[0]=="size:auto")||(params[0]=="size:0")) parsedParams['autosize']=true;
		else if (params[0] && (params[0].substr(0,5)=="size:")) parsedParams['requestedSize']=params[0].substr(5);
		if (params[0].substr(0,6)=="width:") parsedParams['width']=params[0].substr(6);
		if (params[0]=="hidelist") parsedParams['hidelist']=true;
		if (params[0]=="inline")   parsedParams['inline']=true;
		if (params[0]=="-title")   parsedParams['hide_title']=true;
		if (params[0]=="-date")    parsedParams['hide_date']=true;
		if (params[0]=="-author")  parsedParams['hide_author']=true;
		if (params[0]=="-creator") parsedParams['hide_creator']=true;
		if (params[0]=="-tags")    parsedParams['hide_tags']=true;
		if (params[0]=="-missing") parsedParams['hide_missing']=true;
		if (params[0]=="-orphans") parsedParams['hide_orphans']=true;
		if (params[0]=="-shadows") parsedParams['hide_shadows']=true;
		params.shift(); 
	}
	setStylesheet(config.macros.tableOfContents.css,"tableOfContents");
	var newTOC=createTiddlyElement(place,parsedParams['inline']?"span":"div",null,"TOC",null)
	if (parsedParams['margin'])	{ newTOC.style.margin=parsedParams['margin']; }
	if (parsedParams['padding'])	{ newTOC.style.padding=parsedParams['padding']; }
	if (parsedParams['label']!="") newTOC.innerHTML=config.macros.tableOfContents.html.replace(/%label%/,parsedParams['label']);
	var newTOCList=createTOCList(newTOC,parsedParams)
	refreshTOCList(newTOCList);
	store.addNotification(null,reloadTOCLists);	// reload listbox after every tiddler change
}

// IE needs explicit global scoping for functions/vars called from browser events
window.onChangeTOCList=onChangeTOCList;
window.onClickTOCList=onClickTOCList;
window.onDblClickTOCList=onDblClickTOCList;
window.reloadTOCLists=reloadTOCLists;
window.refreshTOCList=refreshTOCList;
window.onClickTOCMenu=onClickTOCMenu;
window.resizeTOC=resizeTOC;
	
function createTOCList(place,params) {
	var list = createTiddlyElement(place,"select",null,"TOCList",params['prompt'])
	list.params=params;
	list.onchange=onChangeTOCList;
	list.onclick=onClickTOCList;
	list.ondblclick=onDblClickTOCList;
	list.onkeyup=onKeyUpTOCList;
	list.style.display=config.options.chkTOCShow ? "block" : "none" ;
	list.sortBy=config.options.txtTOCSortBy;
	list.dateFormat="DD MMM YYYY";
	list.requestedSize=config.options.txtTOCListSize;
	list.expandall=false;
	list.cmdMax=config.macros.tableOfContents.cmdMax;
	if (params['hide_title'])   list.cmdMax--;
	if (params['hide_date'])    list.cmdMax--;
	if (params['hide_author'])  list.cmdMax--;
	if (params['hide_creator']) list.cmdMax--;
	if (params['hide_tags'])    list.cmdMax--;
	if (params['hide_missing']) list.cmdMax--;
	if (params['hide_orphans']) list.cmdMax--;
	if (params['hide_shadows']) list.cmdMax--;
	if (params['sortby'])       { list.sortBy=params['sortby']; list.noSortCookie=true; }
	if (params['date'])         { list.dateFormat=params['date']; }
	if (params['autosize'])     { list.autosize=true; list.noSizeCookie=true; }
	if (params['requestedSize']){ list.requestedSize=params['requestedSize']; list.noSizeCookie=true; }
	if (params['width'])        { list.style.width=params['width']; }
	if (params['hidelist'])     { list.style.display ="none" ; list.noShowCookie=true; }
	if (params['expandall'])    { list.expandall=true; }
	return list;
}

function onChangeTOCList() {
	var thisTiddler=this.options[this.selectedIndex].value;
	if ((this.size==1)&&(thisTiddler!='')&&(this.selectedIndex>this.cmdMax))
		story.displayTiddler(null,thisTiddler,1);
	refreshTOCList(this);
	return false;
}
function onClickTOCList(e) {
	if (!e) var e = window.event;
	if (this.size==1) return; // don't toggle display for droplist
	if (e.shiftKey) { this.expandall=!this.expandall; refreshTOCList(this);}
	e.cancelBubble = true; if (e.stopPropagation) e.stopPropagation();
	return true;
}
function onDblClickTOCList(e) {
	if (!e) var e = window.event;
	var thisTiddler=this.options[this.selectedIndex].value;
	if ((thisTiddler!='')&&(this.selectedIndex>this.cmdMax))
		story.displayTiddler(null,thisTiddler,1);
	e.cancelBubble = true; if (e.stopPropagation) e.stopPropagation();
	return false;
}
function onKeyUpTOCList(e) {
	if (!e) var e = window.event;
	if (e.keyCode!=13) return true;
	var thisTiddler=this.options[this.selectedIndex].value;
	if ((thisTiddler!='')&&(this.selectedIndex>this.cmdMax))
		story.displayTiddler(null,thisTiddler,1);
	e.cancelBubble = true; if (e.stopPropagation) e.stopPropagation();
	return false;
}
function reloadTOCLists() {
	var all=document.all? document.all.tags("select") : document.getElementsByTagName("select");
	for (var i=0; i<all.length; i++)
		if (all[i].className=="TOCList")
			{ all[i].selectedIndex=-1; refreshTOCList(all[i]); }
}
 
function refreshTOCList(list) {
	var selectedIndex = list.selectedIndex;
	if (selectedIndex==-1) selectedIndex=0;
	var sortBy = list.sortBy;
	var showHidden = config.options.chkTOCIncludeHidden && !(config.options.chkHttpReadOnly && readOnly);

	if (selectedIndex==0) sortBy=list.sortBy;	// "nnn tiddlers" heading - use previous sort order
	else if (selectedIndex<=list.cmdMax)sortBy=list.value;
	else { if (list.options[list.selectedIndex].value=='') expandTOC(list); return; }

	list.sortBy = sortBy; // save current sort order
	if (!list.noSortCookie) { config.options.txtTOCSortBy=sortBy; saveOptionCookie("txtTOCSortBy"); }

	// get the list of tiddlers
	var tiddlers = [];
	switch (sortBy) {
		case "missing":	tiddlers=store.getMissingLinks(); break;
		case "tags": tiddlers=store.getTags(); break;
		case "orphans":	tiddlers=store.getOrphans(); break;
		case "shadows": for (var t in config.shadowTiddlers) tiddlers.push(t); tiddlers.sort();	break;
		default: tiddlers=store.getTiddlers(sortBy=='creator'?'modifier':sortBy,showHidden?'':'excludeLists'); break;
	}

	// clear current listbox contents
	while (list.length > 0) { list.options[0] = null; }
	list.saved=null;

	// add heading and control items to list
	var i=0;
	var theHeading=tiddlers.length+' tiddlers:';
	if (sortBy=='missing') theHeading=tiddlers.length+' missing tiddlers:';
	if (sortBy=='orphans') theHeading=tiddlers.length+' orphaned tiddlers:';
	if (sortBy=='tags')    theHeading=tiddlers.length+' tags:';
	if (sortBy=='shadows') theHeading=tiddlers.length+' shadow tiddlers:';
	var indent=String.fromCharCode(160)+String.fromCharCode(160);
	var sel=">";
	list.options[i++]=new Option(theHeading,'');
	function headerOpt(txt,val) { return new Option(((sortBy==val)?sel:indent)+' ['+txt+']',val); }
	if (!list.params['hide_title'])   list.options[i++]=headerOpt('by title','title');
	if (!list.params['hide_date'])    list.options[i++]=headerOpt('by date','modified');
	if (!list.params['hide_author'])  list.options[i++]=headerOpt('by author','modifier');
	if (!list.params['hide_creator']) list.options[i++]=headerOpt('by creator','creator');
	if (!list.params['hide_tags'])    list.options[i++]=headerOpt('by tags','tags');
	if (!list.params['hide_missing']) list.options[i++]=headerOpt('missing','missing');
	if (!list.params['hide_orphans']) list.options[i++]=headerOpt('orphans','orphans');
	if (!list.params['hide_shadows']) list.options[i++]=headerOpt('shadows','shadows');
	// output the tiddler list
	switch(sortBy) {
		case "title":
			for (var t = 0; t < tiddlers.length; t++)
				list.options[i++] = new Option(tiddlers[t].title,tiddlers[t].title);
			break;
		case "modified":
		case "modifier":
		case "creator":
			if (sortBy=="modified") tiddlers.reverse(); // show newest first
			if (sortBy=="creator") { // sort by custom field with fallback value
				tiddlers.sort(function (a,b) {
					var v1=a.fields.creator||a.modifier;
					var v2=b.fields.creator||b.modifier;
					return (v1==v2)?0:(v1>v2?1:-1);
				});
			}
			var lastSection = "";
			for (var t = 0; t < tiddlers.length; t++){
				var tiddler = tiddlers[t];
				var theSection = "";
				var m=tiddler.modified;
				if (sortBy=="modified") theSection=m.getFullYear()+'.'+(m.getMonth()+1)+'.'+m.getDate();
				if (sortBy=="modifier") theSection = tiddler.modifier;
				if (sortBy=="creator") theSection=tiddler.fields['creator']||tiddler.modifier;
				if (theSection != lastSection) {
					lastSection = theSection;
					if (sortBy=="modified") theSection = m.formatString(list.dateFormat);
					list.options[i++] = new Option('+ '+theSection,"");
				}
				list.options[i++] = new Option(indent+indent+tiddler.title,tiddler.title);
			}
			expandTOC(list);
			break;
		case "tags":
			// tagged tiddlers, by tag
			var tagcount=0;
			var lastTag = null;
			for (var t = 0; t < tiddlers.length; t++) {  // actually a list of tags, not tiddlers... 
				var theTag = tiddlers[t][0]; var tid=store.getTiddler(theTag);
				if (tid && tid.isTagged('excludeLists')) continue; // skip excluded tags
				var temp = store.getTaggedTiddlers(theTag);
				var tagged=[]; for (var q=0; q<temp.length; q++) // hide excluded tiddlers
					if (!temp[q].isTagged('excludeLists')) tagged.push(temp[q]); 
				if (tagged.length) { tagcount++;
					list.options[i++]=new Option('+ '+theTag+" ("+tagged.length+")","");
					for(var r=0; r<tagged.length; r++)
						list.options[i++]=
							new Option(indent+indent+tagged[r].title,tagged[r].title);
				}
			}
			// count untagged tiddlers
			var temp = store.getTiddlers("title");
			var c=0; for (var r=0; r<temp.length;r++) if (!temp[r].tags.length) c++;
			// create 'pseudo-tag' listing untagged tiddlers (if any)
			if (c>0) {
				list.options[i++] = new Option("+ untagged ("+c+")","");
				for (var r=0; r<temp.length;r++) if (!temp[r].tags.length)
					list.options[i++] = new
						Option(indent+indent+temp[r].title,temp[r].title);
			}
			list.options[0].text=tagcount+' tags:';
			expandTOC(list);
			break;
		case "missing": case "orphans": case "shadows":
			for (var t = 0; t < tiddlers.length; t++)
				list.options[i++] = new Option(tiddlers[t],tiddlers[t]);
			break;
	}
	list.selectedIndex=selectedIndex; // select current control item
	list.size = (list.autosize)?list.options.length:list.requestedSize;
}

// show/hide branch of TOCList based on current selection
function expandTOC(list) {
	var selectedIndex = list.selectedIndex;
	if (selectedIndex==-1) selectedIndex=0;
	var sortBy = list.sortBy;

	// don't collapse/expand list for alpha-sorted "flatlist" TOC contents
	// or list control items
	if ((sortBy=="title")||(sortBy=="missing")||(sortBy=="orphans")||(sortBy=="shadows")) return;
	if ((selectedIndex>0)&&(selectedIndex<=list.cmdMax)) return;

	// get current selected text/value and cache the 
	// complete list.  Then clear the current list contents
	var theText = list.options[selectedIndex].text;
	var theValue = list.options[selectedIndex].value;
	if (!list.saved) {
		list.saved=new Array();
		for (var i=0;i<list.length;i++) list.saved[i]=list.options[i];
	}
	while (list.length > 0) { list.options[0] = null; }

	// put back heading items until item text matches current selected heading
	var i=0;
	for (var t=0; t<list.saved.length; t++) {
		var opt=list.saved[t];
		if (list.expandall||(opt.value=='')||(i<=list.cmdMax)) list.options[i++] = opt;
		if (opt.text==theText) break;
	}
	selectedIndex=i-1;	// this is the NEW index of the current selected heading
	// put back items with value!='' until value==''
	for ( t++; t<list.saved.length; t++) {
		var opt=list.saved[t];
		if (list.expandall||opt.value!='') list.options[i++] = opt;
		if (opt.value=='') break;
	}
	// put back remaining items with value==''
	for ( ; t<list.saved.length; t++) {
		var opt=list.saved[t];
		if (list.expandall||opt.value=='') list.options[i++] = opt;
	}
	list.selectedIndex = selectedIndex;
	list.size = (list.autosize)?list.options.length:list.requestedSize;
}

// these functions process clicks on the 'control links' that are displayed above the listbox
function getTOCListFromButton(which) {
	var list = null;
	switch (which.id) {
		case 'TOCMenu':
			var theSiblings = which.parentNode.parentNode.parentNode.childNodes;
			var thePlace=which.parentNode.parentNode.parentNode.parentNode.parentNode.id;
			break;
		case 'TOCSmaller': case 'TOCLarger': case 'TOCMaximize':
			var theSiblings = which.parentNode.parentNode.childNodes;
			var thePlace=which.parentNode.parentNode.parentNode.parentNode.id;
			break;
	}
	for (var k=0; k<theSiblings.length; k++)
		if (theSiblings[k].className=="TOCList") { list=theSiblings[k]; break; }
	return list;
}
function onClickTOCMenu(which) {
	var list=getTOCListFromButton(which); if (!list) return;
	var opening = list.style.display=="none";
	if(config.options.chkAnimate) anim.startAnimating(new Slider(list,opening,false,"none"));
	else list.style.display = opening ? "block" : "none" ;
	if (!list.noShowCookie) { config.options.chkTOCShow = opening; saveOptionCookie("chkTOCShow"); }
	return(false);
}
function resizeTOC(which) {
	var list=getTOCListFromButton(which); if (!list) return;
	var size = list.size;
	if (list.style.display=="none")	// make sure list is visible
		if(config.options.chkAnimate) anim.startAnimating(new Slider(list,true,false,"none"));
		else list.style.display = "block" ;
	switch (which.id) {
		case 'TOCSmaller':	// decrease current listbox size
			if (list.autosize) { list.autosize=false; size=config.options.txtTOCListSize; }
			if (size==1)	break;
			size -= 1;	// shrink by one line
			list.requestedSize = list.size = size;
			break;
		case 'TOCLarger':	// increase current listbox size
			if (list.autosize) { list.autosize=false; size=config.options.txtTOCListSize; }
			if (size>=list.options.length)	break;
			size += 1;	// grow by one line
			list.requestedSize = list.size = size;
			break;
		case 'TOCMaximize':	// toggle autosize
			list.autosize  = (list.size!=list.options.length);
			list.size = (list.autosize)?list.options.length:list.requestedSize;
			break;
	}
	if (!list.noSizeCookie && !list.autosize)
		{ config.options.txtTOCListSize=size; saveOptionCookie("txtTOCListSize"); }
}
//}}}
|Name|TableOfContentsPluginInfo|
|Source|http://www.TiddlyTools.com/#TableOfContentsPlugin|
|Documentation|http://www.TiddlyTools.com/#TableOfContentsPluginInfo|
|Version|2.4.3|
|Author|Eric Shulman|
|License|http://www.TiddlyTools.com/#LegalStatements|
|~CoreVersion|2.1|
|Type|documentation|
|Description|documentation for TableOfContentsPlugin|
When there are many tiddlers in a document, the standard 'tabbed list of tiddlers' in the right-hand sidebar can become very long, occupying a lot of page space and requiring a lot scrolling in order to locate and select a tiddler.  This plugin replaces the standard tabs with a listbox/droplist control that uses a very small amount of page space, regardless of the number of tiddlers in the document.
!!!!!Usage
<<<
{{{
<<tableOfContents label:... sort:... date:... size:...
	width:... padding:... margin:... prompt:... inline hidelist
	-title -date -author -creator -tags -missing -orphans -shadows
}}}
*''label:text'' (default="contents")<br>the text that appears above the listbox.
*''sort:fieldtype''<br>sets the initial display order for items in the listbox.  'fieldtype' is one of: ''title, modified, modifier, creator, tags, missing, orphans,'' or ''shadows''.
*''date:format''<br>format for dates in listbox display, using TiddlyWiki date formatting (e.g. "DDD, MMM DD YYY")
*''size:nnn'' (default=1)<br>the initial number of lines to display in the listbox.  If size=1, a droplist is created, otherwise a fixed-size listbox is created.  You can use "size:0" or "size:auto" to display a varible-height listbox that automatically adjusts to fit the current list contents without scrolling.
*''width:...'' (default=100%)<br>the width of the listbox/droplist, using CSS units cm, px, em, or %.  You can also use a ".TOCList" custom CSS class definition to override the built-in CSS declarations for the listbox.
*''padding:...''<br>sets listbox CSS padding style
*''margin:...''<br>sets listbox CSS margin style
*''prompt:...''<br>sets non-selectable prompt text that is displayed as the first line of the listbox //(note: this feature is not supported by the listbox control on all browsers)//.  Let's you include a short text message (such as "select a tiddler"), even when displaying a compact single-line droplist.
*''inline''<br>By default, the listbox is rendered inside a {{{<div>}}} element.  This keyword causes the plugin to use a {{{<span>}}} instead, allowing for more flexible 'inline' placement when embedded within other content.
*''hidelist''<br>when present, only the listbox label and size controls will be appear when first displayed.  Clicking the label toggles the listbox display.
*''-title, -date, -author, -creator, -tags, -missing, -orphans, -shadows''<br>Omits the indicated list command item and corresponding listbox content.  
Select (or double-click) a title from the listbox to open a tiddler, or select a 'command' items to set the order and type of tiddlers that are shown in the list:
*''[by title]''<br>displays all tiddlers in the document in alphanumeric order
*''[by date/author/creator/tags]''<br>displays indented sections, sorted accordingly, with headings (indicated by a '+') that can be expanded, one at a time, to view the list of tiddlers in that section. You can also ''shift-click'' on a section heading expand/collapse all sections at once.
*''[missing]''<br>displays tiddlers that have been referenced within the document but do not yet exist.
*''[orphans]''<br>displays tiddlers that do exist in the document but have not been referenced by a link from anywhere else within the document.
*''[shadows]''<br>displays special default/fallback tiddlers that are used by TiddlyWiki to configure built-in features and add-on macros/extensions.
The ''size of the listbox can be adjusted'' so you can view more (or less) tiddler titles at one time.  Select ''[-]'' to reduce the size by one line, ''[+]'' to increase the size by one line, or ''[=]'' to autosize the list to fit the current contents (toggles on/off). //Note: If the listbox is reduced to a single line, it displayed as a droplist instead of a fixed-sized listbox.//  You can ''show/hide the entire listbox'' by selecting the "contents" label that appears above the listbox.
<<<
!!!!!Configuration
<<option chkTOCShow>> display table of contents listbox
<<option chkTOCIncludeHidden>> include tiddlers tagged with <<tag excludeLists>> in listbox
listbox shows <<option txtTOCListSize>> lines, sorted by <<option txtTOCSortBy>>
!!!!!Parameters
<<<
<<<
!!!!!Examples
<<<
{{{<<tableOfContents "label:all tiddlers" sort:title width:40% size:1>>}}}
<<tableOfContents "label:all tiddlers" sort:title width:40% size:1>>
{{{<<tableOfContents "label:by date" sort:modified size:1 width:40%>>}}}
<<tableOfContents "label:by date" sort:modified size:1 width:40%>>
{{{<<tableOfContents "label:tagged tiddlers" sort:tags size:1 width:40%>>}}}
<<tableOfContents "label:tagged tiddlers" sort:tags size:1 width:40%>>
{{{<<tableOfContents "label:shadow tiddlers" sort:shadows size:1 width:40%>>}}}
<<tableOfContents "label:shadow tiddlers" sort:shadows size:1 width:40%>>
<<<
!!!!!Revisions
<<<
2008.04.09 2.4.3 restored config.options.chkTOCShow and onClickTOCMenu() handler
2008.04.07 2.4.2 added "Configuration" section and removed config.options.chkTOCShow and onClickTOCMenu() handler
2008.01.08 [*.*.*] plugin size reduction: documentation moved to ...Info tiddler
2007.12.25 2.4.1 code cleanup and performance improvements
2007.12.25 2.4.0 renamed 'system' section to 'shadows' (and no longer list plugins, etc. in that section).  Also, added 'by creator' sort order (with fallback to 'modifier' if 'creator' custom field is undefined). Thanks to RA for suggestion and code tweaks.
2007.12.04 [*.*.*] update for TW2.3.0: replaced deprecated core functions, regexps, and macros
2007.03.22 2.3.2 in refreshTOCLists(), when sorting by date, use convertToLocalYYYYMMDDHHMM() instead of formatString() to compare dates for 'section headings' and only use formatString() when actually generating the section heading date display.  Improves performance significantly for date sorted listbox, especially in documents with hundreds of tiddlers.  Suggestion by AndreasHoefler.
2007.03.21 2.3.1 in refreshTOCLists(), only get list of 'select' elements, instead of scanning through all elements (saves significant time during refresh events.  Suggestion by AndreasHoefler.
2006.11.27 2.3.0 added ability to omit sections from listbox via macro params (e.g., "-date -tags", etc.).  Based on request from DavidWinfield.
2006.05.21 2.2.7 added onkeyup handling for enter key (=view selected tiddler, equivalent to double-click)
2006.02.14 2.2.6 FF1501 fix: add 'var r' and 'var k' to unintended global variable declarations in refreshTOCList() and getTOCListFromButton().  Thanks for report from AndreasHoefler.
2006.02.04 2.2.5 add 'var' to unintended global variable declarations to avoid FireFox 1.5.0.1 crash bug when assigning to globals
2005.12.21 2.2.2 in onClickTOCList() and onDblClickTOCList(), prevent mouse events from 'bubbling' up to other handlers
2005.10.30 2.2.1 in refreshTOCList(), fixed calculation of "showHidden" to check for 'readOnly' (i.e., "via HTTP") flag.  Based on a report from LyallPearce
2005.10.30 2.2.0 hide tiddlers tagged with 'excludeLists' (with option to override, i.e., "include hidden tiddlers")
2005.10.09 2.1.0 combined documentation and code in a single tiddler
added click toggle for expand-all vs. show-one-branch
2005.08.07 2.0.0 major re-write to not use static ID values for listbox controls, so that multiple macro instances can exist without corrupting each other or the DOM.  Moved HTML and CSS definitions into plugin code instead of using separate tiddlers.  Added macro parameters for label, sort, date, size, width, hidelist and showtabs
2005.08.03 1.0.3 added "showtabs" optional parameter
2005.07.27 1.0.2 core update 1.2.29: custom overlayStyleSheet() replaced with new core setStylesheet().  Added show/hide toggle (click on 'contents' link)
2005.07.23 1.0.1 added parameter checks and corrected addNotification() usage
2005.07.20 1.0.0 Initial Release
<<<
<<cloud tag tag tag>>
/***
|Name|TagCloudPlugin|
|Source|http://www.TiddlyTools.com/#TagCloudPlugin|
|Version|1.7.0|
|Author|Eric Shulman|
|Original Author|Clint Checketts|
|License|http://www.TiddlyTools.com/#LegalStatements|
|~CoreVersion|2.1|
|Type|plugin|
|Description|present a 'cloud' of tags (or links) using proportional font display|
!Usage
<<<
{{{
<<cloud type action:... limit:... tag tag tag ...>>
<<cloud type action:... limit:... +TiddlerName>>
<<cloud type action:... limit:... -TiddlerName>>
<<cloud type action:... limit:... =tagvalue>>
}}}
where:
* //type// is a keyword, one of:
** ''tags'' (default) - displays a cloud of tags, based on frequency of use
** ''links'' - displays a cloud of tiddlers, based on number of links //from// each tiddler
** ''references'' - displays a cloud of tiddlers, based on number of links //to// each tiddler
* ''action:popup'' (default) - clicking a cloud item shows a popup with links to related tiddlers<br>//or//<br> ''action:goto'' - clicking a cloud item immediately opens the tiddler corresponding to that item
* ''limit:N'' (optional) - restricts the cloud display to only show the N most popular tags/links
* ''tag tag tag...'' (or ''title title title'' if ''links''/''references'' is used)<br>shows all tags/links in the document //except// for those listed as macro parameters
* ''+TiddlerName''<br>show only tags/links read from a space-separated, bracketed list stored in a separate tiddler.
* ''-TiddlerName''<br>show all tags/links //except// those read from a space-separated, bracketed list stored in a separate tiddler.
* ''=tagvalue'' (//only if type=''tags''//)<br>shows only tags that are themselves tagged with the indicated tag value (i.e., ~TagglyTagging usage)
//note: for backward-compatibility, you can also use the macro {{{<<tagCloud ...>>}}} in place of {{{<<cloud ...>>}}}//
<<<
!Examples
<<<
//all tags excluding<<tag systemConfig>>, <<tag excludeMissing>> and <<tag script>>//
{{{<<cloud systemConfig excludeMissing script>>}}}
{{groupbox{<<cloud systemConfig excludeMissing script>>}}}
//top 10 tags excluding<<tag systemConfig>>, <<tag excludeMissing>> and <<tag script>>//
{{{<<cloud limit:10 systemConfig excludeMissing script>>}}}
{{groupbox{<<cloud limit:10 systemConfig excludeMissing script>>}}}
//tags listed in// [[FavoriteTags]]
{{{<<cloud +FavoriteTags>>}}}
{{groupbox{<<cloud +FavoriteTags>>}}}
//tags NOT listed in// [[FavoriteTags]]
{{{<<cloud -FavoriteTags>>}}}
{{groupbox{<<cloud -FavoriteTags>>}}}
//links to tiddlers tagged with 'package'//
{{{<<cloud action:goto =package>>}}}
{{groupbox{<<cloud action:goto =package>>}}}
//top 20 most referenced tiddlers//
{{{<<cloud references limit:20>>}}}
{{groupbox{<<cloud references limit:20>>}}}
//top 20 tiddlers that contain the most links//
{{{<<cloud links limit:20>>}}}
{{groupbox{<<cloud links limit:20>>}}}
<<<
!Revisions
<<<
2009.07.17 [1.7.0] added {{{-TiddlerName}}} parameter to exclude tags that are listed in the indicated tiddler
2009.02.26 [1.6.0] added {{{action:...}}} parameter to apply popup vs. goto action when clicking cloud items
2009.02.05 [1.5.0] added ability to show links or back-links (references) instead of tags and renamed macro to {{{<<cloud>>}}} to reflect more generalized usage.
2008.12.16 [1.4.2] corrected group calculation to prevent 'group=0' error
2008.12.16 [1.4.1] revised tag filtering so excluded tags don't affect calculations
2008.12.15 [1.4.0] added {{{limit:...}}} parameter to restrict the number of tags displayed to the top N most popular
2008.11.15 [1.3.0] added {{{+TiddlerName}}} parameter to include only tags that are listed in the indicated tiddler
2008.09.05 [1.2.0] added '=tagname' parameter to include only tags that are themselves tagged with the specified value (i.e., ~TagglyTagging usage)
2008.07.03 [1.1.0] added 'segments' property to macro object.  Extensive code cleanup
<<<
!Code
***/
//{{{
version.extensions.TagCloudPlugin= {major: 1, minor: 7 , revision: 0, date: new Date(2009,7,17)};
//Originally created by Clint Checketts, contributions by Jonny Leroy and Eric Shulman
//Currently maintained and enhanced by Eric Shulman
//}}}
//{{{
config.macros.cloud = {
	tagstip: "%1 tiddlers tagged with '%0'",
	refslabel: " (%0 references)",
	refstip: "%1 tiddlers have links to '%0'",
	linkslabel: " (%0 links)",
	linkstip: "'%0' has links to %1 other tiddlers",
	groups: 9,
	init: function() {
		config.macros.tagCloud=config.macros.cloud; // for backward-compatibility
		config.shadowTiddlers.TagCloud='<<cloud>>';
		config.shadowTiddlers.StyleSheetTagCloud=
			'/*{{{*/\n'
			+'.tagCloud span {line-height: 3.5em; margin:3px;}\n'
			+'.tagCloud1{font-size: 80%;}\n'
			+'.tagCloud2{font-size: 100%;}\n'
			+'.tagCloud3{font-size: 120%;}\n'
			+'.tagCloud4{font-size: 140%;}\n'
			+'.tagCloud5{font-size: 160%;}\n'
			+'.tagCloud6{font-size: 180%;}\n'
			+'.tagCloud7{font-size: 200%;}\n'
			+'.tagCloud8{font-size: 220%;}\n'
			+'.tagCloud9{font-size: 240%;}\n'
			+'/*}}}*/\n';
		setStylesheet(store.getTiddlerText('StyleSheetTagCloud'),'tagCloudsStyles');
	},
	getLinks: function(tiddler) { // get list of links to existing tiddlers and shadows
		if (!tiddler.linksUpdated) tiddler.changed();
		var list=[]; for (var i=0; i<tiddler.links.length; i++) {
			var title=tiddler.links[i];
			if (store.isShadowTiddler(title)||store.tiddlerExists(title))
				list.push(title);
		}
		return list;
	},
	handler: function(place,macroName,params) {
		// unpack params
		var inc=[]; var ex=[]; var limit=0; var action='popup';
		var links=(params[0]&&params[0].toLowerCase()=='links'); if (links) params.shift();
		var refs=(params[0]&&params[0].toLowerCase()=='references'); if (refs) params.shift();
		if (params[0]&&params[0].substr(0,7).toLowerCase()=='action:')
			action=params.shift().substr(7).toLowerCase();
		if (params[0]&&params[0].substr(0,6).toLowerCase()=='limit:')
			limit=parseInt(params.shift().substr(6));
		while (params.length) {
			if (params[0].substr(0,1)=='+') { // read taglist from tiddler
				inc=inc.concat(store.getTiddlerText(params[0].substr(1),'').readBracketedList());
			} else if (params[0].substr(0,1)=='-') { // exclude taglist from tiddler
				ex=ex.concat(store.getTiddlerText(params[0].substr(1),'').readBracketedList());
			} else if (params[0].substr(0,1)=='=') { // get tag list using tagged tags
				var tagged=store.getTaggedTiddlers(params[0].substr(1));
				for (var t=0; t<tagged.length; t++) inc.push(tagged[t].title);
			} else ex.push(params[0]); // exclude params
			params.shift();
		}
		// get all items, include/exclude specific items
		var items=[];
		var list=(links||refs)?store.getTiddlers('title','excludeLists'):store.getTags();
		for (var t=0; t<list.length; t++) {
			var title=(links||refs)?list[t].title:list[t][0];
			if (links)	var count=this.getLinks(list[t]).length;
			else if (refs)	var count=store.getReferringTiddlers(title).length;
			else 		var count=list[t][1];
			if ((!inc.length||inc.contains(title))&&(!ex.length||!ex.contains(title)))
				items.push({ title:title, count:count });
		}
		if(!items.length) return;
		// sort by decending count, limit results (optional)
		items=items.sort(function(a,b){return(a.count==b.count)?0:(a.count>b.count?-1:1);});
		while (limit && items.length>limit) items.pop();
		// find min/max and group size
		var most=items[0].count;
		var least=items[items.length-1].count;
		var groupSize=(most-least+1)/this.groups;
		// sort by title and draw the cloud of items
		items=items.sort(function(a,b){return(a.title==b.title)?0:(a.title>b.title?1:-1);});
		var cloudWrapper = createTiddlyElement(place,'div',null,'tagCloud',null);
		for (var t=0; t<items.length; t++) {
			cloudWrapper.appendChild(document.createTextNode(' '));
			var group=Math.ceil((items[t].count-least)/groupSize)||1;
			var className='tagCloudtag tagCloud'+group;
			var tip=refs?this.refstip:links?this.linkstip:this.tagstip;
			tip=tip.format([items[t].title,items[t].count]);
			if (action=='goto') { // TAG/LINK/REFERENCES GOTO
				var btn=createTiddlyLink(cloudWrapper,items[t].title,true,className);
				btn.title=tip;
				btn.style.fontWeight='normal';
			} else if (!links&&!refs) { // TAG POPUP
				var btn=createTiddlyButton(cloudWrapper,items[t].title,tip,onClickTag,className);
				btn.setAttribute('tag',items[t].title);
			} else { // LINK/REFERENCES POPUP
				var btn=createTiddlyButton(cloudWrapper,items[t].title,tip,
					function(ev) { var e=ev||window.event; var cmt=config.macros.cloud;
						var popup = Popup.create(this);
						var title = this.getAttribute('tiddler');
						var count = this.getAttribute('count');
						var refs  = this.getAttribute('refs')=='T';
						var links = this.getAttribute('links')=='T';
						var label = (refs?cmt.refslabel:cmt.linkslabel).format([count]);
						createTiddlyLink(popup,title,true);
						createTiddlyText(popup,label);
						createTiddlyElement(popup,'hr');
						if (refs) {
							popup.setAttribute('tiddler',title);
							config.commands.references.handlePopup(popup,title);
						}
						if (links) {
							var tiddler = store.fetchTiddler(title);
							var links=config.macros.cloud.getLinks(tiddler);
							for(var i=0;i<links.length;i++)
								createTiddlyLink(createTiddlyElement(popup,'li'),
									links[i],true);
						}
						Popup.show();
						e.cancelBubble=true; if(e.stopPropagation) e.stopPropagation();
						return false;
					}, className);
				btn.setAttribute('tiddler',items[t].title);
				btn.setAttribute('count',items[t].count);
				btn.setAttribute('refs',refs?'T':'F');
				btn.setAttribute('links',links?'T':'F');
				btn.title=tip;
			}
		}
	}
};
//}}}
<<cloud -OmitFromTagCloud>>
10000 ug-N/L NH4Cl from research technicians to test [[NH4Cl50u.001]]

3.5ml in 50ml -> 49.946 uM
/***
|Name|TiddlerIconsPlugin|
|Source|http://www.TiddlyTools.com/#TiddlerIconsPlugin|
|Version|2.1.0|
|Author|Eric Shulman|
|License|http://www.TiddlyTools.com/#LegalStatements|
|~CoreVersion|2.1|
|Type|plugin|
|Description|display icons next to tiddler title, based on tiddler's attributes (tags, fields, slices, etc)|
!!!!!Usage
<<<
{{{<<tiddlerIcons>>}}} - shows icons for the current tiddler
or
{{{<<tiddlerIcons =TiddlerName>>}}} - shows icons for the specified tiddler
or
{{{<<tiddlerIcons iconID>>}}} - shows a specific icon
<<<
!!!!!Examples
<<<
{{{
icons for current tiddler: <<tiddlerIcons>>
}}}
icons for current tiddler: <<tiddlerIcons>>
{{{
icons for [[Welcome]] tiddler: <<tiddlerIcons =Welcome>>
}}}
icons for [[Welcome]] tiddler: <<tiddlerIcons =Welcome>>
{{{
All icons:
<<tiddlerIcons recent>> <<tiddlerIcons changed>> <<tiddlerIcons unsaved>> <<tiddlerIcons Trash>>
<<tiddlerIcons tag>> <<tiddlerIcons core>> <<tiddlerIcons systemConfig>> <<tiddlerIcons CSS>>
<<tiddlerIcons html>> <<tiddlerIcons template>> <<tiddlerIcons script>> <<tiddlerIcons attachment>>
<<tiddlerIcons settings>> <<tiddlerIcons pluginInfo>> <<tiddlerIcons faq>> <<tiddlerIcons task>>
}}}
All icons:
<<tiddlerIcons recent>> <<tiddlerIcons changed>> <<tiddlerIcons unsaved>> <<tiddlerIcons Trash>> <<tiddlerIcons tag>> <<tiddlerIcons core>> <<tiddlerIcons systemConfig>> <<tiddlerIcons CSS>> <<tiddlerIcons html>> <<tiddlerIcons template>> <<tiddlerIcons script>> <<tiddlerIcons attachment>> <<tiddlerIcons settings>> <<tiddlerIcons pluginInfo>> <<tiddlerIcons faq>> <<tiddlerIcons task>>
<<<
!!!!!Configuration
<<<
You can add extra icons definitions based on matching tag values.  First, import or create a tiddler called [[TiddlerIconsPluginConfig]] and tag it with<<tag systemConfig>>.  Then, in that tiddler, use the following code format to //merge// your additional icon definitions into the default {{{config.macros.tiddlerIcons.map}}} object.
{{{
merge(config.macros.tiddlerIcons.map,{
	tagvalue: ["tooltip","imagefile"],
	tagvalue: ["tooltip","imagefile"],
	...
	tagvalue: ["tooltip","imagefile"]   // note: no comma after last definition
}
}}}
<<<
!!!!!Revisions
<<<
2008.10.02 [2.1.0] added "=TiddlerName" param (shows icons for specified tiddler)
2007.08.01 [2.0.0] converted from inline script
2007.05.28 [1.0.0] initial release (as inline script)
<<<
!!!!!Code
***/
//{{{
version.extensions.TiddlerIconsPlugin= {major: 2, minor: 1, revision: 0, date: new Date(2008,10,2)};
config.macros.tiddlerIcons = {
	unknown: "unknown tiddler icon: %0",
	map: {
		recent: ["this tiddler was UPDATED within the last 10 days","asterisk_yellow.png"],
		changed: ["this tiddler was UPDATED after your last visit","star.png"],
		unsaved: ["this tiddler has UNSAVED CHANGES","exclamation.png"],
		tag: ["this is a TAG tiddler","tag_blue.png"],
		html: ["this is an HTML MARKUP tiddler","html.png"]
	},
	handler: function(place,macroName,params,wikifier,paramString,tiddler) {
		var img="[img[%0|%1]]";
		var imgs=[]; // collected set of applicable images
		var p=params[0]; // abbrev

		// if icon keyword was supplied, just show one icon and exit.
		if (p&&p.substr(0,1)!="=") {
			wikify(this.map[p]?img.format(this.map[p]):this.unknown.format([p]),place);
			return;
		}

		// if TiddlerName was supplied, use that tiddler, otherwise use current tiddler
		var here=story.findContainingTiddler(place);
		if (!p && !here) return; // not in a tiddler
		var title=p?p.substr(1):here.getAttribute('tiddler');
		var tid=store.getTiddler(title); if (!tid) return; // tiddler not found

		// add 'tag' icon if this tiddler IS a tag
		var tags=store.getTags();
		for (i=0;i<tags.length;i++) if (tags[i][0]==title) imgs.push(img.format(this.map["tag"]));
		if (!tid) { wikify(imgs.join(""),place); return; }

		// add 'unsaved', 'changed', or 'recent' icon based on tiddler vs. document date
		// (uses config.options.lastSaved, updated by [[UnsavedChangesPlugin]])
		if (tid.modified > (config.options.lastSaved?config.options.lastSaved:document.lastModified))
			imgs.push(img.format(this.map["unsaved"]));
		else {
			// add 'changed' icon if tiddler has been modified since last visit
			// (uses config.lastVisit, updated by [[VisitCounterPlugin]])
			// truncate seconds from last visit timestamp for comparison with tiddler modification timestamp
			if (config.lastVisit)
				var last=new Date((new Date(config.lastVisit).getTime())-(new Date(config.lastVisit).getSeconds()*1000));
			if (tid.modified >= last)
				imgs.push(img.format(this.map["changed"]));
			else if (tid.modified >= (new Date()).getTime()-86400000*10)
				imgs.push(img.format(this.map["recent"])); // add 'recent' icon if tiddler has been modified in last 10 days
		}
		if (title.substr(0,6)=="Markup")
			imgs.push(img.format(this.map["html"]));

		// add 'type' icons based on tag(s)... see TiddlerIconsPluginConfig for icon map definitions
		// sort tags for consistent icon display order 
		var tags=[]; for (i=0;i<tid.tags.length;i++) tags.push(tid.tags[i]); tags.sort();
		for (var t=0; t<tags.length; t++)
			if (this.map[tags[t]]) imgs.push(img.format(this.map[tags[t]]));
		wikify(imgs.join(""),place);
	}
};
//}}}
/***
|Name|TiddlerIconsPluginConfig|
|Source|http://www.TiddlyTools.com/#TiddlerIconsPluginConfig|
|Version|2.0.0|
|Author|Eric Shulman|
|License|http://www.TiddlyTools.com/#LegalStatements|
|~CoreVersion|2.1|
|Type|plugin|
|Requires|TiddlerIconsPlugin|
|Description|configure additional icons for TiddlerIconsPlugin, based on containing tiddler's tags|

!!!!!Usage
<<<
This plugin configuration tiddler can be used to add extra icon definitions, based on matching tag values, using the following code format:
{{{
merge(config.macros.tiddlerIcons.map, {
	tagvalue: ["tooltip","imagefile"],
	tagvalue: ["tooltip","imagefile"],
	...
	tagvalue: ["tooltip","imagefile"]   // note: no comma after last definition
}
}}}
<<<
!!!!!Revisions
<<<
2007.08.01 [2.0.0] converted from inline script
<<<
!!!!!Code
***/
//{{{
merge(config.macros.tiddlerIcons.map, {
	Trash: ["this tiddler has been tagged as TRASH","delete.png"],
	core: ["this is a CUSTOMIZED TiddlyWiki core tiddler","application_add.png"],
	systemConfig: ["this is a PLUGIN tiddler","cog.png"],
	CSS: ["this is a CSS STYLESHEET tiddler","css.png"],
	template: ["this is a TiddlyWiki layout TEMPLATE","layout.png"],
	script: ["this is an INLINE SCRIPT tiddler","script_code.png"],
	attachment: ["this is a binary file ATTACHMENT","disk.png"],
	settings: ["this tiddler contains SETTINGS or DATA used by plugins or core features","wrench.png"],
	pluginInfo: ["this tiddler contains PLUGIN DOCUMENTATION","information.png"],
	TiddlyTools: ["this tiddler contains TIDDLYTOOLS INFORMATION","information.png"],
	faq: ["this tiddler contains a FAQ/HOW-TO article","help.png"],
	bookmark: ["this tiddler contains a BOOKMARK URL","page_link.png"],
	task: ["this is a TASK tiddler","tick.png"]
});
//}}}
|~ViewToolbar|closeTiddler closeOthers +editTiddler > fields syncing permalink references jump|
|~EditToolbar|+saveTiddler -cancelTiddler deleteTiddler|
5ml of sediment over-water from stored cores was taken and diluted 1:10 with low ammonium seawater from stn 107 surface (in situ measured at 10nM). 6 x 10ml samples were put in centrifuge tubes and calibrated by standard additions of 50uM stock standard (volumes 0, 25, 50, 75, 100, 200 uL). Also included was a sample of Stn 107 surface water with no standard added.
Before trying a full on nitrification experiment in the lab, need to test that the bateria I collected on the cruise are still active.

Took 10 ml of sample of sediment + overlying water from Tyne samples from CEND311 and diluted to 250ml in clean polycarbonate bottle. Added 0.5uM NH4Cl and took sample for OPA analysis (plus one before addition of NH4Cl and one spiked one to determine instrument response at analysis time). Took another sample (plus spiked sample) after 24 hours. 

Results:
t0
pre NH3: 86 (contaminated by drop of sediment)
with NH4: 230
spiked 455

t20: 218
spiked: 305
Helping Douglas work up his total nitrogen data from his aerosol samples which we measured a couple of weeks back we've noticed a sizeable blank from the ultra pure water in the lab - approx 4.5 uM. We're  sure it's the milliq as he was using it for sample dilution and applying a correction changes his data from gobbledook to making good sense. I assume it's organic N as I haven't heard of any problems with the autoanalyser, but then maybe we woudn't unless sample dilutions were hiding the problem. Never had a problem before though with the inorganic N so my bet is that it's organic, which we've only been able to measure at low or sub micromolar concentrations since getting the Skalar Formacs.

Not the end of the world Douglas' N rich aerosol filter extracts but a really big deal for low nutrient water measurements. Again, not seawater as I don't use ultra pure water for blanks or sample processing, or standards to any great extent (another win for standard additions...). Still, one to watch out for - I've heard tell that UPW systems can get a bit organic nitrogen happy - looks like ours has.
{{{
 
  var TiddlyLock = {}; // Create a namespace for our new function.
  TiddlyLock.displayTiddler = story.displayTiddler;
  story.displayTiddler = function(srcElement,titles,template,unused1,unused2,animate,unused3)
  {
    //if (urchinTracker) { urchinTracker('/' + titles); }
    TiddlyLock.displayTiddler.apply(this,arguments);
  }
 
}}}
<!--{{{-->
<!--{{{-->
<div class='toolbar' macro='toolbar [[ToolbarCommands::ViewToolbar]]'></div>
<div class='title' macro='view title'></div>
<div class='subtitle'><span macro='view modifier link'></span>, <span macro='view modified date'></span> (<span macro='message views.wikified.createdPrompt'></span> <span macro='view created date'></span>)</div>
<div class='tagging'><div macro='whatLinksHere "<br>linking:<br> "'></div></div>
<!--<div class='tagging' macro='tagging'></div>-->
<div class='tagged' macro='tags'></div>
<div class='viewer' macro='view text wikified'></div>
<!--<div class='disqus' macro='tiddler disqus with: {{tiddler?tiddler.title:"general"}}'></div> -->
<div class='tagClear'></div>
<!--}}}-->
<!--}}}-->
Waste from the cruise will contain the following:

Orthopthalaldehyde <0.1 g/L
Ethanol <0.5% by volume
Na2B4O7.10H20 <5 g/L
NaS <0.05 g/L
HgCl2 <0.01 g/L
Allylthiourea <10 uM
Sodium Azide <5 uM
15N-NH4 <0.1 uM


Let's assume we need to get between 1 and 10 ~Tg-C out of the ocean for each of the compounds. The figure below shows the results of back-calculation of the required seawater concentration for a range of compounds, required source strengths (s, in g-C per year) and gas phase concentrations. 

click on image to view full size
[img[http://figshare.com/figures/images/thumb/4/44/Monoterpenes.png/500px-Monoterpenes.png][http://figshare.com/figures/images/4/44/Monoterpenes.png]]

Because of the low solubility of isoprene and the monoterpenes, the gas phase concentration barely affects the result - i.e. gas phase concentration is close to zero at 1000ppt relative to sw concentration (except for the much more soluble a-terpineol, which will not be discussed further). Sensitivity analysis (not shown) also demonstrates that the results are rather robust to values of global mean T, S and winspdeed (only varying by about +/- 5% over realistic ranges of mean values). 

Ignoring gas phase concentration (fixing it at 100ppt), the table below shows concentration required for source strengths of 1, 5, and 10 ~Tg-C from each compound, and also observed marine concentrations, where available. All water phase concentrations in pM.

|!compound|!s=1 ~Tg-C|!s=5 ~Tg-C|!s=10 ~Tg-C|Observed (REF)|
|Isoprene|60|290|580|12-94 (Matsunaga et al, 2002); 10-50 (Milne et al, 1995); 4-70 (Kurihara et al, 2010) 20 probably representative (Shaw, Gantt and Meskhidze, 2010) |
|alpha-Pinene|36|170|350|5-65000!! (Button and Juttner, 1989)|

So, it looks like Isoprene might account for a flux of up to 1 Tg-C out of the ocean, and the jury's out on the monoterpenes as there is just the one study on seawater concentrations, which found average a-Pinene concentration of 65000pM in June of 1985 and 5 in June 1986. Seems a little peculiar!! 

However if the monoterpenes are the source of the SOA, then a number of them (10ish) need to be at or above the concentration of isoprene to constitute a total organic C flux of roughly 10 Tg or more to the atmosphere. Seawater measurements needed! If alpha pinene is at anything like the average of the 1985 and 1986 coastal concentrations seen by Button et al, then 500Tg-C could be coming from the oceans in the form of a-Pinene alone.  




plotting code for figure:

{{{
plot_it<-function(compound,source_strengths=c(1e12,5e12,10e12),gas_phase_concentration_range=c(1,10,100,1000)){

 x<-data.frame(gasconc<-gas_phase_concentration_range)
 leglist<-NULL
 for(s in source_strengths){
 	x[,paste("s=",as.character(s),sep="")]<-1e6*Cxsw(compound,x[,1],s,1)
	leglist<-c(leglist,paste("s=",as.character(s),sep=""))
 }
 ymax=100*(ceiling(max(x[-1])/100))
 y=seq(from=0,to=ymax,length.out=nrow(x))
 matplot(x[,1],y,type="n",xlab="gas phase concentration / ppt",ylab="water phase concentration / pM",main=compound)
 matlines(x[,1],x[2:length(x)],lty=1:(length(x)-1),col="black")
 legend("topleft",leglist,lty=seq(from=1,to=length(x)-1, by=1))
}

}}}
'Top down' (from global transport and atmospheric chemistry models based on amount of secondary organic aerosol) and 'bottom up' (estimating marine biogenic production) approaches to closing the budget for the contribution of isoprene and the monoterpenes' contribution to SOA are miles apart. Taking modelled and measured atmospheric concentrations and a required flux per unit are from the top down approach, we will be able to estimate the seawater concentration required to drive the necessary flux. If this comes out at e.g. >uM levels we can be pretty sure that the budget won't close and we need to look to other compounds for SOA. If it's nM or less then the jury's still out and we need more investigation. A really simple bit of work but hopefully useful and informative. 

So, given that we need to account for a given mass of organic compounds getting into the aerosol per year (i.e. a flux), F$_x$ (where x is the compound of interest), and there are a reasonable number of observations of gas phase concentrations of monoterpenes and isoprene, C$_{x_{(g)}}$, we can extrapolate the required average seawater concentration from the above terms, the average temperature and salinity, solubility and transfer velocity like so:

C$_{x_{(sw)}}$ = $\frac{C_{x_{(g)}}}{K_H}$ - $\frac{F}{K_w}$

Where $K_H$ and $K_w$ are the dimensionless gas/liquid transfer velocity and total transfer velocity with respect to the water side of the interface, both of which are T and S dependent (and the latter wind dependent) and can be calculated from my numerical scheme. F needs to be negative for a flux out of the ocean

Therefore we can write a simple script to calculate this for a given compound and values of F$_x$, C$_{x_{(g)}}$ and global average values of temperature, salinity and windspeed. 

{{{
source("K_calcs_Johnson_OS.R")

#SOAMass<- 1e12 #annual mass of carbon in SOA from emitted compound
#SOA_conversion_factor<- 0.1 #amount of emitted gas which ends up as SOA (0-1)


mgws<-7.6 #mean global wind speed in m/s (second product moment - assuming squared K-u relationship)
mgT<-15 #mean global ocean surface temp
mgS<-35 #mean global surface salinity		

Cxsw<-function(compound,Cxg,SOAmass=1e12,SOA_conversion_factor=0.1){
	#input gas phase concentration in ppt, get seawater concentration in uM
	
	#convert gas phase concentration to mol/m3
	Cg<-(Cxg*1e-12*101325)/(8.314472*(mgT+273.15))

	Fx<- -SOAmass/SOA_conversion_factor #required annual flux of gas out of ocean
	print(paste("For oceanic isoprene flux of Fx",Fx,"g-C per year"))
	#convert flux to moles C per year
	F<-Fx/12

	#and to moles of compound per year
	F<-F/compounds[compound,"C"]

	#and to moles per unit area per second (ocean s.a. 3.6e14m2)
	F<-F/(3.6e14*3600*24*365.25)

	Csw_moles_per_metrecubed<-(Cg/KH(compound,mgT,mgS))-(F/Kw(compound,mgT,mgws,mgS))
 
	pM<-Csw_moles_per_metrecubed*1e9
	print(paste(pM,"pM"))

	#return value in umol/l
	Csw_moles_per_metrecubed*1e3
}

}}}

Need to write 'trace gas flux 101' for a book chapter. I want to make it more useful to people new to the field than the usual regurgitation of the theory and presentation of the data that doesn't point out what it is you really need to know if you want to calculate a flux. What are the key points the chapter needs to get accross?

# concentration uncertainty is greater than transfer velocity uncertainty for most or all of the (short-lived) trace gases
# water side transfer velocity parameterisations that you might apply to your trace gas flux problem are empirically-derived (at some level) from observations of the flux of particular gases, or possibly heat and momentum
# air-side transfer velocity parameterisations are based on micrometeorological models of water vapour transfer and poorly validated
# It is difficult to reconcile the wind-speed relationships from different types of gas exchange experiments. Diffrerences, if real, tell us something important.
# Wind is not a direct mechanistic predictor of transfer velocity, but is a useful and pragmatic choice of proxy!
# Whilst there are significant uncertainties associated with the wind dependence of kw parameterisations, other effects are likely to introduce greater uncertainty into gas exchange estimates when applying the parameterisation to other gases, particularly more soluble ones for kw
# bubble effects are parameterised into kw but is actually a separate flux term with k and delta C aspects. 

and the 'classic' gas exchange text book sections are

# gas exchange models
** thin / stagnant film model
*** k-delta-c
*** derive ka /kw etc
** other models
*** e.g. surface renewal, boundary layer etc.
# bubbles
# other processes
** e.g. chemical enhancement, rain, surfactants etc.  
# parameterisations
** wind tunnel studies
** global 14C constraint
** tracer
** direct measurement (e.g eddy covariance) 
** noaa coare

so, how to organise the chapter?

# introduction
** take kDc out of thin film model and generalise in section on the air-water interface like in Bernt Jahne's book chapter.
** derive ka/kw and solubility dependence of partitioning
** turbulent forcing -> windspeed parameterisations-> form and schmidt number dependence
** approaches to calculating gas fluxes
# Schmidt number dependence
** interfacial models
** micrometeorological models
# processes driving gas exchange
** wind
** waves
** bubbles
** temperature, humidity and rain effects
** surfactants
** chemical and biological enhancement
** others
# parameterising gas exchange with windspeed
** kw
*** Global constraint 
*** Natural tracer
*** Deliberate tracer
*** Direct measurements
*** the role of bubbles
*** reconciling observations
** ka
# non-windspeed based parameterisations
** the role of remote sensing
# Gas-dependent and gas-specific effects
# Other considerations
/***
|Name|WhatLinksHerePlugin|
|Source|http://rumkin.com/tools/tiddlywiki/#WhatLinksHerePlugin|
|Version|1.0.0|
|Author|Tyler Akins|
|License|Public Domain|
|~CoreVersion|2.1|
|Type|plugin|
|Requires||
|Overrides||
|Description|Displays a list of pages that link to the current page.  Something like a lightweight version of RelatedTiddlersPlugin.  The links[] data is scanned for all tiddlers that link to the current tiddler.|
!Usage
{{{
<<whatLinksHere txtIfList txtIfNoList>>
}}}
* txtIfList: String to print at the top of the list if there is at least one page that links in to the current one.
* txtIfNoList:  String to print at the top if there are no pages that link to the current tiddler.

!Configuration
Do not list these tiddlers:
{{wideInput{<<option txtWhatLinksHereExclude 40>>}}}

!Examples

This is a live example of what links to this page:
|<<whatLinksHere "List of pages that link to me: <br>" "Sorry, nobody links to me.">>|
I like to put it in my ViewTemplate.  Replace the line that says
{{{
<div class='tagged' macro='tags'></div>
}}}
with this
{{{
<div class='tagged'><div macro='tags'></div><div macro='whatLinksHere "<br>What Links Here: <br> "'></div></div>
}}}

!Installation
# Import the WhatLinksHerePlugin tiddler.
# Modify a tiddler or template to use the whatLinksHere macro.  See above for a sample modification to ViewTemplate

!Revision History
* 1.0.0 (2007-09-30)
** Initial version.

!Credits
The RelatedTiddlersPlugin by Eric L. Shulman was the base for this one.  Even though I didn't use 95% of the code, I did use it for inspiration.

!Code
***/
//{{{
version.extensions.WhatLinksHerePlugin={major: 1, minor: 0, revision: 0, date: new Date(2007,9,30)};

// initialize 'autozoom' and 'exclude' tree options (defaults are not to zoom, and to follow all links)
if (config.options.txtWhatLinksHereExclude===undefined)
	config.options.txtWhatLinksHereExclude='GettingStarted DefaultTiddlers tabTimeline';
if (config.optionsDesc)
	config.optionsDesc.txtWhatLinksHereExclude = "Space or double-bracket separated list of tiddlers to not show"

config.macros.whatLinksHere={
	handler: function(place,macroName,params,wikifier,paramString,tiddler) {
		var span = createTiddlyElement(place, "span");
		var excludes = config.options.txtWhatLinksHereExclude.readBracketedList();
		var results = [];
		var tid = story.findContainingTiddler(place);
		var root = "";
		var out = ""
		if (tid) {
			root=tid.getAttribute("tiddler");
		}

		store.forEachTiddler(function(title,tiddler) {
			if (! excludes || ! excludes.contains(title)) {
				var links = tiddler.getLinks();
				for (var i=0; i < links.length; i++) {
					if (links[i] == root) {
						results.pushUnique(title);
					}
				}
			}
		});
		results.sort();
		out = "[[" + results.join("]]\n[[") + "]]";
		if (results.length && params[0])
			out = params[0] + out;
		if (! results.length && params[1])
			out = params[1] + out;
		out = "{{whatLinksHere{" + out + "}}}";
		wikify(out, place);
	}
}

//}}}
|''Type:''|file|
|''URL:''|http://bob.mcelrath.org/plugins.html#systemConfig|
|''Workspace:''|(default)|

This tiddler was automatically created to record the details of this server
-> take the sum of each group and plot them with barplot, then overlay rectangles for subgroup stacking using symbol()

{{{
boxvector<-c(G_Wa,G_Wtot,A_Wa,A_Wtot,V_Wa, V_Wtot)	
boxes<-array(boxvector,dim=c(2,3),dimnames=list(c("W_a","W_tot"),c("Granite","Andesite","Vermiculite")))
	
# make the plot of Wa and Wtot beside each otehr
ylabel<-expression(paste("Mean weathered amount /  ",mu,"moles",sep=""))
barplot(	
	boxes,
        beside=TRUE,
	space=c(0,1),
	col=c("lightblue","darkblue"),
	cex.lab=1.2,
	cex.names=1.2,
	main=element,
	#ylab= ylabel,
	ylim=c(0,(max(boxes[2,])+max(Wtot_err)))
)
	
#arrange the data for Wmoss for an overlay rectangle
W_moss<-c(G_Wmoss,A_Wmoss,V_Wmoss)
rectmatrix<-matrix(nrow=3,ncol=2)
rectmatrix[,1]<-c(1,1,1)
rectmatrix[,2]<-W_moss
midpoints<-as.double(boxes[2,])-W_moss/2
symbols(x=c(2.5,5.5,8.5),y=midpoints,rectangles=rectmatrix,add=TRUE,inches=FALSE,bg="chartreuse3")

#draw error bars
abiox0<-c(1.5,4.5,7.5)
abioy0<-boxes[1,]-Wa_err
abioy1<-boxes[1,]+Wa_err
arrows(abiox0,abioy0,abiox0,abioy1,angle=90,code=3,length=0.125)
totx0<-c(2.5,5.5,8.5)
toty0<-boxes[2,]-Wtot_err	
toty1<-boxes[2,]+Wtot_err
arrows(totx0,toty0,totx0,toty1,angle=90,code=3,length=0.125)


}}}

which makes something that looks like this:

[img[http://www.nature.com/ngeo/journal/v5/n2/carousel/ngeo1390-f2.jpg]]

except groups are different - not element, as in image, but substrate (granite, vermiculite, andesite)