LOADING: ...

MAST867 Bioinformatics Research
<!--{{{-->
<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]];}

#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]];}

#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 0em 1em 1em; left:-1px; top:-1px;}
.headerForeground {position:absolute; padding:4.5em 0em 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:0em 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 .3em 0;}
#sidebarTabs .tabContents {width:15em; overflow:hidden;}

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

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

.tiddlerPopupButton {padding:0.2em 0.2em 0.2em 0.2em;}
.popupTiddler {position: absolute; z-index:300; padding:1em 1em 1em 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 0em;}
.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 0em 0em 0.5em;}
.tab {margin:0em 0em 0em 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 0em 14em;}

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

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

.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:0em 0.25em; padding:0em 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 0em; font-size:.9em;}
.editorFooter .button {padding-top:0px; padding-bottom:0px;}

.fieldsetFix {border:0; padding:0; margin:1px 0px 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 0.3em 0.5em;}
#backstageToolbar {position:relative;}
#backstageArea a {font-weight:bold; margin-left:0.5em; padding:0.3em 0.5em 0.3em 0.5em;}
#backstageButton {display:none; position:absolute; z-index:175; top:0em; right:0em;}
#backstageButton a {padding:0.1em 0.4em 0.1em 0.4em; margin:0.1em 0.1em 0.1em 0.1em;}
#backstage {position:relative; width:100%; z-index:50;}
#backstagePanel {display:none; z-index:100; position:absolute; margin:0em 3em 0em 3em; padding:1em 1em 1em 1em;}
.backstagePanelFooter {padding-top:0.2em; float:right;}
.backstagePanelFooter a {padding:0.2em 0.4em 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 1em;}
/* Fixes a feature in Firefox 1.5.0.2 where print preview displays the noscript content */
noscript {display:none;}
}
/*}}}*/
<!--{{{-->
<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 closeTiddler closeOthers +editTiddler > fields syncing permalink references jump'></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 +saveTiddler -cancelTiddler deleteTiddler'></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'></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>>
|''Type:''|file|
|''URL:''|http://mptw.tiddlyspot.com|
|''Workspace:''|(default)|

This tiddler was automatically created to record the details of this server
|''Type:''|file|
|''URL:''|http://tiddlywiki.bidix.info|
|''Workspace:''|(default)|

This tiddler was automatically created to record the details of this server
|''Type:''|file|
|''URL:''|http://tw.lewcid.org|
|''Workspace:''|(default)|

This tiddler was automatically created to record the details of this server
|''Type:''|file|
|''URL:''|http://www.tiddlytools.com|
|''Workspace:''|(default)|

This tiddler was automatically created to record the details of this server
{{tableindex{
|[[Test1]]|[[Test2]]|[[subtopic3]]|
}}}
<!--{{{-->
<div class='toolbar' macro='toolbar closeTiddler closeOthers +editTiddler > fields syncing permalink references jump'></div>
<div class='01macro='tiddler 01subtopicMenu'></div><div class='title' macro='view title'></div>
<div class='viewer' macro='view text wikified'></div><div class='tagClear'></div>
<!--}}}-->
<!--{{{-->
<div class='toolbar' macro='toolbar closeTiddler closeOthers +editTiddler > fields syncing permalink references jump'></div>
<div class='AAuse' macro='tiddler AAuseSubtopicMenu'></div><div class='title' macro='view title'></div>
<div class='viewer' macro='view text wikified'></div><div class='tagClear'></div>
<!--}}}-->
/***
|''Name:''|AnnotationsPlugin|
|''Description:''|Inline annotations for tiddler text.|
|''Author:''|Saq Imtiaz ( lewcid@gmail.com )|
|''Source:''|http://tw.lewcid.org/#AnnotationsPlugin|
|''Code Repository:''|http://tw.lewcid.org/svn/plugins|
|''Version:''|2.0|
|''Date:''||
|''License:''|[[Creative Commons Attribution-ShareAlike 3.0 License|http://creativecommons.org/licenses/by-sa/3.0/]]|
|''~CoreVersion:''|2.2.3|

!!Usage:
*{{{((text to annotate(annotation goes here)}}}
* To include the text being annotated, in the popup as a title, put {{{^}}} as the first letter of the annotation text.
** {{{((text to annotate(^annotation goes here)}}}

!!Examples:
Mouse over, the text below:
* ((banana(the best fruit in the world)))
* ((banana(^ the best fruit in the world)))

***/
// /%
config.formatters.unshift({name:"annotations",match:"\\(\\(",lookaheadRegExp:/\(\((.*?)\((\^?)((?:.|\n)*?)\)\)\)/g,handler:function(w){
this.lookaheadRegExp.lastIndex=w.matchStart;
var _2=this.lookaheadRegExp.exec(w.source);
if(_2&&_2.index==w.matchStart){
var _3=createTiddlyElement(w.output,"span",null,"annosub",_2[1]);
_3.anno=_2[3];
if(_2[2]){
_3.subject=_2[1];
}
_3.onmouseover=this.onmouseover;
_3.onmouseout=this.onmouseout;
_3.ondblclick=this.onmouseout;
w.nextMatch=_2.index+_2[0].length;
}
},onmouseover:function(e){
popup=createTiddlyElement(document.body,"div",null,"anno");
this.popup=popup;
if(this.subject){
wikify("!"+this.subject+"\n",popup);
}
wikify(this.anno,popup);
addClass(this,"annosubover");
Popup.place(this,popup,{x:25,y:7});
},onmouseout:function(e){
removeNode(this.popup);
this.popup=null;
removeClass(this,"annosubover");
}});
setStylesheet(".anno{position:absolute;border:2px solid #000;background-color:#DFDFFF; color:#000;padding:0.5em;max-width:15em;width:expression(document.body.clientWidth > (255/12) *parseInt(document.body.currentStyle.fontSize)?'15em':'auto' );}\n"+".anno h1, .anno h2{margin-top:0;color:#000;}\n"+".annosub{background:#ccc;}\n"+".annosubover{z-index:25; background-color:#DFDFFF;cursor:help;}\n","AnnotationStyles");


// %/
!
^^(from http://en.wikipedia.org/wiki/Bioinformatics)^^
''Bioinformatics'' is the application of information technology to the field of molecular biology. The term bioinformatics was coined by Paulien Hogeweg in 1978 for the study of informatic processes in biotic systems. Bioinformatics nowadays entails the creation and advancement of databases, algorithms, computational and statistical techniques, and theory to solve formal and practical problems arising from the management and analysis of biological data. Over the past few decades rapid developments in genomic and other molecular research technologies and developments in information technologies have combined to produce a tremendous amount of information related to molecular biology. It is the name given to these mathematical and computing approaches used to glean understanding of biological processes. Common activities in bioinformatics include mapping and analyzing DNA and protein sequences, aligning different DNA and protein sequences to compare them and creating and viewing 3-D models of protein structures. Bioinformatics is the branch of life science that deals with the study of application of information technology to the field of molecular biology.
[[BACK to Resources|Resource Index]]
!!!
!BioPython: Genetic Sequence Module
1. Get BioPython [[HERE | http://biopython.org/wiki/Main_Page]]
[img[00/biopy01.png]]
!!!

2. Bioinformatics course tutorial can be found online: http://www.pasteur.fr/recherche/unites/sis/formation/python/index.html
[img[00/python-bioinfo.png]]
!!!

3. BioPython Tutorial: [[CLICK HERE|00/Tutorial-Biopython.pdf]]
!!


!!
[[BACK to Resources|Resource Index]]
!!!
!Bioinformatics Core at DBI:
''Biowolf'' is the 286-core parallel computing cluster maintained at the Delaware Biotechnology Institute. Class accounts will be assigned to any participants interested in learning how to utilize this resource.

When you are ready to start using the SUN GRID ENGINE to submit jobs to run on Biowolf, here's a detailed overview of the system provided by Doug O'Neal: 
''A Hitchhiker's Guide to Biowolf:'' http://bioit.dbi.udel.edu/howto/sge

!!!Getting STARTED with your new accout:
# Your "username" and password were emailed to you. They are the first two entries in the text line. 
** Your username is "class" followed by two digits, like "class05"
** Your password is the random 6 character string of letters and numbers
# Make an __[[SSH]]__ connection in a command window
** @@{{{ ssh username@biowolf.dbi.udel.edu }}}@@
** You will be prompted for your initial password
# Change your password:
** The command prompt will look like: @@{{{classXX@biowolf ~$ }}}@@
** Type the command ''passwd'', hit <enter>, follow the queries. 

Now add some default folders to your home directory as follows:
{{{
    prompt> mkdir 01-DATA 
    prompt> mkdir 02-SCRIPTS 
    prompt> mkdir 03-SANDBOX
}}}
* ''01-DATA''
**  You will use this folder to store data files
* ''02-SCRIPTS''
** You will use this folder to store scripts
* ''03-SANDBOX''
** You will use this folder as your working folder for editing and running scripts
** When you are done with an analysis, you will copy the current version of your script back into "02-SCRIPTS" and move any of the data output generated into an appropriate folder in "01-DATA". Then you will delete whatever is left in "03-SANDBOX" to leave it clean for your next code session.
!!!FILE Transfer
It is important that in addition to the command window you have established above, you are also able to use SSH to move files between your Biowolf account and your own computer. 
| TASK 1: Copy all the scripts you have in this class to your "02-SCRIPTS" folder. |
This is accomplished with different interface programs for each OS platform. But basically you want a GUI interface showing you a current folder on your computer and a current folder on Biowolf so you can easily navigate between folders and copy files with a simple drag-drop mouse action. 
* On PCs the GUI you want to run is "SSH-client" (I think), which you can get from UD Network: [[SSH]].
* On Macs, you want the MacFuse plugin for SSH: see [[SSH]].
* On Unix/Linux, I use KDE's Knoqueror that allows for {{{fish://user@biowolf.dbi.udel.edu}}} connections. 

!!!Basic UNIX commands
Work through this simple @@[[UNIX TUTORIAL|http://www.ee.surrey.ac.uk/Teaching/Unix/unix1.html]]@@ to get an introduction to command window controls.
These are the basic commands you will need to use:
{{{
commands:
      ls  = list files aka "dir"
      rm = remove file aka "delete"
      cd .. = change directory up one level
      cd foldername = change directory down one level to foldername
      mkdir foldername = make directory foldername
}}}

!!!
!CDHIT
With the output from a mega-sequencing run in a fasta file of short reads, the ''cd-hit-est'' utility can be a quick first pass at dividing the data into unique (100% identical) sequences with a count of how many times each occurs in the output file. Your batch file to ''biowolf'' would look something like this:
{{{
#!/bin/sh -x
#$ -cwd
#$ -S /bin/sh
#$ -j y
#$ -pe mpi 1
#$ -M your-email@udel.edu
#$ -m bae
#$ -N cdhit

./cd-hit-est -i "inputfilename" -o "outputfilename" -c 1.0 -n 10 -l 20 -M 8000
}}}

!!Parsing the output files:
Here's a quick perl script to combine data from the two types of output files into one tab-delimited file that can easily be utilized in other scripted programs for further analysis (call it ''01-~CDHIT-sequence-parser.pl'' //[Thanks goes to Sridhara]//):
{{{
#!/usr/bin/perl
use strict;
#-------------------H E A D E R -------------
# PARSER for the CD-HIT output files.
# First step to processing mega-sequencing fasta files can be a quick screen
#    through cd-hit-est to ID unique sequence strings:
#    prompt$ cd-hit-est -i "inputfilename" -o "outputfilename" -c 1.0 -n 10 -l 20 -M 8000
# This parser takes the two cd-hit output files and generates a tab-delimited
#    file combining the unique sequences, total counts, and header info.
# SG/AM-2009

#----------------U S E R   V A R I A B L E S----------
my $CLUSTERinfile = "cdhit-clusterfile-test.txt";
my $FASTAinfile   = "cdhit-fastafile-test.txt";
my $QUANTfile = "SeqCount-$FASTAinfile";
#--------------G L O B A L   V A R I A B L E S -----------
my @ClusterCount;
#------------------------------------------------------------
#--------------M A I N -------------------------
#--------------------------------------------------------

# 1. Get the CLUSTER counts . . . . . . . . 
print"\n\nOpening the CLUSTER file to read counts for each signature\n\n";
$/= ">Cluster ";
open (CLUSTER,"<$CLUSTERinfile") or die "cannot open nada $CLUSTERinfile\n";
my @FILE = <CLUSTER>;
close (CLUSTER);
shift (@FILE);

foreach my $entry (@FILE)
{	my @seqdata = split ("\n", $entry);
	$ClusterCount[$seqdata[0]]=$#seqdata -1 ;
}

# 2. Get the sequence data . . . . . . . 
print"\nOpening the FASTA file to input NT sequence reads\n\n";
$/= ">";
open (IN,"<$FASTAinfile") or die "cannot open nada $FASTAinfile\n";
my @Distinct = <IN>;
close (IN);
shift (@Distinct);
open (OUT, ">$QUANTfile");
my $i = 0;
foreach my $entry (@Distinct)
{	my @d = split ("\n", $entry);
	$d[0] =~ s/\s+//g;
	$d[1] =~ s/\s+//g;
# 3. OUTPUT counts and sequence to tab-delimited file . . . . . . . . . 
	print OUT "$d[1]\t$d[0]\t$ClusterCount[$i]\n";
	$i += 1;
	print " . ";
}
close (OUT);
&DataCheck($i,$#ClusterCount);

print "\n * * * *   D O N E   * * * * \n\n\n";

#------- EOF ----------------------------------------------
sub DataCheck
{
	my $x = shift;
	my $y = shift;
	if ($x -1 == $y)
	{	print "\nFiles sizes MATCH!\n\n";	}
	else
	{	print "Warning: Unequal File SIZES.\n\n";  }	
}
#------------------------------------------------------------
}}}

!! Sample Files:
Here's what the cd-hit output files look like. 
File 1 is the cluster file:
{{{
>Cluster 0
0       36nt, >SNPSTER4_90_307R0... *
1       36nt, >SNPSTER4_90_307R0... at +/100%
2       36nt, >SNPSTER4_90_307R0... at +/100%
3       36nt, >SNPSTER4_90_307R0... at +/100%
4       36nt, >SNPSTER4_90_307R0... at +/100%
>Cluster 1
0       36nt, >SNPSTER4_90_307R0... *
1       36nt, >SNPSTER4_90_307R0... at +/100%
2       36nt, >SNPSTER4_90_307R0... at +/100%
3       36nt, >SNPSTER4_90_307R0... at +/100%
4       36nt, >SNPSTER4_90_307R0... at +/100%
5       36nt, >SNPSTER4_90_307R0... at +/100%
>Cluster 2
0       36nt, >SNPSTER4_90_307R0... *
>Cluster 3
0       36nt, >SNPSTER4_90_307R0... *
1       36nt, >SNPSTER4_90_307R0... at +/100%
2       36nt, >SNPSTER4_90_307R0... at +/100%
}}}

File 2 is the fasta file:
{{{
>SNPSTER4_90_307R0AAXX:1:1:1337:1322 run=080625_SNPSTER4_090_307R0AAXX
GTCAGCGAAACGGAGAAGCAGACACGACTTGCCGAC
>SNPSTER4_90_307R0AAXX:1:1:1257:1568 run=080625_SNPSTER4_090_307R0AAXX
GGGGCTTCAGTTTATATTTTTTTTGCTCGCTTCATT
>SNPSTER4_90_307R0AAXX:1:1:1353:1550 run=080625_SNPSTER4_090_307R0AAXX
GTGACTGAATCTTGTTATTTCCCCAGTAGGAAATCG
>SNPSTER4_90_307R0AAXX:1:1:1263:1564 run=080625_SNPSTER4_090_307R0AAXX
GTTCTCATCGAAATATTACCGCGAATTAAATCGGCC
}}}

!


/***
''Name:'' CalendarPlugin
''Version:'' <<getversion calendar>> (<<getversiondate calendar "DD MMM YYYY">>)
''Author:'' SteveRumsby

''Configuration:''

|''First day of week:''|<<option txtCalFirstDay>>|(Monday = 0, Sunday = 6)|
|''First day of weekend:''|<<option txtCalStartOfWeekend>>|(Monday = 0, Sunday = 6)|

''Syntax:'' 
|{{{<<calendar>>}}}|Produce a full-year calendar for the current year|
|{{{<<calendar year>>}}}|Produce a full-year calendar for the given year|
|{{{<<calendar year month>>}}}|Produce a one-month calendar for the given month and year|
|{{{<<calendar thismonth>>}}}|Produce a one-month calendar for the current month|
|{{{<<calendar lastmonth>>}}}|Produce a one-month calendar for last month|
|{{{<<calendar nextmonth>>}}}|Produce a one-month calendar for next month|

***/
// //Modify this section to change the text displayed for the month and day names, to a different language for example. You can also change the format of the tiddler names linked to from each date, and the colours used.

// // ''[[Changes]] by ELS 2005.10.30:''
// // config.macros.calendar.handler()
// // ^^use "tbody" element for IE compatibility^^
// // ^^IE returns 2005 for current year, FF returns 105... fix year adjustment accordingly^^
// // createCalendarDays()
// // ^^use showDate() function (if defined) to render autostyled date with linked popup^^
// // calendar stylesheet definition
// // ^^use .calendar class-specific selectors, add text centering and margin settings^^

//{{{
config.macros.calendar = {};

config.macros.calendar.monthnames = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
config.macros.calendar.daynames = ["M", "T", "W", "T", "F", "S", "S"];

config.macros.calendar.weekendbg = "#c0c0c0";
config.macros.calendar.monthbg = "#e0e0e0";
config.macros.calendar.holidaybg = "#ffc0c0";

//}}}
// //''Code section:''
// (you should not need to alter anything below here)//
//{{{
if(config.options.txtCalFirstDay == undefined)
  config.options.txtCalFirstDay = 0;
if(config.options.txtCalStartOfWeekend == undefined)
  config.options.txtCalStartOfWeekend = 5;

config.macros.calendar.tiddlerformat = "0DD/0MM/YYYY";  // This used to be changeable - for now, it isn't// <<smiley :-(>> 

version.extensions.calendar = { major: 0, minor: 6, revision: 0, date: new Date(2006, 1, 22)};
config.macros.calendar.monthdays = [ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];

config.macros.calendar.holidays = [ ]; // Not sure this is required anymore - use reminders instead
//}}}

// //Is the given date a holiday?
//{{{
function calendarIsHoliday(date)
{
 var longHoliday = date.formatString("0DD/0MM/YYYY");
 var shortHoliday = date.formatString("0DD/0MM");

 for(var i = 0; i < config.macros.calendar.holidays.length; i++) {
   if(config.macros.calendar.holidays[i] == longHoliday || config.macros.calendar.holidays[i] == shortHoliday) {
     return true;
   }
 }
 return false;
}
//}}}

// //The main entry point - the macro handler.
// //Decide what sort of calendar we are creating (month or year, and which month or year)
// // Create the main calendar container and pass that to sub-ordinate functions to create the structure.
// ELS 2005.10.30: added creation and use of "tbody" for IE compatibility and fixup for year >1900//
// ELS 2005.10.30: fix year calculation for IE's getYear() function (which returns '2005' instead of '105')//
//{{{
config.macros.calendar.handler = function(place,macroName,params)
{
   var calendar = createTiddlyElement(place, "table", null, "calendar", null);
   var tbody = createTiddlyElement(calendar, "tbody", null, null, null);
   var today = new Date();
   var year = today.getYear();
   if (year<1900) year+=1900;
   if (params[0] == "thismonth")
  {
      cacheReminders(new Date(year, today.getMonth(), 1, 0, 0), 31);
      createCalendarOneMonth(tbody, year, today.getMonth());
  } 
  else if (params[0] == "lastmonth") {
      var month = today.getMonth()-1; if (month==-1) { month=11; year--; }
      cacheReminders(new Date(year, month, 1, 0, 0), 31);
      createCalendarOneMonth(tbody, year, month);
   }
   else if (params[0] == "nextmonth") {
      var month = today.getMonth()+1; if (month>11) { month=0; year++; }
      cacheReminders(new Date(year, month, 1, 0, 0), 31);
      createCalendarOneMonth(tbody, year, month);
   }
   else {
      if (params[0]) year = params[0];
      if(params[1])
      {
         cacheReminders(new Date(year, params[1]-1, 1, 0, 0), 31);
         createCalendarOneMonth(tbody, year, params[1]-1);
      }
      else
      {
         cacheReminders(new Date(year, 0, 1, 0, 0), 366);
         createCalendarYear(tbody, year);
      }
   }
  window.reminderCacheForCalendar = null;
}
//}}}
//{{{
//This global variable is used to store reminders that have been cached
//while the calendar is being rendered.  It will be renulled after the calendar is fully rendered.
window.reminderCacheForCalendar = null;
//}}}
//{{{
function cacheReminders(date, leadtime)
{
  if (window.findTiddlersWithReminders == null)
    return;
  window.reminderCacheForCalendar = {};
  var leadtimeHash = [];
  leadtimeHash [0] = 0;
  leadtimeHash [1] = leadtime;
  var t = findTiddlersWithReminders(date, leadtimeHash, null, 1);
  for(var i = 0; i < t.length; i++) {
    //just tag it in the cache, so that when we're drawing days, we can bold this one.
     window.reminderCacheForCalendar[t[i]["matchedDate"]] = "reminder:" + t[i]["params"]["title"]; 
  }
}
//}}}
//{{{
function createCalendarOneMonth(calendar, year, mon)
{
  var row = createTiddlyElement(calendar, "tr", null, null, null);
  createCalendarMonthHeader(calendar, row, config.macros.calendar.monthnames[mon] + " " + year, true, year, mon);
  row = createTiddlyElement(calendar, "tr", null, null, null);
  createCalendarDayHeader(row, 1);
  createCalendarDayRowsSingle(calendar, year, mon);
}
//}}}

//{{{
function createCalendarMonth(calendar, year, mon)
{
  var row = createTiddlyElement(calendar, "tr", null, null, null);
  createCalendarMonthHeader(calendar, row, config.macros.calendar.monthnames[mon] + " " + year, false, year, mon);
  row = createTiddlyElement(calendar, "tr", null, null, null);
  createCalendarDayHeader(row, 1);
  createCalendarDayRowsSingle(calendar, year, mon);
}
//}}}

//{{{
function createCalendarYear(calendar, year)
{
  var row;
  row = createTiddlyElement(calendar, "tr", null, null, null);
  var back = createTiddlyElement(row, "td", null, null, null);
  var backHandler = function() {
      removeChildren(calendar);
      createCalendarYear(calendar, year-1);
    };
  createTiddlyButton(back, "<", "Previous year", backHandler);
  back.align = "center";

  var yearHeader = createTiddlyElement(row, "td", null, "calendarYear", year);
  yearHeader.align = "center";
  yearHeader.setAttribute("colSpan", 19);

  var fwd = createTiddlyElement(row, "td", null, null, null);
  var fwdHandler = function() {
    removeChildren(calendar);
    createCalendarYear(calendar, year+1);
  };
  createTiddlyButton(fwd, ">", "Next year", fwdHandler);
  fwd.align = "center";

  createCalendarMonthRow(calendar, year, 0);
  createCalendarMonthRow(calendar, year, 3);
  createCalendarMonthRow(calendar, year, 6);
  createCalendarMonthRow(calendar, year, 9);
}
//}}}

//{{{
function createCalendarMonthRow(cal, year, mon)
{
  var row = createTiddlyElement(cal, "tr", null, null, null);
  createCalendarMonthHeader(cal, row, config.macros.calendar.monthnames[mon], false, year, mon);
  createCalendarMonthHeader(cal, row, config.macros.calendar.monthnames[mon+1], false, year, mon);
  createCalendarMonthHeader(cal, row, config.macros.calendar.monthnames[mon+2], false, year, mon);
  row = createTiddlyElement(cal, "tr", null, null, null);
  createCalendarDayHeader(row, 3);
  createCalendarDayRows(cal, year, mon);
}
//}}}

//{{{
function createCalendarMonthHeader(cal, row, name, nav, year, mon)
{
  var month;
  if(nav) {
    var back = createTiddlyElement(row, "td", null, null, null);
    back.align = "center";
    back.style.background = config.macros.calendar.monthbg;

/*
    back.setAttribute("colSpan", 2);

    var backYearHandler = function() {
      var newyear = year-1;
      removeChildren(cal);
      cacheReminders(new Date(newyear, mon , 1, 0, 0), 31);
      createCalendarOneMonth(cal, newyear, mon);
    };
    createTiddlyButton(back, "<<", "Previous year", backYearHandler);
*/
    var backMonHandler = function() {
      var newyear = year;
      var newmon = mon-1;
      if(newmon == -1) { newmon = 11; newyear = newyear-1;}
      removeChildren(cal);
      cacheReminders(new Date(newyear, newmon , 1, 0, 0), 31);
      createCalendarOneMonth(cal, newyear, newmon);
    };
    createTiddlyButton(back, "<", "Previous month", backMonHandler);


    month = createTiddlyElement(row, "td", null, "calendarMonthname", name)
//    month.setAttribute("colSpan", 3);
    month.setAttribute("colSpan", 5);

    var fwd = createTiddlyElement(row, "td", null, null, null);
    fwd.align = "center";
    fwd.style.background = config.macros.calendar.monthbg; 

//    fwd.setAttribute("colSpan", 2);
    var fwdMonHandler = function() {
      var newyear = year;
      var newmon = mon+1;
      if(newmon == 12) { newmon = 0; newyear = newyear+1;}
      removeChildren(cal);
      cacheReminders(new Date(newyear, newmon , 1, 0, 0), 31);
      createCalendarOneMonth(cal, newyear, newmon);
    };
    createTiddlyButton(fwd, ">", "Next month", fwdMonHandler);
/*
    var fwdYear = createTiddlyElement(row, "td", null, null, null);
    var fwdYearHandler = function() {
      var newyear = year+1;
      removeChildren(cal);
      cacheReminders(new Date(newyear, mon , 1, 0, 0), 31);
      createCalendarOneMonth(cal, newyear, mon);
    };
    createTiddlyButton(fwd, ">>", "Next year", fwdYearHandler);
*/
  } else {
    month = createTiddlyElement(row, "td", null, "calendarMonthname", name)
    month.setAttribute("colSpan", 7);
  }
  month.align = "center";
  month.style.background = config.macros.calendar.monthbg;
}
//}}}

//{{{
function createCalendarDayHeader(row, num)
{
  var cell;
  for(var i = 0; i < num; i++) {
    for(var j = 0; j < 7; j++) {
      var d = j + (config.options.txtCalFirstDay - 0);
      if(d > 6) d = d - 7;
      cell = createTiddlyElement(row, "td", null, null, config.macros.calendar.daynames[d]);

      if(d == (config.options.txtCalStartOfWeekend-0) || d == (config.options.txtCalStartOfWeekend-0+1))
        cell.style.background = config.macros.calendar.weekendbg;
    }
  }
}
//}}}

//{{{
function createCalendarDays(row, col, first, max, year, mon)
{
  var i;
  for(i = 0; i < col; i++) {
    createTiddlyElement(row, "td", null, null, null);
  }
  var day = first;
  for(i = col; i < 7; i++) {
    var d = i + (config.options.txtCalFirstDay - 0);
    if(d > 6) d = d - 7;
    var daycell = createTiddlyElement(row, "td", null, null, null);
    var isaWeekend = ((d == (config.options.txtCalStartOfWeekend-0) || d == (config.options.txtCalStartOfWeekend-0+1))? true:false);

    if(day > 0 && day <= max) {
      var celldate = new Date(year, mon, day);
      // ELS 2005.10.30: use <<date>> macro's showDate() function to create popup
      if (window.showDate) {
        showDate(daycell,celldate,"popup","DD","DD-MMM-YYYY",true, isaWeekend); 
      } else {
        if(isaWeekend) daycell.style.background = config.macros.calendar.weekendbg;
        var title = celldate.formatString(config.macros.calendar.tiddlerformat);
        if(calendarIsHoliday(celldate)) {
          daycell.style.background = config.macros.calendar.holidaybg;
        }
        if(window.findTiddlersWithReminders == null) {
          var link = createTiddlyLink(daycell, title, false);
          link.appendChild(document.createTextNode(day));
        } else {
          var button = createTiddlyButton(daycell, day, title, onClickCalendarDate);
        }
      }
    }
    day++;
  }
}
//}}}

// //We've clicked on a day in a calendar - create a suitable pop-up of options.
// //The pop-up should contain:
// // * a link to create a new entry for that date
// // * a link to create a new reminder for that date
// // * an <hr>
// // * the list of reminders for that date
//{{{
function onClickCalendarDate(e)
{
  var button = this;
  var date = button.getAttribute("title");
  var dat = new Date(date.substr(6,4), date.substr(3,2)-1, date.substr(0, 2));

  date = dat.formatString(config.macros.calendar.tiddlerformat);
  var popup = createTiddlerPopup(this);
  popup.appendChild(document.createTextNode(date));
  var newReminder = function() {
    var t = store.getTiddlers(date);
    displayTiddler(null, date, 2, null, null, false, false);
    if(t) {
      document.getElementById("editorBody" + date).value += "\n<<reminder day:" + dat.getDate() +
                                                                                         " month:" + (dat.getMonth()+1) +
                                                                                         " year:" + (dat.getYear()+1900) + " title: >>";
    } else {
      document.getElementById("editorBody" + date).value = "<<reminder day:" + dat.getDate() +
                                                                                       " month:" + (dat.getMonth()+1) +
                                                                                       " year:" + (dat.getYear()+1900) + " title: >>";
    }
  };
  var link = createTiddlyButton(popup, "New reminder", null, newReminder); 
  popup.appendChild(document.createElement("hr"));

  var t = findTiddlersWithReminders(dat, [0,14], null, 1);
  for(var i = 0; i < t.length; i++) {
    link = createTiddlyLink(popup, t[i].tiddler, false);
    link.appendChild(document.createTextNode(t[i].tiddler));
  }
}
//}}}

//{{{
function calendarMaxDays(year, mon)
{
 var max = config.macros.calendar.monthdays[mon];
 if(mon == 1 && (year % 4) == 0 && ((year % 100) != 0 || (year % 400) == 0)) {
 max++;
 }
 return max;
}
//}}}

//{{{
function createCalendarDayRows(cal, year, mon)
{
 var row = createTiddlyElement(cal, "tr", null, null, null);

 var first1 = (new Date(year, mon, 1)).getDay() -1 - (config.options.txtCalFirstDay-0);
 if(first1 < 0) first1 = first1 + 7;
 var day1 = -first1 + 1;
 var first2 = (new Date(year, mon+1, 1)).getDay() -1 - (config.options.txtCalFirstDay-0);
 if(first2 < 0) first2 = first2 + 7;
 var day2 = -first2 + 1;
 var first3 = (new Date(year, mon+2, 1)).getDay() -1 - (config.options.txtCalFirstDay-0);
 if(first3 < 0) first3 = first3 + 7;
 var day3 = -first3 + 1;

 var max1 = calendarMaxDays(year, mon);
 var max2 = calendarMaxDays(year, mon+1);
 var max3 = calendarMaxDays(year, mon+2);

 while(day1 <= max1 || day2 <= max2 || day3 <= max3) {
 row = createTiddlyElement(cal, "tr", null, null, null);
 createCalendarDays(row, 0, day1, max1, year, mon); day1 += 7;
 createCalendarDays(row, 0, day2, max2, year, mon+1); day2 += 7;
 createCalendarDays(row, 0, day3, max3, year, mon+2); day3 += 7;
 }
}
//}}}

//{{{
function createCalendarDayRowsSingle(cal, year, mon)
{
 var row = createTiddlyElement(cal, "tr", null, null, null);

 var first1 = (new Date(year, mon, 1)).getDay() -1 - (config.options.txtCalFirstDay-0);
 if(first1 < 0) first1 = first1+ 7;
 var day1 = -first1 + 1;
 var max1 = calendarMaxDays(year, mon);

 while(day1 <= max1) {
 row = createTiddlyElement(cal, "tr", null, null, null);
 createCalendarDays(row, 0, day1, max1, year, mon); day1 += 7;
 }
}
//}}}

// //ELS 2005.10.30: added styles
//{{{
setStylesheet(".calendar, .calendar table, .calendar th, .calendar tr, .calendar td { font-size:10pt; text-align:center; } .calendar, .calendar a { margin:0px !important; padding:0px !important; }", "calendarStyles");
//}}}
/***
|Name|CheckboxPlugin|
|Source|http://www.TiddlyTools.com/#CheckboxPlugin|
|Version|2.2.4|
|Author|Eric Shulman - ELS Design Studios|
|License|http://www.TiddlyTools.com/#LegalStatements <<br>>and [[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]|
|~CoreVersion|2.1|
|Type|plugin|
|Requires||
|Overrides||
|Description|Add checkboxes to your tiddler content|
This plugin extends the TiddlyWiki syntax to allow definition of checkboxes that can be embedded directly in tiddler content.  Checkbox states are preserved by either:
* automatically modifying the tiddler content (deprecated)
* or, by setting/removing tags on specified tiddlers,
* or, by setting custom field values on specified tiddlers,
* or, by saving to a locally-stored cookie ID.
When an ID is assigned to the checkbox, it enables direct programmatic access to the checkbox DOM element, as well as creating an entry in TiddlyWiki's config.options[ID] internal data.  In addition to tracking the checkbox state, you can also specify custom javascript for programmatic initialization and onClick event handling for any checkbox, so you can provide specialized side-effects in response to state changes.
!!!!! Inline wiki-syntax usage
<<<
//{{{
[ ]or[_] and [x]or[X]
//}}}
Simple checkboxes using 'Inline X' storage.  The current unchecked/checked state is indicated by the character between the {{{[}}} and {{{]}}} brackets ("_" means unchecked, "X" means checked).  When you click on a checkbox, the current state is retained by directly modifying the tiddler content to place the corresponding "_" or "X" character in between the brackets.
>//''NOTE: 'Inline X' syntax has been deprecated...''  This storage format only works properly for checkboxes that are directly embedded and accessed from content in a single tiddler.  However, if that tiddler is 'transcluded' into another (by using the {{{<<tiddler TiddlerName>>}}} macro), the 'Inline X' will be ''erroneously stored in the containing tiddler's source content, resulting in corrupted content in that tiddler.''  For anything but the most simple of "to do list" uses, you should select from the various alternative storage methods described below...//
//{{{
[x=id]
//}}}
Assign an optional ID to the checkbox so you can use {{{document.getElementByID("id")}}} to manipulate the checkbox DOM element, as well as tracking the current checkbox state in {{{config.options["id"]}}}.  If the ID starts with "chk" the checkbox state will also be saved in a cookie, so it can be automatically restored whenever the checkbox is re-rendered (overrides any default {{{[x]}}} or {{{[_]}}} value).  If a cookie value is kept, the "_" or "X" character in the tiddler content remains unchanged, and is only applied as the default when a cookie-based value is not currently defined.
//{{{
[x(title|tag)] or [x(title:tag)]
//}}}
Initializes and tracks the current checkbox state by setting or removing a particular tag value from a specified tiddler.  If you omit the tiddler title (and the | or : separator), the specified tag is assigned to the current tiddler.  If you omit the tag value, as in {{{(title|)}}}, the default tag, {{{checked}}}, is assumed.  Omitting both the title and tag, {{{()}}}, tracks the checkbox state by setting the "checked" tag on the current tiddler.  When tag tracking is used, the "_" or "X" character in the tiddler content remains unchanged, and is not used to set or track the checkbox state.  If a tiddler title named in the tag does not exist, the checkbox state defaults to the "inline X" value.  If this value is //checked//, or is subsequently changed to //checked//, it will automatically create the missing tiddler and then add the tag to it.  //''NOTE: beginning with version 2.1.2 of this plugin, the "|" separator is the preferred separator between the title and tag name, as it avoids syntactic ambiguity when ":" is used within tiddler titles or tag names.''//
//{{{
[x(field@tiddler)]
//}}}
Initializes and tracks the current checkbox state by setting a particular custom field value from a specified tiddler.  If you omit the tiddler title (but not the "@" separator), the specified field on the current tiddler is used.  If you omit the field name, as in {{{(@tiddler)}}}, a default fieldname of {{{checked}}} is assumed.  Omitting both the field and the tiddler title, {{{(@)}}}, defaults to setting the "checked" field on the current tiddler.  When field tracking is used, the "_" or "X" character in the tiddler content remains unchanged, and is not used to set or track the checkbox state.  If the tiddler title named in the parameter does not exist, the checkbox state defaults to the "inline X" value.  If this value is //checked// or is subsequently changed to //checked//, it will automatically create the missing tiddler and then add the field to it.
//{{{
[x{javascript}{javascript}]
//}}}
You can define optional javascript code segments to add custom initialization and/or 'onClick' handling to a checkbox.  The current checkbox state (and it's other DOM attributes) can be set or read from within these code segments by reference to the default context-object, 'this'.

The first code segment will be executed when the checkbox is initially displayed, so that you can programmatically determine it's starting checked/unchecked state.  The second code segment (if present) is executed whenever the checkbox is clicked, so that you can perform programmed responses or intercept and override the checkbox state based on complex logic using the TW core API or custom functions defined in plugins (e.g. testing a particular tiddler title to see if certain tags are set or setting some tags when the checkbox is clicked).

Note: if you want to use the default checkbox initialization processing with a custom onclick function, use this syntax: {{{ [x=id{}{javascript}] }}} 
<<<
!!!!! Macro usage
<<<
In addition to embedded checkboxes using the wiki syntax described above, a ''macro-based syntax'' is also provided, for use in templates where wiki syntax cannot be directly used.  This macro syntax can also be used in tiddler content, as an alternative to the wiki syntax.  When embedded in [[PageTemplate]], [[ViewTemplate]], or [[EditTemplate]] (or custom alternative templates), use the following macro syntax:
//{{{
<span macro="checkbox target checked id onInit onClick"></span>
//}}}
or, when embedded in tiddler content, use the following macro syntax:
//{{{
<<checkbox target checked id onInit onClick>>
//}}}
where:
''target''
>is either a tag reference (e.g., ''tagname|tiddlername'') or a field reference (e.g. ''fieldname@tiddlername''), as described above.
''checked'' (optional)
>is a keyword that sets the initial state of the checkbox to "checked".  When omitted, the default checkbox state is "unchecked".
''id'' (optional)
>specifies an internal config.options.* ID, as described above.  If the ID begins with "chk", a cookie-based persistent value will be created to track the checkbox state in between sessions.
''onInit'' (optional)
>contains a javascript event handler to be performed when the checkbox is initially rendered (see details above).
''onClick'' (optional)
>contains a javascript event handler to be performed each time the checkbox is clicked (see details above).
>//note: to use the default onInit handler with a custom onClick handler, use "" (empty quotes) as a placeholder for the onInit parameter//
<<<
!!!!!Examples
<<<
''checked and unchecked static default ("inline X") values:''
//{{{
[X] label
[_] label
//}}}
>[X] label
>[_] label
''document-based value (id='demo', no cookie):''
//{{{
[_=demo] label
//}}}
>[_=demo] label
''cookie-based value  (id='chkDemo'):''
//{{{
[_=chkDemo] label
//}}}
>[_=chkDemo] label
''tag-based value (TogglyTagging):''
//{{{
[_(CheckboxPlugin|demotag)]
[_(CheckboxPlugin|demotag){this.refresh.tagged=this.refresh.container=false}]
//}}}
>[_(CheckboxPlugin|demotag)] toggle 'demotag' (and refresh tiddler display)
>[_(CheckboxPlugin|demotag){this.refresh.tagged=this.refresh.container=false}] toggle 'demotag' (no refresh)
''field-based values:''
//{{{
[_(demofield@CheckboxPlugin)] demofield@CheckboxPlugin
[_(demofield@)] demofield@ (equivalent to demonfield@ current tiddler)
[_(checked@CheckboxPlugin)] checked@CheckboxPlugin
[_(@CheckboxPlugin)] @CheckboxPlugin
[_(@)] @ (equivalent to checked@ current tiddler)
//}}}
>[_(demofield@CheckboxPlugin)] demofield@CheckboxPlugin
>[_(demofield@)] demofield@ (current tiddler)
>[_(checked@CheckboxPlugin)] checked@CheckboxPlugin
>[_(@CheckboxPlugin)] @CheckboxPlugin
>[_(@)] toggle field: @ (defaults to "checked@here")
>click to view current: <<toolbar fields>>
''custom init and onClick functions:''
//{{{
[X{this.checked=true}{alert(this.checked?"on":"off")}] message box with checkbox state
//}}}
>[X{this.checked=true}{alert(this.checked?"on":"off")}] message box with checkbox state
''retrieving option values:''
>config.options['demo']=<script>return config.options['demo']?"true":"false";</script>
>config.options['chkDemo']=<script>return config.options['chkDemo']?"true":"false";</script>
<<<
!!!!!Configuration
<<<
Normally, when a checkbox state is changed, the affected tiddlers are automatically re-rendered, so that any checkbox-dependent dynamic content can be updated.  There are three possible tiddlers to be re-rendered, depending upon where the checkbox is placed, and what kind of storage method it is using.
*''container'': the tiddler in which the checkbox is displayed. (e.g., this tiddler)
*''tagged'': the tiddler that is being tagged (e.g., "~MyTask" when tagging "~MyTask:done")
*''tagging'': the "tag tiddler" (e.g., "~done" when tagging "~MyTask:done")
You can set the default refresh handling for all checkboxes in your document by using the following javascript syntax either in a systemConfig plugin, or as an inline script.  (Substitute true/false values as desired):
{{{config.checkbox.refresh = { tagged:true, tagging:true, container:true };}}}

You can also override these defaults for any given checkbox by using an initialization function to set one or more of the refresh options.  For example:
{{{[_{this.refresh.container=false}]}}}
<<<
!!!!!Installation
<<<
import (or copy/paste) the following tiddlers into your document:
''CheckboxPlugin'' (tagged with <<tag systemConfig>>)
<<<
!!!!!Revision History
<<<
2007.08.06 - 2.2.5 supress automatic refresh of any tiddler that is currently being edited.  Ensures that current tiddler edit sessions are not prematurely discarded (losing any changes).  However, if checkbox changes a tag on a tiddler being edited, update the "tags" input field (if any) so that saving the edited tiddler correctly reflects any changes due to checkbox activity... see refreshEditorTagField().
2007.07.13 - 2.2.4 in handler(), fix srctid reference (was "w.tiddler", should have been "w.tiddler.title").  This fixes broken 'inline X' plus fatal macro error when using PartTiddlerPlugin.  Thanks to cmari for reporting the problem and UdoBorkowski for finding the code error.
2007.06.21 - 2.2.3 suppress automatic refresh of tiddler when using macro-syntax to prevent premature end of tiddler editing session.
2007.06.20 - 2.2.2 fixed handling for 'inline X' when checkboxes are contained in a 'trancluded' tiddler.  Now, regardless of where an inline X checkbox appears, the X will be placed in the originating source tiddler, rather than the tiddler in which the checkbox appears.
2007.06.17 - 2.2.1 Refactored code to add checkbox //macro// syntax for use in templates (e.g., {{{macro="checkbox ..."}}}. Also, code cleanup of existing tag handling.
2007.06.16 - 2.2.0 added support for tracking checkbox states using tiddler fields via "(fieldname@tiddlername)" syntax.
2006.05.04 - 2.1.3 fix use of findContainingTiddler() to check for a non-null return value, so that checkboxes won't crash when used outside of tiddler display context (such as in header, sidebar or mainmenu)
2006.03.11 - 2.1.2 added "|" as delimiter to tag-based storage syntax (e.g. "tiddler|tag") to avoid parsing ambiguity when tiddler titles or tag names contain ":".   Using ":" as a delimiter is still supported but is deprecated in favor of the new "|" usage.  Based on a problem reported by JeffMason.
2006.02.25 - 2.1.0 added configuration options to enable/disable forced refresh of tiddlers when toggling tags
2006.02.23 - 2.0.4 when toggling tags, force refresh of the tiddler containing the checkbox.
2006.02.23 - 2.0.3 when toggling tags, force refresh of the 'tagged tiddler' so that tag-related tiddler content (such as "to-do" lists) can be re-rendered.
2006.02.23 - 2.0.2 when using tag-based storage, allow use [[ and ]] to quote tiddler or tag names that contain spaces:
{{{[x([[Tiddler with spaces]]:[[tag with spaces]])]}}}
2006.01.10 - 2.0.1 when toggling tags, force refresh of the 'tagging tiddler'.  For example, if you toggle the "systemConfig" tag on a plugin, the corresponding "systemConfig" TIDDLER will be automatically refreshed (if currently displayed), so that the 'tagged' list in that tiddler will remain up-to-date.
2006.01.04 - 2.0.0 update for ~TW2.0
2005.12.27 - 1.1.2 Fix lookAhead regExp handling for {{{[x=id]}}}, which had been including the "]" in the extracted ID.  
Added check for "chk" prefix on ID before calling saveOptionCookie()
2005.12.26 - 1.1.2 Corrected use of toUpperCase() in tiddler re-write code when comparing {{{[X]}}} in tiddler content with checkbox state. Fixes a problem where simple checkboxes could be set, but never cleared.
2005.12.26 - 1.1.0 Revise syntax so all optional parameters are included INSIDE the [ and ] brackets.  Backward compatibility with older syntax is supported, so content changes are not required when upgrading to the current version of this plugin.   Based on a suggestion by GeoffSlocock
2005.12.25 - 1.0.0 added support for tracking checkbox state using tags ("TogglyTagging")
Revised version number for official post-beta release.
2005.12.08 - 0.9.3 support separate 'init' and 'onclick' function definitions.
2005.12.08 - 0.9.2 clean up lookahead pattern
2005.12.07 - 0.9.1 only update tiddler source content if checkbox state is actually different.  Eliminates unnecessary tiddler changes (and 'unsaved changes' warnings)
2005.12.07 - 0.9.0 initial BETA release
<<<
!!!!!Credits
<<<
This feature was created by EricShulman from [[ELS Design Studios|http:/www.elsdesign.com]]
<<<
!!!!!Code
***/
//{{{
version.extensions.CheckboxPlugin = {major: 2, minor: 2, revision:5 , date: new Date(2007,8,6)};
//}}}

//{{{
config.checkbox = { refresh: { tagged:true, tagging:true, container:true } };
config.formatters.push( {
	name: "checkbox",
	match: "\\[[xX_ ][\\]\\=\\(\\{]",
	lookahead: "\\[([xX_ ])(=[^\\s\\(\\]{]+)?(\\([^\\)]*\\))?({[^}]*})?({[^}]*})?\\]",
	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) {
			// get params
			var checked=(lookaheadMatch[1].toUpperCase()=="X");
			var id=lookaheadMatch[2];
			var target=lookaheadMatch[3];
			if (target) target=target.substr(1,target.length-2).trim(); // trim off parentheses
			var fn_init=lookaheadMatch[4];
			var fn_click=lookaheadMatch[5];
			var tid=story.findContainingTiddler(w.output);  if (tid) tid=tid.getAttribute("tiddler");
			var srctid=w.tiddler?w.tiddler.title:null;
			config.macros.checkbox.create(w.output,tid,srctid,w.matchStart+1,checked,id,target,config.checkbox.refresh,fn_init,fn_click);
			w.nextMatch = lookaheadMatch.index + lookaheadMatch[0].length;
		}
	}
} );
config.macros.checkbox = {
	handler: function(place,macroName,params,wikifier,paramString,tiddler) {
		if(!(tiddler instanceof Tiddler)) { // if no tiddler passed in try to find one
			var here=story.findContainingTiddler(place);
			if (here) tiddler=store.getTiddler(here.getAttribute("tiddler"))
		}
		var srcpos=0; // "inline X" not applicable to macro syntax
		var target=params.shift(); if (!target) target="";
		var defaultState=params[0]=="checked"; if (defaultState) params.shift();
		var id=params.shift(); if (id && !id.length) id=null;
		var fn_init=params.shift(); if (fn_init && !fn_init.length) fn_init=null;
		var fn_click=params.shift(); if (fn_click && !fn_click.length) fn_click=null;
		var refresh={ tagged:true, tagging:true, container:false };
		this.create(place,tiddler.title,tiddler.title,0,defaultState,id,target,refresh,fn_init,fn_click);
	},
	create: function(place,tid,srctid,srcpos,defaultState,id,target,refresh,fn_init,fn_click) {
		// create checkbox element
		var c = document.createElement("input");
		c.setAttribute("type","checkbox");
		c.onclick=this.onClickCheckbox;
		c.srctid=srctid; // remember source tiddler
		c.srcpos=srcpos; // remember location of "X"
		c.container=tid; // containing tiddler (may be null if not in a tiddler)
		c.tiddler=tid; // default target tiddler 
		c.refresh = {};
		c.refresh.container = refresh.container;
		c.refresh.tagged = refresh.tagged;
		c.refresh.tagging = refresh.tagging;
		place.appendChild(c);
		// set default state
		c.checked=defaultState;
		// track state in config.options.ID
		if (id) {
			c.id=id.substr(1); // trim off leading "="
			if (config.options[c.id]!=undefined)
				c.checked=config.options[c.id];
			else
				config.options[c.id]=c.checked;
		}
		// track state in (tiddlername|tagname) or (fieldname@tiddlername)
		if (target) {
			var pos=target.indexOf("@");
			if (pos!=-1) {
				c.field=pos?target.substr(0,pos):"checked"; // get fieldname (or use default "checked")
				c.tiddler=target.substr(pos+1); // get specified tiddler name (if any)
				if (!c.tiddler || !c.tiddler.length) c.tiddler=tid; // if tiddler not specified, default == container
				if (store.getValue(c.tiddler,c.field)!=undefined)
					c.checked=(store.getValue(c.tiddler,c.field)=="true"); // set checkbox from saved state
			} else {
				var pos=target.indexOf("|"); if (pos==-1) var pos=target.indexOf(":");
				c.tag=target;
				if (pos==0) c.tag=target.substr(1); // trim leading "|" or ":"
				if (pos>0) { c.tiddler=target.substr(0,pos); c.tag=target.substr(pos+1); }
				if (!c.tag.length) c.tag="checked";
				var t=store.getTiddler(c.tiddler);
				if (t && t.tags)
					c.checked=t.isTagged(c.tag); // set checkbox from saved state
			}
		}
		if (fn_init) c.fn_init=fn_init.trim().substr(1,fn_init.length-2); // trim off surrounding { and } delimiters
		if (fn_click) c.fn_click=fn_click.trim().substr(1,fn_click.length-2);
		c.init=true; c.onclick(); c.init=false; // compute initial state and save in tiddler/config/cookie
	},
	onClickCheckbox: function(event) {
		if (this.fn_init)
			// custom function hook to set initial state (run only once)
			{ try { eval(this.fn_init); this.fn_init=null; } catch(e) { displayMessage("Checkbox init error: "+e.toString()); } }
		else if (this.fn_click)
			// custom function hook to override or react to changes in checkbox state
			{ try { eval(this.fn_click) } catch(e) { displayMessage("Checkbox click error: "+e.toString()); } }
		if (this.id)
			// save state in config AND cookie (only when ID starts with 'chk')
			{ config.options[this.id]=this.checked; if (this.id.substr(0,3)=="chk") saveOptionCookie(this.id); }
		if (this.srctid && this.srcpos>0 && (!this.id || this.id.substr(0,3)!="chk") && !this.tag && !this.field) {
			// save state in tiddler content only if not using cookie, tag or field tracking
			var t=store.getTiddler(this.srctid); // put X in original source tiddler (if any)
			if (t && this.checked!=(t.text.substr(this.srcpos,1).toUpperCase()=="X")) { // if changed
				t.set(null,t.text.substr(0,this.srcpos)+(this.checked?"X":"_")+t.text.substr(this.srcpos+1),null,null,t.tags);
				if (!story.isDirty(t.title)) story.refreshTiddler(t.title,null,true);
				store.setDirty(true);
			}
		}
		if (this.field) {
			if (this.checked && !store.tiddlerExists(this.tiddler))
				store.saveTiddler(this.tiddler,this.tiddler,"",config.options.txtUserName,new Date());
			// set the field value in the target tiddler
			store.setValue(this.tiddler,this.field,this.checked?"true":"false");
			// DEBUG: displayMessage(this.field+"@"+this.tiddler+" is "+this.checked);
		}
		if (this.tag) {
			if (this.checked && !store.tiddlerExists(this.tiddler))
				store.saveTiddler(this.tiddler,this.tiddler,"",config.options.txtUserName,new Date());
			var t=store.getTiddler(this.tiddler);
			if (t) {
				var tagged=(t.tags && t.tags.find(this.tag)!=null);
				if (this.checked && !tagged) { t.tags.push(this.tag); store.setDirty(true); }
				if (!this.checked && tagged) { t.tags.splice(t.tags.find(this.tag),1); store.setDirty(true); }
			}
			// if tag state has been changed, update display of corresponding tiddlers (unless they are in edit mode...)
			if (this.checked!=tagged) {
				if (this.refresh.tagged) {
					if (!story.isDirty(this.tiddler)) story.refreshTiddler(this.tiddler,null,true); // the TAGGED tiddler in view mode
					else config.macros.checkbox.refreshEditorTagField(this.tiddler,this.tag,this.checked); // the TAGGED tiddler in edit mode (with tags field)
				}
				if (this.refresh.tagging)
					if (!story.isDirty(this.tag)) story.refreshTiddler(this.tag,null,true); // the TAGGING tiddler
			}
		}
		// refresh containing tiddler (but not during initial rendering, or we get an infinite loop!) (and not when editing container)
		if (!this.init && this.refresh.container && this.container!=this.tiddler)
			if (!story.isDirty(this.container)) story.refreshTiddler(this.container,null,true); // the tiddler CONTAINING the checkbox
		return true;
	},
	refreshEditorTagField: function(title,tag,set) {
		var tagfield=story.getTiddlerField(title,"tags");
		if (!tagfield||tagfield.getAttribute("edit")!="tags") return; // if no tags field in editor (i.e., custom template)
		var tags=tagfield.value.readBracketedList();
		if (tags.contains(tag)==set) return; // if no change needed
		if (set) tags.push(tag); // add tag
		else tags.splice(tags.indexOf(tag),1); // remove tag
		for (var t=0;t<tags.length;t++) tags[t]=String.encodeTiddlyLink(tags[t]);
		tagfield.value=tags.join(" "); // reassemble tag string (with brackets as needed)
		return;
	}
}
//}}}
!Class Code

1. [[MonkeysTyping]]: combinometrics template, PERL
2. DirectedEvolutionPy: selected evolution, PYTHON
3. DirectedGAPy: basic genetic algorithm structure
4. CDHITparser: combines count and sequence data from different files

!
Background: #fff
Foreground: #000
PrimaryPale: #ddeeaa
PrimaryLight: #ddeeaa
PrimaryMid: #666633
PrimaryDark: #014
SecondaryPale: #bbdd88
SecondaryLight: #fe8
SecondaryMid: #db4
SecondaryDark: #666633
TertiaryPale: #eee
TertiaryLight: #ccc
TertiaryMid: #999
TertiaryDark: #aacc88
Error: #f88
# Group ENTRIES by a common tag, 'xxxx'.
# Create subtopic menu:
** rename as ''//xxxx//SubtopicMenu''
** enter the ENTRY titles into the table cells
# Create the viewtemplate
** rename as ''//xxxx//ViewTemplate''
** edit this line in the body, to this syntax using the 'xxxx' tag name:
{{{
<class='xxxx' macro='tiddler xxxxSubtopicMenu'>
}}}
!!SUBTOPIC PAGE CONTENT
{{{
<html>
<div style="color: rgb(100, 100, 150); font-family: Monaco;"><big><b>
TITLE OR HEADER OR DESCRIPTOR . . . .. 
</html>
1. [[x |1.11]]
2. [[y |1.12]]
3. [[z |1.13]]
!!
}}}
!!PLOT PAGE CONTENT
{{{
//header title//
<html><img src="00/xxxx.png" style="height:400px"></html>
[[BACK|XXTAGNAMEXX]]
!!!
}}}
!!
/***
|''Name:''|CryptoFunctionsPlugin|
|''Description:''|Support for cryptographic functions|
***/
//{{{
if(!version.extensions.CryptoFunctionsPlugin) {
version.extensions.CryptoFunctionsPlugin = {installed:true};

//--
//-- Crypto functions and associated conversion routines
//--

// Crypto "namespace"
function Crypto() {}

// Convert a string to an array of big-endian 32-bit words
Crypto.strToBe32s = function(str)
{
	var be = Array();
	var len = Math.floor(str.length/4);
	var i, j;
	for(i=0, j=0; i<len; i++, j+=4) {
		be[i] = ((str.charCodeAt(j)&0xff) << 24)|((str.charCodeAt(j+1)&0xff) << 16)|((str.charCodeAt(j+2)&0xff) << 8)|(str.charCodeAt(j+3)&0xff);
	}
	while (j<str.length) {
		be[j>>2] |= (str.charCodeAt(j)&0xff)<<(24-(j*8)%32);
		j++;
	}
	return be;
};

// Convert an array of big-endian 32-bit words to a string
Crypto.be32sToStr = function(be)
{
	var str = "";
	for(var i=0;i<be.length*32;i+=8)
		str += String.fromCharCode((be[i>>5]>>>(24-i%32)) & 0xff);
	return str;
};

// Convert an array of big-endian 32-bit words to a hex string
Crypto.be32sToHex = function(be)
{
	var hex = "0123456789ABCDEF";
	var str = "";
	for(var i=0;i<be.length*4;i++)
		str += hex.charAt((be[i>>2]>>((3-i%4)*8+4))&0xF) + hex.charAt((be[i>>2]>>((3-i%4)*8))&0xF);
	return str;
};

// Return, in hex, the SHA-1 hash of a string
Crypto.hexSha1Str = function(str)
{
	return Crypto.be32sToHex(Crypto.sha1Str(str));
};

// Return the SHA-1 hash of a string
Crypto.sha1Str = function(str)
{
	return Crypto.sha1(Crypto.strToBe32s(str),str.length);
};

// Calculate the SHA-1 hash of an array of blen bytes of big-endian 32-bit words
Crypto.sha1 = function(x,blen)
{
	// Add 32-bit integers, wrapping at 32 bits
	add32 = function(a,b)
	{
		var lsw = (a&0xFFFF)+(b&0xFFFF);
		var msw = (a>>16)+(b>>16)+(lsw>>16);
		return (msw<<16)|(lsw&0xFFFF);
	};
	// Add five 32-bit integers, wrapping at 32 bits
	add32x5 = function(a,b,c,d,e)
	{
		var lsw = (a&0xFFFF)+(b&0xFFFF)+(c&0xFFFF)+(d&0xFFFF)+(e&0xFFFF);
		var msw = (a>>16)+(b>>16)+(c>>16)+(d>>16)+(e>>16)+(lsw>>16);
		return (msw<<16)|(lsw&0xFFFF);
	};
	// Bitwise rotate left a 32-bit integer by 1 bit
	rol32 = function(n)
	{
		return (n>>>31)|(n<<1);
	};

	var len = blen*8;
	// Append padding so length in bits is 448 mod 512
	x[len>>5] |= 0x80 << (24-len%32);
	// Append length
	x[((len+64>>9)<<4)+15] = len;
	var w = Array(80);

	var k1 = 0x5A827999;
	var k2 = 0x6ED9EBA1;
	var k3 = 0x8F1BBCDC;
	var k4 = 0xCA62C1D6;

	var h0 = 0x67452301;
	var h1 = 0xEFCDAB89;
	var h2 = 0x98BADCFE;
	var h3 = 0x10325476;
	var h4 = 0xC3D2E1F0;

	for(var i=0;i<x.length;i+=16) {
		var j,t;
		var a = h0;
		var b = h1;
		var c = h2;
		var d = h3;
		var e = h4;
		for(j = 0;j<16;j++) {
			w[j] = x[i+j];
			t = add32x5(e,(a>>>27)|(a<<5),d^(b&(c^d)),w[j],k1);
			e=d; d=c; c=(b>>>2)|(b<<30); b=a; a = t;
		}
		for(j=16;j<20;j++) {
			w[j] = rol32(w[j-3]^w[j-8]^w[j-14]^w[j-16]);
			t = add32x5(e,(a>>>27)|(a<<5),d^(b&(c^d)),w[j],k1);
			e=d; d=c; c=(b>>>2)|(b<<30); b=a; a = t;
		}
		for(j=20;j<40;j++) {
			w[j] = rol32(w[j-3]^w[j-8]^w[j-14]^w[j-16]);
			t = add32x5(e,(a>>>27)|(a<<5),b^c^d,w[j],k2);
			e=d; d=c; c=(b>>>2)|(b<<30); b=a; a = t;
		}
		for(j=40;j<60;j++) {
			w[j] = rol32(w[j-3]^w[j-8]^w[j-14]^w[j-16]);
			t = add32x5(e,(a>>>27)|(a<<5),(b&c)|(d&(b|c)),w[j],k3);
			e=d; d=c; c=(b>>>2)|(b<<30); b=a; a = t;
		}
		for(j=60;j<80;j++) {
			w[j] = rol32(w[j-3]^w[j-8]^w[j-14]^w[j-16]);
			t = add32x5(e,(a>>>27)|(a<<5),b^c^d,w[j],k4);
			e=d; d=c; c=(b>>>2)|(b<<30); b=a; a = t;
		}

		h0 = add32(h0,a);
		h1 = add32(h1,b);
		h2 = add32(h2,c);
		h3 = add32(h3,d);
		h4 = add32(h4,e);
	}
	return Array(h0,h1,h2,h3,h4);
};


}
//}}}
[[FrontPage]]
/***
|''Name:''|DeprecatedFunctionsPlugin|
|''Description:''|Support for deprecated functions removed from core|
***/
//{{{
if(!version.extensions.DeprecatedFunctionsPlugin) {
version.extensions.DeprecatedFunctionsPlugin = {installed:true};

//--
//-- Deprecated code
//--

// @Deprecated: Use createElementAndWikify and this.termRegExp instead
config.formatterHelpers.charFormatHelper = function(w)
{
	w.subWikify(createTiddlyElement(w.output,this.element),this.terminator);
};

// @Deprecated: Use enclosedTextHelper and this.lookaheadRegExp instead
config.formatterHelpers.monospacedByLineHelper = 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 text = lookaheadMatch[1];
		if(config.browser.isIE)
			text = text.replace(/\n/g,"\r");
		createTiddlyElement(w.output,"pre",null,null,text);
		w.nextMatch = lookaheadRegExp.lastIndex;
	}
};

// @Deprecated: Use <br> or <br /> instead of <<br>>
config.macros.br = {};
config.macros.br.handler = function(place)
{
	createTiddlyElement(place,"br");
};

// Find an entry in an array. Returns the array index or null
// @Deprecated: Use indexOf instead
Array.prototype.find = function(item)
{
	var i = this.indexOf(item);
	return i == -1 ? null : i;
};

// Load a tiddler from an HTML DIV. The caller should make sure to later call Tiddler.changed()
// @Deprecated: Use store.getLoader().internalizeTiddler instead
Tiddler.prototype.loadFromDiv = function(divRef,title)
{
	return store.getLoader().internalizeTiddler(store,this,title,divRef);
};

// Format the text for storage in an HTML DIV
// @Deprecated Use store.getSaver().externalizeTiddler instead.
Tiddler.prototype.saveToDiv = function()
{
	return store.getSaver().externalizeTiddler(store,this);
};

// @Deprecated: Use store.allTiddlersAsHtml() instead
function allTiddlersAsHtml()
{
	return store.allTiddlersAsHtml();
}

// @Deprecated: Use refreshPageTemplate instead
function applyPageTemplate(title)
{
	refreshPageTemplate(title);
}

// @Deprecated: Use story.displayTiddlers instead
function displayTiddlers(srcElement,titles,template,unused1,unused2,animate,unused3)
{
	story.displayTiddlers(srcElement,titles,template,animate);
}

// @Deprecated: Use story.displayTiddler instead
function displayTiddler(srcElement,title,template,unused1,unused2,animate,unused3)
{
	story.displayTiddler(srcElement,title,template,animate);
}

// @Deprecated: Use functions on right hand side directly instead
var createTiddlerPopup = Popup.create;
var scrollToTiddlerPopup = Popup.show;
var hideTiddlerPopup = Popup.remove;

// @Deprecated: Use right hand side directly instead
var regexpBackSlashEn = new RegExp("\\\\n","mg");
var regexpBackSlash = new RegExp("\\\\","mg");
var regexpBackSlashEss = new RegExp("\\\\s","mg");
var regexpNewLine = new RegExp("\n","mg");
var regexpCarriageReturn = new RegExp("\r","mg");

}
//}}}
!Directed Evolution Script:
The script and the tool class files can be downloaded below. They are presented in [[Lecture 02|L02.05]]. 

//(These are version #02 files compatible with rpy2)//
[[DirectedEvo.py|02/DirectedEvo02.py]]
[[DirectedEvoTools.py|02/DirectedEvoTools02.py]]

These files generate frequency distribution plots for the number of generations required to "evolve" a specific string target AND a summary plot of the average generation times across all Nmer sequence lengths tested.
<html><table><tr>
<td><img src="02/00-DataPlot-ALL-GATC.png" style="height:200px"></td>
<td><img src="02/00-DistributionPlot-002500-GATC.png" style="height:200px"></td>
</tr></table></html>

!

!Basic Genetic Algorithm Script:
The script and the tool class files can be downloaded below. They are presented in [[Lecture 03|L03]]. 

//(These version files do not require rpy2)//
[[DirectedGA01.py|03/DirectedGA01.py]]
[[DirectedGATools01.py|03/DirectedGATools1.py]]

These files solve a simple algebraic problem: given a fixed number of factors and a target amount, find the combination of factors whose product is equal to the target. The progress of the script while running is an xy plot of the current functional score of the i^^th^^ generation factors plotted against generation number.
<html>
<img src="03/ScorePlotExample.png" style="height:300px">
</html>

!

/***
|!''Name:''|!''E''asily ''A''daptable ''S''ource ''E''ditor|
|''Description:''|this framework allows you to easily create commands that work on the current tiddler text selection in edit mode|
|''Version:''|0.1.0|
|''Date:''|13/01/2007|
|''Source:''|http://yann.perrin.googlepages.com/twkd.html#E.A.S.E|
|''Author:''|[[Yann Perrin|YannPerrin]]|
|''License:''|[[BSD open source license]]|
|''~CoreVersion:''|2.x|
|''Browser:''|Firefox 1.0.4+; Firefox 1.5; InternetExplorer 6.0|
***/
////Messages Definition
//{{{
config.messages.Ease = {
noselection:"nothing selected",
asktitle:"enter the new tiddler title",
exists:" already exists, please enter another title",
askForTagsLabel:"enter the new tiddler tags",
tiddlercreated:" tiddler created"
}
//}}}
////
//{{{
if (!window.TWkd) window.TWkd={context:{}};
if (!TWkd.Ease)
 TWkd.Ease = function (text,tooltip){
 this.text = text;
 this.tooltip = tooltip;
 this.modes = [];
 this.addMode = function(modeDefinition) {this.modes.push(modeDefinition);};
 this.handler = function(event,src,title) {
 TWkd.context.command = this;
 TWkd.context.selection=this.getSelection(title);
 if (this.modes.length==1) {
 this.modes[0].operation();
 }
 else {
 var popup = Popup.create(src);
 if(popup) {
 for (var i=0; i<this.modes.length; i++) {
 createTiddlyButton(createTiddlyElement(popup,"li"), this.modes[i].name, this.modes[i].tooltip, this.OperateFromButton, null, 'id'+i, null);
 }
 Popup.show(popup,false);
 event.cancelBubble = true;
 if (event.stopPropagation) event.stopPropagation();
 return false;
 }
 }
 };
 };

TWkd.Ease.prototype.OperateFromButton = function(e){
 var commandMode=this.getAttribute('Id').replace('id','');
 TWkd.context.command.modes[commandMode].operation();
};

TWkd.Ease.prototype.getTiddlerEditField = function(title,field){
 var tiddler = document.getElementById(story.idPrefix + title);
 if(tiddler != null){
 var children = tiddler.getElementsByTagName("*")
 var e = null;
 for (var t=0; t<children.length; t++){
 var c = children[t];
 if(c.tagName.toLowerCase() == "input" || c.tagName.toLowerCase() == "textarea"){
 if(!e) {e = c;}
 if(c.getAttribute("edit") == field){e = c;}
 }
 }
 if(e){return e;}
 }
} // closes getTiddlerEditField function definition
 
TWkd.Ease.prototype.getSelection = function(title,quiet) {
 var tiddlerTextArea = this.getTiddlerEditField(title,"text");
 var result = {};
 if (document.selection != null && tiddlerTextArea.selectionStart == null) {
 tiddlerTextArea.focus();
 var range = document.selection.createRange();
 var bookmark = range.getBookmark();
 var contents = tiddlerTextArea.value;
 var originalContents = contents;
 var marker = "##SELECTION_MARKER_" + Math.random() + "##";
 while(contents.indexOf(marker) != -1) {
 marker = "##SELECTION_MARKER_" + Math.random() + "##";
 }
 var selection = range.text;
 range.text = marker + range.text + marker;
 contents = tiddlerTextArea.value;
 result.start = contents.indexOf(marker);
 contents = contents.replace(marker, "");
 result.end = contents.indexOf(marker);
 tiddlerTextArea.value = originalContents;
 range.moveToBookmark(bookmark);
 range.select();
 }
 else {
 result.start=tiddlerTextArea.selectionStart;
 result.end=tiddlerTextArea.selectionEnd;
 }
 result.content=tiddlerTextArea.value.substring(result.start,result.end);
 result.source=title;
 if (!result.content&&!quiet) displayMessage(config.messages.Ease.noselection);
 return(result);
}//closes getSelection function definition

// replace selection or insert new content
TWkd.Ease.prototype.putInPlace=function(content,workplace) {
 var tiddlerText = this.getTiddlerEditField(workplace.source,"text");
 tiddlerText.value = tiddlerText.value.substring(0,workplace.start)+content+tiddlerText.value.substring(workplace.end);
}

// asking for title
TWkd.Ease.prototype.askForTitle = function(suggestion) {
 if (!suggestion)
 suggestion = "";
 var newtitle;
 while (!newtitle||store.tiddlerExists(newtitle))
 {
 if (store.tiddlerExists(newtitle))
 displayMessage(newtitle+config.messages.Ease.exists);
 newtitle = prompt(config.messages.Ease.asktitle,suggestion);
 if (newtitle==null)
 {
 displayMessage(config.messages.Ease.titlecancel);
 return(false);
 }
 }
 return(newtitle);
}//closes askForTitle function definition

// creation of a new tiddler
TWkd.Ease.prototype.newTWkdLibTiddler = function(title,content,from,askForTags){
 var tiddler = new Tiddler();
 tiddler.title = title;
 tiddler.modifier = config.options.txtUserName;
 tiddler.text = content;
 (from) ? tiddler.tags = [from] : tiddler.tags=[];
 if (askForTags)
 tiddler.tags = prompt(config.messages.Ease.askForTagsLabel,'[['+from+']]').readBracketedList();
 store.addTiddler(tiddler);
 //store.notifyAll();
 displayMessage(title+config.messages.Ease.tiddlercreated);
}

if (!TWkd.Mode)
 TWkd.Mode = function (name,tooltip,ask,operation) {
 this.name = name;
 this.tooltip = tooltip;
 this.ask = ask;
 this.operation = operation;
 };
//}}}
<div class="toolbar" macro="toolbar +saveTiddler closeOthers -cancelTiddler deleteTiddler"></div>
<div class="title" macro="view title"></div>
<div class="editLabel">Title</div><div class="editor" macro="edit title"></div>
<div class="editLabel">Tags</div><div class="editor" macro="edit tags"></div>
<div class="editorFooter"><span macro="message views.editor.tagPrompt"></span><span macro="tagChooser"></span></div>
<div macro='hideWhen ((tiddler.tags.contains("Contacts"))||(tiddler.title=="New Contact"))'>[[EditToolbar]]<div class='editor' macro='edit text'></div></div>
<div macro='showWhen ((tiddler.tags.contains("Contacts"))||(tiddler.title=="New Contact"))'><div class='editor'>
<table width='100%'>
<tr><th>Name</th><td><span macro='edit ContactFirstName'></span><span macro='edit ContactLastName'></span></td><td rowspan='4' width='50%' macro='edit text'></td></tr>
<tr><th>Adress</th><td><span macro='edit ContactStreetNumber'></span><span macro='edit ContactStreetName'></span><span macro='edit ContactZipCode'></span><span macro='edit ContactCity'></span></td></tr>
<tr><th>Phone</th><td><span macro='edit ContactPhone'></span></td></tr>
<tr><th>Email</th><td><span macro='edit ContactMail'><span></td></tr>
</table>
</div></div>
<div macro='toolbar Format Greek Hebrew Indent Notes Color Highlighting Tables'></div>
[[BACK to Resources|Resource Index]]
!!!
!~Mark-Up Script Editors:
!!!1. Java Edit
''jEdit'' is a feature-rich programmer's text editor built on Java that will run on all computers with JRE (java runtime environment). To download, install, and set up jEdit as quickly and painlessly as possible, go to the [[Quick Start page | http://www.jedit.org/index.php?page=quickstart]].
<html><img src="00/jedit.png" style="height:300px"></html>

!!!2. Crimson Editor
''CE'' is a syntax mark-up editor for MS Windows. Folder navigation is pretty easy using this tool. It can be setup as a pass-through interface to the command terminal so running and editing scripts can all be done in one GUI. To download and install got to [[Crimson Editor | http://www.crimsoneditor.com/]].
<html><img src="00/crimsonedit.png" style="height:300px"></html>

!!!3. Komodo
''KOMODO EDIT'' is a feature code editor from Active State. They sell a high-octane version of the editor Komodo-IDE which is geared to professional coders. The freeware version Komodo-Editor still has more features than you will ever probably require.  To download and install got to [[Komodo | http://www.activestate.com/Products/]], and select ''Komodo-Edit'', not ''Komodo-IDE''.
<html><img src="00/komodo.png" style="height:300px"></html>

!!!4. Vim
Vim is a highly configurable text editor built to enable efficient text editing. It is an improved version of the vi editor distributed with most UNIX systems. Vim is often called a "programmer's editor," and so useful for programming that many consider it an entire IDE. It's not just for programmers, though. Vim is perfect for all kinds of text editing, from composing email to editing configuration files. Vim can be configured to work in a very simple (Notepad-like) way, called evim or Easy Vim.
[[VIM download|http://www.vim.org/index.php]]
!
[[BACK to Lecture 1|L01.06]]
!!!
!Entropy
''ENTROPY'' is a concept to describe the information content of a system given different states of organization. It is borrowed by molecular biologists to describe the "organization" of sequence information. The idea of information entropy was first developed for telecommunications by: Shannon and Weaver, 1949, "The mathematical theory of communication," University of Illinois Press, Chicago.

The idea is that the more information you have about a system, the more certain you are about the current state of that system. The Shannon-Weaver entropy statistics works by a fairly simple summation of the probability states of any system to establish a metric that represents how much you DON'T know about that system. Yes, it is an inverse measure in that the greater the system entropy value, the more complex a system is, and consequently there's more that you don't know about it.

Example 1: From Dweyer's __Genomic PERL__, let's say there is a 90% chance of rain today, a 9% chance of overcast clouds but no rain, and a 1% chance of partly cloudy, sunny skies, with no rain. This weather "system" has the following potential probabilities: 

''WEATHER~~system1~~ = [//p//(Rain), //p//(Clouds), //p//(Sun)] = [0.90, 0.09, 0.01]''

If you heard this information on the radio when you woke up, you would likely make an immediate mental note to bring an umbrella or wear a rain jacket when you left home. If however the forecast was for 33% chance of rain and a 34% chance of overcast skies with no rain and a 33% chance of partly cloudy, sunny skies, with no rain, then you would not be so quick to conclude that you needed an umbrella today. 

''WEATHER~~system2~~ = [//p//(Rain), //p//(Clouds), //p//(Sun)] = [0.33, 0.34, 0.33]''

To make a correct decision about whether or not to bring an umbrella you would need to access more weather data (doppler radar, etc.) to better ascertain.

So these two weather states have very different levels of predictability or complexity or entropy. We generally calculate an entropy statistic as the summation of the probability of each possible state (//p//~~i~~) multiplied by the natural log of that probability:
''H'' = -1 * Ln( (//p//~~i~~ ^^//p//~~i~~^^)! )    //#(remember ! = factorial)//
| ''H'' = -1 * sum (//p//~~i~~ * Ln(//p//~~i~~)  |

''H''-WEATHER~~system1~~ = -1 * ( (0.90 * -0.11) + (0.09 * -2.41) + (0.01 * -4.61) ) = __0.157__
''H''-WEATHER~~system2~~ = -1 * ( (0.33 * -1.11) + (0.34 * -1.08) + (0.33 * -1.11) ) = __1.099__

So if we compare the entropy numbers, the larger value for WEATHER~~system2~~ is interpreted to mean that there is more uncertainty about whether or not it will rain or shine on this day. The high number value means that it is more complex of a decision to ascertain the true state of the weather for day 2. 

| In Bioinformatics you will often be faced with problems of trying to predict something about a DNA sequence base solely on the probabilities that nucloetide bases will be present at different frequencies. |

!
/***
|Name|FontSizePlugin|
|Created by|SaqImtiaz|
|Location|http://tw.lewcid.org/#FontSizePlugin|
|Version|1.0|
|Requires|~TW2.x|
!Description:
Resize tiddler text on the fly. The text size is remembered between sessions by use of a cookie.
You can customize the maximum and minimum allowed sizes.
(only affects tiddler content text, not any other text)

Also, you can load a TW file with a font-size specified in the url.
Eg: http://tw.lewcid.org/#font:110

!Demo:
Try using the font-size buttons in the sidebar, or in the MainMenu above.

!Installation:
Copy the contents of this tiddler to your TW, tag with systemConfig, save and reload your TW.
Then put {{{<<fontSize "font-size:">>}}} in your SideBarOptions tiddler, or anywhere else that you might like.

!Usage
{{{<<fontSize>>}}} results in <<fontSize>>
{{{<<fontSize font-size: >>}}} results in <<fontSize font-size:>>

!Customizing:
The buttons and prefix text are wrapped in a span with class fontResizer, for easy css styling.
To change the default font-size, and the maximum and minimum font-size allowed, edit the config.fontSize.settings section of the code below.

!Notes:
This plugin assumes that the initial font-size is 100% and then increases or decreases the size by 10%. This stepsize of 10% can also be customized.

!History:
*27-07-06, version 1.0 : prevented double clicks from triggering editing of containing tiddler.
*25-07-06,  version 0.9

!Code
***/

//{{{
config.fontSize={};

//configuration settings
config.fontSize.settings =
{
            defaultSize : 100,  // all sizes in %
            maxSize : 200,
            minSize : 40,
            stepSize : 10
};

//startup code
var fontSettings = config.fontSize.settings;

if (!config.options.txtFontSize)
            {config.options.txtFontSize = fontSettings.defaultSize;
            saveOptionCookie("txtFontSize");}
setStylesheet(".tiddler .viewer {font-size:"+config.options.txtFontSize+"%;}\n","fontResizerStyles");
setStylesheet("#contentWrapper .fontResizer .button {display:inline;font-size:105%; font-weight:bold; margin:0 1px; padding: 0 3px; text-align:center !important;}\n .fontResizer {margin:0 0.5em;}","fontResizerButtonStyles");

//macro
config.macros.fontSize={};
config.macros.fontSize.handler = function (place,macroName,params,wikifier,paramString,tiddler)
{

               var sp = createTiddlyElement(place,"span",null,"fontResizer");
               sp.ondblclick=this.onDblClick;
               if (params[0])
                           createTiddlyText(sp,params[0]);
               createTiddlyButton(sp,"+","increase font-size",this.incFont);
               createTiddlyButton(sp,"=","reset font-size",this.resetFont);
               createTiddlyButton(sp,"–","decrease font-size",this.decFont);
}

config.macros.fontSize.onDblClick = function (e)
{
             if (!e) var e = window.event;
             e.cancelBubble = true;
             if (e.stopPropagation) e.stopPropagation();
             return false;
}

config.macros.fontSize.setFont = function ()
{
               saveOptionCookie("txtFontSize");
               setStylesheet(".tiddler .viewer {font-size:"+config.options.txtFontSize+"%;}\n","fontResizerStyles");
}

config.macros.fontSize.incFont=function()
{
               if (config.options.txtFontSize < fontSettings.maxSize)
                  config.options.txtFontSize = (config.options.txtFontSize*1)+fontSettings.stepSize;
               config.macros.fontSize.setFont();
}

config.macros.fontSize.decFont=function()
{

               if (config.options.txtFontSize > fontSettings.minSize)
                  config.options.txtFontSize = (config.options.txtFontSize*1) - fontSettings.stepSize;
               config.macros.fontSize.setFont();
}

config.macros.fontSize.resetFont=function()
{

               config.options.txtFontSize=fontSettings.defaultSize;
               config.macros.fontSize.setFont();
}

config.paramifiers.font =
{
               onstart: function(v)
                  {
                   config.options.txtFontSize = v;
                   config.macros.fontSize.setFont();
                  }
};
//}}}
/***
|''Name:''|ForEachTiddlerPlugin|
|''Version:''|1.0.8 (2007-04-12)|
|''Source:''|http://tiddlywiki.abego-software.de/#ForEachTiddlerPlugin|
|''Author:''|UdoBorkowski (ub [at] abego-software [dot] de)|
|''Licence:''|[[BSD open source license (abego Software)|http://www.abego-software.de/legal/apl-v10.html]]|
|''Copyright:''|&copy; 2005-2007 [[abego Software|http://www.abego-software.de]]|
|''TiddlyWiki:''|1.2.38+, 2.0|
|''Browser:''|Firefox 1.0.4+; Firefox 1.5; InternetExplorer 6.0|
!Description

Create customizable lists, tables etc. for your selections of tiddlers. Specify the tiddlers to include and their order through a powerful language.

''Syntax:'' 
|>|{{{<<}}}''forEachTiddler'' [''in'' //tiddlyWikiPath//] [''where'' //whereCondition//] [''sortBy'' //sortExpression// [''ascending'' //or// ''descending'']] [''script'' //scriptText//] [//action// [//actionParameters//]]{{{>>}}}|
|//tiddlyWikiPath//|The filepath to the TiddlyWiki the macro should work on. When missing the current TiddlyWiki is used.|
|//whereCondition//|(quoted) JavaScript boolean expression. May refer to the build-in variables {{{tiddler}}} and  {{{context}}}.|
|//sortExpression//|(quoted) JavaScript expression returning "comparable" objects (using '{{{<}}}','{{{>}}}','{{{==}}}'. May refer to the build-in variables {{{tiddler}}} and  {{{context}}}.|
|//scriptText//|(quoted) JavaScript text. Typically defines JavaScript functions that are called by the various JavaScript expressions (whereClause, sortClause, action arguments,...)|
|//action//|The action that should be performed on every selected tiddler, in the given order. By default the actions [[addToList|AddToListAction]] and [[write|WriteAction]] are supported. When no action is specified [[addToList|AddToListAction]]  is used.|
|//actionParameters//|(action specific) parameters the action may refer while processing the tiddlers (see action descriptions for details). <<tiddler [[JavaScript in actionParameters]]>>|
|>|~~Syntax formatting: Keywords in ''bold'', optional parts in [...]. 'or' means that exactly one of the two alternatives must exist.~~|

See details see [[ForEachTiddlerMacro]] and [[ForEachTiddlerExamples]].

!Revision history
* v1.0.8 (2007-04-12)
** Adapted to latest TiddlyWiki 2.2 Beta importTiddlyWiki API (introduced with changeset 2004). TiddlyWiki 2.2 Beta builds prior to changeset 2004 are no longer supported (but TiddlyWiki 2.1 and earlier, of cause)
* v1.0.7 (2007-03-28)
** Also support "pre" formatted TiddlyWikis (introduced with TW 2.2) (when using "in" clause to work on external tiddlers)
* v1.0.6 (2006-09-16)
** Context provides "viewerTiddler", i.e. the tiddler used to view the macro. Most times this is equal to the "inTiddler", but when using the "tiddler" macro both may be different.
** Support "begin", "end" and "none" expressions in "write" action
* v1.0.5 (2006-02-05)
** Pass tiddler containing the macro with wikify, context object also holds reference to tiddler containing the macro ("inTiddler"). Thanks to SimonBaird.
** Support Firefox 1.5.0.1
** Internal
*** Make "JSLint" conform
*** "Only install once"
* v1.0.4 (2006-01-06)
** Support TiddlyWiki 2.0
* v1.0.3 (2005-12-22)
** Features: 
*** Write output to a file supports multi-byte environments (Thanks to Bram Chen) 
*** Provide API to access the forEachTiddler functionality directly through JavaScript (see getTiddlers and performMacro)
** Enhancements:
*** Improved error messages on InternetExplorer.
* v1.0.2 (2005-12-10)
** Features: 
*** context object also holds reference to store (TiddlyWiki)
** Fixed Bugs: 
*** ForEachTiddler 1.0.1 has broken support on win32 Opera 8.51 (Thanks to BrunoSabin for reporting)
* v1.0.1 (2005-12-08)
** Features: 
*** Access tiddlers stored in separated TiddlyWikis through the "in" option. I.e. you are no longer limited to only work on the "current TiddlyWiki".
*** Write output to an external file using the "toFile" option of the "write" action. With this option you may write your customized tiddler exports.
*** Use the "script" section to define "helper" JavaScript functions etc. to be used in the various JavaScript expressions (whereClause, sortClause, action arguments,...).
*** Access and store context information for the current forEachTiddler invocation (through the build-in "context" object) .
*** Improved script evaluation (for where/sort clause and write scripts).
* v1.0.0 (2005-11-20)
** initial version

!Code
***/
//{{{

	
//============================================================================
//============================================================================
//		   ForEachTiddlerPlugin
//============================================================================
//============================================================================

// Only install once
if (!version.extensions.ForEachTiddlerPlugin) {

if (!window.abego) window.abego = {};

version.extensions.ForEachTiddlerPlugin = {
	major: 1, minor: 0, revision: 8, 
	date: new Date(2007,3,12), 
	source: "http://tiddlywiki.abego-software.de/#ForEachTiddlerPlugin",
	licence: "[[BSD open source license (abego Software)|http://www.abego-software.de/legal/apl-v10.html]]",
	copyright: "Copyright (c) abego Software GmbH, 2005-2007 (www.abego-software.de)"
};

// For backward compatibility with TW 1.2.x
//
if (!TiddlyWiki.prototype.forEachTiddler) {
	TiddlyWiki.prototype.forEachTiddler = function(callback) {
		for(var t in this.tiddlers) {
			callback.call(this,t,this.tiddlers[t]);
		}
	};
}

//============================================================================
// forEachTiddler Macro
//============================================================================

version.extensions.forEachTiddler = {
	major: 1, minor: 0, revision: 8, date: new Date(2007,3,12), provider: "http://tiddlywiki.abego-software.de"};

// ---------------------------------------------------------------------------
// Configurations and constants 
// ---------------------------------------------------------------------------

config.macros.forEachTiddler = {
	 // Standard Properties
	 label: "forEachTiddler",
	 prompt: "Perform actions on a (sorted) selection of tiddlers",

	 // actions
	 actions: {
		 addToList: {},
		 write: {}
	 }
};

// ---------------------------------------------------------------------------
//  The forEachTiddler Macro Handler 
// ---------------------------------------------------------------------------

config.macros.forEachTiddler.getContainingTiddler = function(e) {
	while(e && !hasClass(e,"tiddler"))
		e = e.parentNode;
	var title = e ? e.getAttribute("tiddler") : null; 
	return title ? store.getTiddler(title) : null;
};

config.macros.forEachTiddler.handler = function(place,macroName,params,wikifier,paramString,tiddler) {
	// config.macros.forEachTiddler.traceMacroCall(place,macroName,params,wikifier,paramString,tiddler);

	if (!tiddler) tiddler = config.macros.forEachTiddler.getContainingTiddler(place);
	// --- Parsing ------------------------------------------

	var i = 0; // index running over the params
	// Parse the "in" clause
	var tiddlyWikiPath = undefined;
	if ((i < params.length) && params[i] == "in") {
		i++;
		if (i >= params.length) {
			this.handleError(place, "TiddlyWiki path expected behind 'in'.");
			return;
		}
		tiddlyWikiPath = this.paramEncode((i < params.length) ? params[i] : "");
		i++;
	}

	// Parse the where clause
	var whereClause ="true";
	if ((i < params.length) && params[i] == "where") {
		i++;
		whereClause = this.paramEncode((i < params.length) ? params[i] : "");
		i++;
	}

	// Parse the sort stuff
	var sortClause = null;
	var sortAscending = true; 
	if ((i < params.length) && params[i] == "sortBy") {
		i++;
		if (i >= params.length) {
			this.handleError(place, "sortClause missing behind 'sortBy'.");
			return;
		}
		sortClause = this.paramEncode(params[i]);
		i++;

		if ((i < params.length) && (params[i] == "ascending" || params[i] == "descending")) {
			 sortAscending = params[i] == "ascending";
			 i++;
		}
	}

	// Parse the script
	var scriptText = null;
	if ((i < params.length) && params[i] == "script") {
		i++;
		scriptText = this.paramEncode((i < params.length) ? params[i] : "");
		i++;
	}

	// Parse the action. 
	// When we are already at the end use the default action
	var actionName = "addToList";
	if (i < params.length) {
	   if (!config.macros.forEachTiddler.actions[params[i]]) {
			this.handleError(place, "Unknown action '"+params[i]+"'.");
			return;
		} else {
			actionName = params[i]; 
			i++;
		}
	} 
	
	// Get the action parameter
	// (the parsing is done inside the individual action implementation.)
	var actionParameter = params.slice(i);


	// --- Processing ------------------------------------------
	try {
		this.performMacro({
				place: place, 
				inTiddler: tiddler,
				whereClause: whereClause, 
				sortClause: sortClause, 
				sortAscending: sortAscending, 
				actionName: actionName, 
				actionParameter: actionParameter, 
				scriptText: scriptText, 
				tiddlyWikiPath: tiddlyWikiPath});

	} catch (e) {
		this.handleError(place, e);
	}
};

// Returns an object with properties "tiddlers" and "context".
// tiddlers holds the (sorted) tiddlers selected by the parameter,
// context the context of the execution of the macro.
//
// The action is not yet performed.
//
// @parameter see performMacro
//
config.macros.forEachTiddler.getTiddlersAndContext = function(parameter) {

	var context = config.macros.forEachTiddler.createContext(parameter.place, parameter.whereClause, parameter.sortClause, parameter.sortAscending, parameter.actionName, parameter.actionParameter, parameter.scriptText, parameter.tiddlyWikiPath, parameter.inTiddler);

	var tiddlyWiki = parameter.tiddlyWikiPath ? this.loadTiddlyWiki(parameter.tiddlyWikiPath) : store;
	context["tiddlyWiki"] = tiddlyWiki;
	
	// Get the tiddlers, as defined by the whereClause
	var tiddlers = this.findTiddlers(parameter.whereClause, context, tiddlyWiki);
	context["tiddlers"] = tiddlers;

	// Sort the tiddlers, when sorting is required.
	if (parameter.sortClause) {
		this.sortTiddlers(tiddlers, parameter.sortClause, parameter.sortAscending, context);
	}

	return {tiddlers: tiddlers, context: context};
};

// Returns the (sorted) tiddlers selected by the parameter.
//
// The action is not yet performed.
//
// @parameter see performMacro
//
config.macros.forEachTiddler.getTiddlers = function(parameter) {
	return this.getTiddlersAndContext(parameter).tiddlers;
};

// Performs the macros with the given parameter.
//
// @param parameter holds the parameter of the macro as separate properties.
//				  The following properties are supported:
//
//						place
//						whereClause
//						sortClause
//						sortAscending
//						actionName
//						actionParameter
//						scriptText
//						tiddlyWikiPath
//
//					All properties are optional. 
//					For most actions the place property must be defined.
//
config.macros.forEachTiddler.performMacro = function(parameter) {
	var tiddlersAndContext = this.getTiddlersAndContext(parameter);

	// Perform the action
	var actionName = parameter.actionName ? parameter.actionName : "addToList";
	var action = config.macros.forEachTiddler.actions[actionName];
	if (!action) {
		this.handleError(parameter.place, "Unknown action '"+actionName+"'.");
		return;
	}

	var actionHandler = action.handler;
	actionHandler(parameter.place, tiddlersAndContext.tiddlers, parameter.actionParameter, tiddlersAndContext.context);
};

// ---------------------------------------------------------------------------
//  The actions 
// ---------------------------------------------------------------------------

// Internal.
//
// --- The addToList Action -----------------------------------------------
//
config.macros.forEachTiddler.actions.addToList.handler = function(place, tiddlers, parameter, context) {
	// Parse the parameter
	var p = 0;

	// Check for extra parameters
	if (parameter.length > p) {
		config.macros.forEachTiddler.createExtraParameterErrorElement(place, "addToList", parameter, p);
		return;
	}

	// Perform the action.
	var list = document.createElement("ul");
	place.appendChild(list);
	for (var i = 0; i < tiddlers.length; i++) {
		var tiddler = tiddlers[i];
		var listItem = document.createElement("li");
		list.appendChild(listItem);
		createTiddlyLink(listItem, tiddler.title, true);
	}
};

abego.parseNamedParameter = function(name, parameter, i) {
	var beginExpression = null;
	if ((i < parameter.length) && parameter[i] == name) {
		i++;
		if (i >= parameter.length) {
			throw "Missing text behind '%0'".format([name]);
		}
		
		return config.macros.forEachTiddler.paramEncode(parameter[i]);
	}
	return null;
}

// Internal.
//
// --- The write Action ---------------------------------------------------
//
config.macros.forEachTiddler.actions.write.handler = function(place, tiddlers, parameter, context) {
	// Parse the parameter
	var p = 0;
	if (p >= parameter.length) {
		this.handleError(place, "Missing expression behind 'write'.");
		return;
	}

	var textExpression = config.macros.forEachTiddler.paramEncode(parameter[p]);
	p++;

	// Parse the "begin" option
	var beginExpression = abego.parseNamedParameter("begin", parameter, p);
	if (beginExpression !== null) 
		p += 2;
	var endExpression = abego.parseNamedParameter("end", parameter, p);
	if (endExpression !== null) 
		p += 2;
	var noneExpression = abego.parseNamedParameter("none", parameter, p);
	if (noneExpression !== null) 
		p += 2;

	// Parse the "toFile" option
	var filename = null;
	var lineSeparator = undefined;
	if ((p < parameter.length) && parameter[p] == "toFile") {
		p++;
		if (p >= parameter.length) {
			this.handleError(place, "Filename expected behind 'toFile' of 'write' action.");
			return;
		}
		
		filename = config.macros.forEachTiddler.getLocalPath(config.macros.forEachTiddler.paramEncode(parameter[p]));
		p++;
		if ((p < parameter.length) && parameter[p] == "withLineSeparator") {
			p++;
			if (p >= parameter.length) {
				this.handleError(place, "Line separator text expected behind 'withLineSeparator' of 'write' action.");
				return;
			}
			lineSeparator = config.macros.forEachTiddler.paramEncode(parameter[p]);
			p++;
		}
	}
	
	// Check for extra parameters
	if (parameter.length > p) {
		config.macros.forEachTiddler.createExtraParameterErrorElement(place, "write", parameter, p);
		return;
	}

	// Perform the action.
	var func = config.macros.forEachTiddler.getEvalTiddlerFunction(textExpression, context);
	var count = tiddlers.length;
	var text = "";
	if (count > 0 && beginExpression)
		text += config.macros.forEachTiddler.getEvalTiddlerFunction(beginExpression, context)(undefined, context, count, undefined);
	
	for (var i = 0; i < count; i++) {
		var tiddler = tiddlers[i];
		text += func(tiddler, context, count, i);
	}
	
	if (count > 0 && endExpression)
		text += config.macros.forEachTiddler.getEvalTiddlerFunction(endExpression, context)(undefined, context, count, undefined);

	if (count == 0 && noneExpression) 
		text += config.macros.forEachTiddler.getEvalTiddlerFunction(noneExpression, context)(undefined, context, count, undefined);
		

	if (filename) {
		if (lineSeparator !== undefined) {
			lineSeparator = lineSeparator.replace(/\\n/mg, "\n").replace(/\\r/mg, "\r");
			text = text.replace(/\n/mg,lineSeparator);
		}
		saveFile(filename, convertUnicodeToUTF8(text));
	} else {
		var wrapper = createTiddlyElement(place, "span");
		wikify(text, wrapper, null/* highlightRegExp */, context.inTiddler);
	}
};


// ---------------------------------------------------------------------------
//  Helpers
// ---------------------------------------------------------------------------

// Internal.
//
config.macros.forEachTiddler.createContext = function(placeParam, whereClauseParam, sortClauseParam, sortAscendingParam, actionNameParam, actionParameterParam, scriptText, tiddlyWikiPathParam, inTiddlerParam) {
	return {
		place : placeParam, 
		whereClause : whereClauseParam, 
		sortClause : sortClauseParam, 
		sortAscending : sortAscendingParam, 
		script : scriptText,
		actionName : actionNameParam, 
		actionParameter : actionParameterParam,
		tiddlyWikiPath : tiddlyWikiPathParam,
		inTiddler : inTiddlerParam, // the tiddler containing the <<forEachTiddler ...>> macro call.
		viewerTiddler : config.macros.forEachTiddler.getContainingTiddler(placeParam) // the tiddler showing the forEachTiddler result
	};
};

// Internal.
//
// Returns a TiddlyWiki with the tiddlers loaded from the TiddlyWiki of 
// the given path.
//
config.macros.forEachTiddler.loadTiddlyWiki = function(path, idPrefix) {
	if (!idPrefix) {
		idPrefix = "store";
	}
	var lenPrefix = idPrefix.length;
	
	// Read the content of the given file
	var content = loadFile(this.getLocalPath(path));
	if(content === null) {
		throw "TiddlyWiki '"+path+"' not found.";
	}
	
	var tiddlyWiki = new TiddlyWiki();

	// Starting with TW 2.2 there is a helper function to import the tiddlers
	if (tiddlyWiki.importTiddlyWiki) {
		if (!tiddlyWiki.importTiddlyWiki(content))
			throw "File '"+path+"' is not a TiddlyWiki.";
		tiddlyWiki.dirty = false;
		return tiddlyWiki;
	}
	
	// The legacy code, for TW < 2.2
	
	// Locate the storeArea div's
	var posOpeningDiv = content.indexOf(startSaveArea);
	var posClosingDiv = content.lastIndexOf(endSaveArea);
	if((posOpeningDiv == -1) || (posClosingDiv == -1)) {
		throw "File '"+path+"' is not a TiddlyWiki.";
	}
	var storageText = content.substr(posOpeningDiv + startSaveArea.length, posClosingDiv);
	
	// Create a "div" element that contains the storage text
	var myStorageDiv = document.createElement("div");
	myStorageDiv.innerHTML = storageText;
	myStorageDiv.normalize();
	
	// Create all tiddlers in a new TiddlyWiki
	// (following code is modified copy of TiddlyWiki.prototype.loadFromDiv)
	var store = myStorageDiv.childNodes;
	for(var t = 0; t < store.length; t++) {
		var e = store[t];
		var title = null;
		if(e.getAttribute)
			title = e.getAttribute("tiddler");
		if(!title && e.id && e.id.substr(0,lenPrefix) == idPrefix)
			title = e.id.substr(lenPrefix);
		if(title && title !== "") {
			var tiddler = tiddlyWiki.createTiddler(title);
			tiddler.loadFromDiv(e,title);
		}
	}
	tiddlyWiki.dirty = false;

	return tiddlyWiki;
};


	
// Internal.
//
// Returns a function that has a function body returning the given javaScriptExpression.
// The function has the parameters:
// 
//	 (tiddler, context, count, index)
//
config.macros.forEachTiddler.getEvalTiddlerFunction = function (javaScriptExpression, context) {
	var script = context["script"];
	var functionText = "var theFunction = function(tiddler, context, count, index) { return "+javaScriptExpression+"}";
	var fullText = (script ? script+";" : "")+functionText+";theFunction;";
	return eval(fullText);
};

// Internal.
//
config.macros.forEachTiddler.findTiddlers = function(whereClause, context, tiddlyWiki) {
	var result = [];
	var func = config.macros.forEachTiddler.getEvalTiddlerFunction(whereClause, context);
	tiddlyWiki.forEachTiddler(function(title,tiddler) {
		if (func(tiddler, context, undefined, undefined)) {
			result.push(tiddler);
		}
	});
	return result;
};

// Internal.
//
config.macros.forEachTiddler.createExtraParameterErrorElement = function(place, actionName, parameter, firstUnusedIndex) {
	var message = "Extra parameter behind '"+actionName+"':";
	for (var i = firstUnusedIndex; i < parameter.length; i++) {
		message += " "+parameter[i];
	}
	this.handleError(place, message);
};

// Internal.
//
config.macros.forEachTiddler.sortAscending = function(tiddlerA, tiddlerB) {
	var result = 
		(tiddlerA.forEachTiddlerSortValue == tiddlerB.forEachTiddlerSortValue) 
			? 0
			: (tiddlerA.forEachTiddlerSortValue < tiddlerB.forEachTiddlerSortValue)
			   ? -1 
			   : +1; 
	return result;
};

// Internal.
//
config.macros.forEachTiddler.sortDescending = function(tiddlerA, tiddlerB) {
	var result = 
		(tiddlerA.forEachTiddlerSortValue == tiddlerB.forEachTiddlerSortValue) 
			? 0
			: (tiddlerA.forEachTiddlerSortValue < tiddlerB.forEachTiddlerSortValue)
			   ? +1 
			   : -1; 
	return result;
};

// Internal.
//
config.macros.forEachTiddler.sortTiddlers = function(tiddlers, sortClause, ascending, context) {
	// To avoid evaluating the sortClause whenever two items are compared 
	// we pre-calculate the sortValue for every item in the array and store it in a 
	// temporary property ("forEachTiddlerSortValue") of the tiddlers.
	var func = config.macros.forEachTiddler.getEvalTiddlerFunction(sortClause, context);
	var count = tiddlers.length;
	var i;
	for (i = 0; i < count; i++) {
		var tiddler = tiddlers[i];
		tiddler.forEachTiddlerSortValue = func(tiddler,context, undefined, undefined);
	}

	// Do the sorting
	tiddlers.sort(ascending ? this.sortAscending : this.sortDescending);

	// Delete the temporary property that holds the sortValue.	
	for (i = 0; i < tiddlers.length; i++) {
		delete tiddlers[i].forEachTiddlerSortValue;
	}
};


// Internal.
//
config.macros.forEachTiddler.trace = function(message) {
	displayMessage(message);
};

// Internal.
//
config.macros.forEachTiddler.traceMacroCall = function(place,macroName,params) {
	var message ="<<"+macroName;
	for (var i = 0; i < params.length; i++) {
		message += " "+params[i];
	}
	message += ">>";
	displayMessage(message);
};


// Internal.
//
// Creates an element that holds an error message
// 
config.macros.forEachTiddler.createErrorElement = function(place, exception) {
	var message = (exception.description) ? exception.description : exception.toString();
	return createTiddlyElement(place,"span",null,"forEachTiddlerError","<<forEachTiddler ...>>: "+message);
};

// Internal.
//
// @param place [may be null]
//
config.macros.forEachTiddler.handleError = function(place, exception) {
	if (place) {
		this.createErrorElement(place, exception);
	} else {
		throw exception;
	}
};

// Internal.
//
// Encodes the given string.
//
// Replaces 
//	 "$))" to ">>"
//	 "$)" to ">"
//
config.macros.forEachTiddler.paramEncode = function(s) {
	var reGTGT = new RegExp("\\$\\)\\)","mg");
	var reGT = new RegExp("\\$\\)","mg");
	return s.replace(reGTGT, ">>").replace(reGT, ">");
};

// Internal.
//
// Returns the given original path (that is a file path, starting with "file:")
// as a path to a local file, in the systems native file format.
//
// Location information in the originalPath (i.e. the "#" and stuff following)
// is stripped.
// 
config.macros.forEachTiddler.getLocalPath = function(originalPath) {
	// Remove any location part of the URL
	var hashPos = originalPath.indexOf("#");
	if(hashPos != -1)
		originalPath = originalPath.substr(0,hashPos);
	// Convert to a native file format assuming
	// "file:///x:/path/path/path..." - pc local file --> "x:\path\path\path..."
	// "file://///server/share/path/path/path..." - FireFox pc network file --> "\\server\share\path\path\path..."
	// "file:///path/path/path..." - mac/unix local file --> "/path/path/path..."
	// "file://server/share/path/path/path..." - pc network file --> "\\server\share\path\path\path..."
	var localPath;
	if(originalPath.charAt(9) == ":") // pc local file
		localPath = unescape(originalPath.substr(8)).replace(new RegExp("/","g"),"\\");
	else if(originalPath.indexOf("file://///") === 0) // FireFox pc network file
		localPath = "\\\\" + unescape(originalPath.substr(10)).replace(new RegExp("/","g"),"\\");
	else if(originalPath.indexOf("file:///") === 0) // mac/unix local file
		localPath = unescape(originalPath.substr(7));
	else if(originalPath.indexOf("file:/") === 0) // mac/unix local file
		localPath = unescape(originalPath.substr(5));
	else // pc network file
		localPath = "\\\\" + unescape(originalPath.substr(7)).replace(new RegExp("/","g"),"\\");	
	return localPath;
};

// ---------------------------------------------------------------------------
// Stylesheet Extensions (may be overridden by local StyleSheet)
// ---------------------------------------------------------------------------
//
setStylesheet(
	".forEachTiddlerError{color: #ffffff;background-color: #880000;}",
	"forEachTiddler");

//============================================================================
// End of forEachTiddler Macro
//============================================================================


//============================================================================
// String.startsWith Function
//============================================================================
//
// Returns true if the string starts with the given prefix, false otherwise.
//
version.extensions["String.startsWith"] = {major: 1, minor: 0, revision: 0, date: new Date(2005,11,20), provider: "http://tiddlywiki.abego-software.de"};
//
String.prototype.startsWith = function(prefix) {
	var n =  prefix.length;
	return (this.length >= n) && (this.slice(0, n) == prefix);
};



//============================================================================
// String.endsWith Function
//============================================================================
//
// Returns true if the string ends with the given suffix, false otherwise.
//
version.extensions["String.endsWith"] = {major: 1, minor: 0, revision: 0, date: new Date(2005,11,20), provider: "http://tiddlywiki.abego-software.de"};
//
String.prototype.endsWith = function(suffix) {
	var n = suffix.length;
	return (this.length >= n) && (this.right(n) == suffix);
};


//============================================================================
// String.contains Function
//============================================================================
//
// Returns true when the string contains the given substring, false otherwise.
//
version.extensions["String.contains"] = {major: 1, minor: 0, revision: 0, date: new Date(2005,11,20), provider: "http://tiddlywiki.abego-software.de"};
//
String.prototype.contains = function(substring) {
	return this.indexOf(substring) >= 0;
};

//============================================================================
// Array.indexOf Function
//============================================================================
//
// Returns the index of the first occurance of the given item in the array or 
// -1 when no such item exists.
//
// @param item [may be null]
//
version.extensions["Array.indexOf"] = {major: 1, minor: 0, revision: 0, date: new Date(2005,11,20), provider: "http://tiddlywiki.abego-software.de"};
//
Array.prototype.indexOf = function(item) {
	for (var i = 0; i < this.length; i++) {
		if (this[i] == item) {
			return i;
		}
	}
	return -1;
};

//============================================================================
// Array.contains Function
//============================================================================
//
// Returns true when the array contains the given item, otherwise false. 
//
// @param item [may be null]
//
version.extensions["Array.contains"] = {major: 1, minor: 0, revision: 0, date: new Date(2005,11,20), provider: "http://tiddlywiki.abego-software.de"};
//
Array.prototype.contains = function(item) {
	return (this.indexOf(item) >= 0);
};

//============================================================================
// Array.containsAny Function
//============================================================================
//
// Returns true when the array contains at least one of the elements 
// of the item. Otherwise (or when items contains no elements) false is returned.
//
version.extensions["Array.containsAny"] = {major: 1, minor: 0, revision: 0, date: new Date(2005,11,20), provider: "http://tiddlywiki.abego-software.de"};
//
Array.prototype.containsAny = function(items) {
	for(var i = 0; i < items.length; i++) {
		if (this.contains(items[i])) {
			return true;
		}
	}
	return false;
};


//============================================================================
// Array.containsAll Function
//============================================================================
//
// Returns true when the array contains all the items, otherwise false.
// 
// When items is null false is returned (even if the array contains a null).
//
// @param items [may be null] 
//
version.extensions["Array.containsAll"] = {major: 1, minor: 0, revision: 0, date: new Date(2005,11,20), provider: "http://tiddlywiki.abego-software.de"};
//
Array.prototype.containsAll = function(items) {
	for(var i = 0; i < items.length; i++) {
		if (!this.contains(items[i])) {
			return false;
		}
	}
	return true;
};


} // of "install only once"

// Used Globals (for JSLint) ==============
// ... DOM
/*global 	document */
// ... TiddlyWiki Core
/*global 	convertUnicodeToUTF8, createTiddlyElement, createTiddlyLink, 
			displayMessage, endSaveArea, hasClass, loadFile, saveFile, 
			startSaveArea, store, wikify */
//}}}


/***
!Licence and Copyright
Copyright (c) abego Software ~GmbH, 2005 ([[www.abego-software.de|http://www.abego-software.de]])

Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:

Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.

Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or other
materials provided with the distribution.

Neither the name of abego Software nor the names of its contributors may be
used to endorse or promote products derived from this software without specific
prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
DAMAGE.
***/

!Format menu
|''bold''|@@highlight@@|
|//italic//|[[hyperlink]]|
|__underline__||
!Greek menu
|{{greek{κλητοι̂ς}}}|{{gkindent{{{gkindent{{{gkindent{κλητοι̂ς}}}}}}}}}|
|{{gkindent{κλητοι̂ς}}}|{{gkindent{{{gkindent{{{gkindent{{{gkindent{κλητοι̂ς}}}}}}}}}}}}|
|{{gkindent{{{gkindent{κλητοι̂ς}}}}}}|{{gkindent{{{gkindent{{{gkindent{{{gkindent{{{gkindent{κλητοι̂ς}}}}}}}}}}}}}}}|
!!Hebrew menu
{{hebrewNoAlign{וַיָּקָם}}}
{{hebrewRightAlign{וַיָּקָם}}}
{{hebAlignAndIndent{וַיָּקָם}}}
{{hebAlignAndIndent{{{hebAlignAndIndent{וַיָּקָם}}}}}}
{{hebAlignAndIndent{{{hebAlignAndIndent{{{hebAlignAndIndent{וַיָּקָם}}}}}}}}}
{{hebAlignAndIndent{{{hebAlignAndIndent{{{hebAlignAndIndent{{{hebAlignAndIndent{וַיָּקָם}}}}}}}}}}}}
{{hebAlignAndIndent{{{hebAlignAndIndent{{{hebAlignAndIndent{{{hebAlignAndIndent{{{hebAlignAndIndent{וַיָּקָם}}}}}}}}}}}}}}}
!Indent menu
{{engindent{Text}}}
{{engindent{{{engindent{Text}}}}}}
{{engindent{{{engindent{{{engindent{Text}}}}}}}}}
{{engindent{{{engindent{{{engindent{{{engindent{Text}}}}}}}}}}}}
{{engindent{{{engindent{{{engindent{{{engindent{{{engindent{Text}}}}}}}}}}}}}}}
!Notes menu
((syntax(add note here))) &#149; ((translation(add note here))) &#149; ((text(add note here))) &#149; ((gram(add note here))) ((Popup: your text here(your popup text here)))
!Color menu
{{red{Red}}} {{blue{Blue}}} {{green{Green}}} {{gold{Gold}}} {{gray{Gray}}} {{magenta{Magenta}}} {{purple{Purple}}} {{teal{Teal}}} {{burgundy{Burgundy}}}
!Highlighting menu
@@bgcolor(#ff6666):Red@@ @@bgcolor(#ccccff):Blue@@ @@Yellow@@ @@bgcolor(#99ff99):Green@@ @@bgcolor(#cc9966):Brown@@ @@bgcolor(#cccc99):Gray@@ @@bgcolor(#ff9933):Orange@@
!Tables menu
Invisible table: {{invisiblecomm{
|!Invisible table header|!Invisible table header|!invisible table header|
|data|data|data|
|data|data|data|
|data|data|data|
}}}
Sortable table:
|sortable|k
|Header1|Header2|Header3|h
|Aa|B3|data7|
|Ab|B2|data2|
|Ac|B1|data8|
Standard table:
|!Header|!Header|!Header|
|data|data|data|
|data|data|data|
|data|data|data|
Table cell colors:
|!Below is a light gray cell|!Below is a dark gray cell|!Below are regular cells|
|bgcolor(#eeeeee):text here|||
||bgcolor(#cccccc):text there||
|||text anywhere|
<html><div style="color: rgb(100, 100, 150); font-family: Monaco;"><big><big><big><b><center>
Environmental/Functional Bioinformatics Research Development
<br>
</b></big>
<br>

MAST 867-010  Spring 2009
<br>
<br>
Dr. Adam G. Marsh<br></big>
<i>College of Marine & Earth Studies</i><br>
<small>email: amarsh-at-udel-dot-edu; office: 645-4367
<br>
</html>
!!!
''COURSE DESCRIPTION:'' MAST867 will focus on developing and implementing an informatics research project for each participant using the data/subject of their choice. Prof. Marsh teaches two introductory courses (one in programming and one in informatics; see links below) and MAST867 is designed to culminate the programming and informatic skills of these students by focusing on a directed bioinformatics research project that is ''hypothesis'' driven. The two courses below are not prerequisites, but it is necessary for students to have some knowledge of programming and some knowledge of using UNIX (linux, os x) systems for MAST867. The format of the course will be class lectures for the first 4 weeks, and then for the remainder of the semester students will consult with Prof. Marsh individually once a week on their research projects. These consultations sessions will involve collaborative editing, writing and debugging code to develop a specific tool/pipeline that each student will need in their research.  At the end of the course students should be capable of some degree of independent work with PERL, PYTHON, or R. Students will also be required to write up a small bioinformatics research paper, which ideally could be incorporated as a chapter/appendix in their dissertation. 

[[MAST667 S08|http://icewater.cms.udel.edu/EnvBioInfo/]]  1 CR Environmental Bioinformatics
[[MAST667 F08|http://icewater.cms.udel.edu/IntroPerl/]]  2 CR PERL Beginning Bioinformatics
!!!
[[BACK to Resources|Resource Index]]
!!!
!National Center Bioinformatics: Genome Database
NCBI is a comprehensive database repository for genetic sequence data. Below are the links to reaching the microbial genomes via http or ftp
!!The Emerald City: http://www.ncbi.nlm.nih.gov/genomes/lproks.cgi
[img[00/ncbi-lproks.png]]
!!The Man Behind The Curtain: ftp://ftp.ncbi.nlm.nih.gov/genomes/Bacteria/
[img[00/ftp-ncbi.png]]

!!!
!Babel Genome Library

# Calculate the amount of hard disk storage space you would need to store a babel library of 3 MB bacterial genomes.

Note: Each ASCII character in a sequence file (as flat text) requires 1 byte of storage.

! 
!Directed model probabilities
Using the MonkeysTyping script:
# Add an iterative loop so that one target string is repeatedly matched 100 times and an average generation count is calculated.
# Add another iterative loop so that 5 different strings varying in length by more than 10 characters is iteratively processed.
# PLOT y-axis = average generation time vs x-axis = number of characters to match
# Add regression line to plot

|@@SEND YOUR DATA PLOT TO ME BY THURSDAY 5:00 PM@@|
!!!

!!!23FEB: Hint 1
Set up the strings you will test as a PERL array:
{{{
my @quotes = qw |
We have nothing to fear but fear itself,
Ask not what your country can do for you but what you can do for your country,
Four score and seven years ago our forefathers setforth to build a new nation dedicated to the proposition that all men are created equal,
|
}}}
Remember that entries in a "quoted word" list (that's what the qw stands for) are separated by a comma, so there can be no commas in the text you enter. Now the outside iteration loop would look like this:
{{{
foreach my $line (@quotes)
{     foreach my $i (0..99)
      {
             #Monkey Typing Goes Here....
      }
      # Calculate MEAN number of bananas here . . .

}
}}}



!
/***
|Name:|HideWhenPlugin|
|Description:|Allows conditional inclusion/exclusion in templates|
|Version:|3.1 ($Rev: 3919 $)|
|Date:|$Date: 2008-03-13 02:03:12 +1000 (Thu, 13 Mar 2008) $|
|Source:|http://mptw.tiddlyspot.com/#HideWhenPlugin|
|Author:|Simon Baird <simon.baird@gmail.com>|
|License:|http://mptw.tiddlyspot.com/#TheBSDLicense|
For use in ViewTemplate and EditTemplate. Example usage:
{{{<div macro="showWhenTagged Task">[[TaskToolbar]]</div>}}}
{{{<div macro="showWhen tiddler.modifier == 'BartSimpson'"><img src="bart.gif"/></div>}}}
***/
//{{{

window.hideWhenLastTest = false;

window.removeElementWhen = function(test,place) {
	window.hideWhenLastTest = test;
	if (test) {
		removeChildren(place);
		place.parentNode.removeChild(place);
	}
};


merge(config.macros,{

	hideWhen: { handler: function(place,macroName,params,wikifier,paramString,tiddler) {
		removeElementWhen( eval(paramString), place);
	}},

	showWhen: { handler: function(place,macroName,params,wikifier,paramString,tiddler) {
		removeElementWhen( !eval(paramString), place);
	}},

	hideWhenTagged: { handler: function (place,macroName,params,wikifier,paramString,tiddler) {
		removeElementWhen( tiddler.tags.containsAll(params), place);
	}},

	showWhenTagged: { handler: function (place,macroName,params,wikifier,paramString,tiddler) {
		removeElementWhen( !tiddler.tags.containsAll(params), place);
	}},

	hideWhenTaggedAny: { handler: function (place,macroName,params,wikifier,paramString,tiddler) {
		removeElementWhen( tiddler.tags.containsAny(params), place);
	}},

	showWhenTaggedAny: { handler: function (place,macroName,params,wikifier,paramString,tiddler) {
		removeElementWhen( !tiddler.tags.containsAny(params), place);
	}},

	hideWhenTaggedAll: { handler: function (place,macroName,params,wikifier,paramString,tiddler) {
		removeElementWhen( tiddler.tags.containsAll(params), place);
	}},

	showWhenTaggedAll: { handler: function (place,macroName,params,wikifier,paramString,tiddler) {
		removeElementWhen( !tiddler.tags.containsAll(params), place);
	}},

	hideWhenExists: { handler: function(place,macroName,params,wikifier,paramString,tiddler) {
		removeElementWhen( store.tiddlerExists(params[0]) || store.isShadowTiddler(params[0]), place);
	}},

	showWhenExists: { handler: function(place,macroName,params,wikifier,paramString,tiddler) {
		removeElementWhen( !(store.tiddlerExists(params[0]) || store.isShadowTiddler(params[0])), place);
	}},

	hideWhenTitleIs: { handler: function(place,macroName,params,wikifier,paramString,tiddler) {
		removeElementWhen( tiddler.title == params[0], place);
	}},

	showWhenTitleIs: { handler: function(place,macroName,params,wikifier,paramString,tiddler) {
		removeElementWhen( tiddler.title != params[0], place);
	}},

	'else': { handler: function(place,macroName,params,wikifier,paramString,tiddler) {
		removeElementWhen( !window.hideWhenLastTest, place);
	}}

});

//}}}

{{{
<html><div style="color: rgb(100, 100, 150); font-family: Monaco;"><big><b>
abcdefghijklmnopqrstuvwxyz
</html>
}}}
/***
|''Name:''|HistoryPlugin|
|''Description:''|Limits to only one tiddler open. Manages an history stack and provides macro to navigate in this history (<<history>><<back>><<forward>>).|
|''Version:''|1.0.0|
|''Date:''|2008-03-23|
|''Source:''|http://tiddlywiki.bidix.info/#HistoryPlugin|
|''Author:''|BidiX (BidiX (at) bidix (dot) info)|
|''[[License]]:''|[[BSD open source license|http://tiddlywiki.bidix.info/#%5B%5BBSD%20open%20source%20license%5D%5D ]]|
|''~CoreVersion:''|2.3.0|
***/
//{{{
	Story.prototype.tiddlerHistory = [];
	Story.prototype.historyCurrentPos = -1;
	Story.prototype.currentTiddler = null;
	Story.prototype.maxPos = 11;

	Story.prototype.old_history_displayTiddler = Story.prototype.displayTiddler;
	Story.prototype.displayTiddler = function(srcElement,title,template,animate,slowly)
	{
		title = ((typeof title === "string") ? title : title.title);
		//SinglePageMode
		if (this.currentTiddler) this.closeTiddler(this.currentTiddler);
		if (template == 2) {
			//switch to Edit mode : don't manage
			story.old_history_displayTiddler(null,title,template,animate,slowly);
			return; 
		}
		// if same tiddler no change
		if (this.tiddlerHistory[this.historyCurrentPos] == title) {
			this.currentTiddler = title;
			story.old_history_displayTiddler(null,title,template,animate,slowly);
			return;
		}
		if (this.historyCurrentPos == this.tiddlerHistory.length -1) {
			// bottom of stack
	    	this.tiddlerHistory.push(title);
		   	if (this.tiddlerHistory.length > 11) {
	                 this.tiddlerHistory.shift();
	       	} else {
		    this.historyCurrentPos += 1;
	            }

		} else {
			// middle of stack
		    this.historyCurrentPos += 1;
			if (this.tiddlerHistory[this.historyCurrentPos] != title) {
				// path change => cut history
				this.tiddlerHistory[this.historyCurrentPos] = title;
				var a = [];
				for(var i = 0; i <= this.historyCurrentPos;i++) {
					a[i] = this.tiddlerHistory[i];
				}
				this.tiddlerHistory = a;
			}
		}
		this.currentTiddler = title;
		story.old_history_displayTiddler(null,title,template,animate,true);
	        scrollTo(0, 1);
	}

	Story.prototype.old_history_closeTiddler = Story.prototype.closeTiddler;
	Story.prototype.closeTiddler = function(title,animate,slowly)
	{
		this.currentTiddler = null;
	    story.old_history_closeTiddler.apply(this,arguments);
	}

	config.macros.history = {};
	config.macros.history.action = function(event) {
	var popup = Popup.create(this);
		if(popup)
			{
	        if (!story.tiddlerHistory.length)
	            createTiddlyText(popup,"No history");
	        else
	           {
	           var c = story.tiddlerHistory.length;
			   for (i=0; i<c;i++ )
	               {
					var elmt = createTiddlyElement(popup,"li");
				   	var btn = createTiddlyButton(elmt,story.tiddlerHistory[i],story.tiddlerHistory[i],config.macros.history.onClick);
					btn.setAttribute("historyPos",i);
			       }
	           }
	        }
		Popup.show(popup,false);
		event.cancelBubble = true;
		if (event.stopPropagation) event.stopPropagation();
		return false;
	}
	config.macros.history.handler = function(place,macroName,params)
	{
		createTiddlyButton(place, 'history', 'history', config.macros.history.action);
	}

	config.macros.history.onClick = function(ev)
	{
		var e = ev ? ev : window.event;
		var historyPos = this.getAttribute("historyPos");
		story.historyCurrentPos = historyPos -1;
		story.displayTiddler(null,story.tiddlerHistory[historyPos]);
		return false;
	};

	config.macros.back = {};
	config.macros.back.action = function() {
	       if (story.historyCurrentPos > 0) {
				if (story.currentTiddler) story.closeTiddler(story.currentTiddler);
				story.historyCurrentPos = story.historyCurrentPos -2;
				story.displayTiddler(null,story.tiddlerHistory[story.historyCurrentPos+1]);
			} else {
				//if (story.currentTiddler) story.old_history_displayTiddler(null,story.currentTiddler);
				};
		return false;
	}
	config.macros.back.handler = function(place,macroName,params)
	{
		createTiddlyButton(place, '<<', 'back', config.macros.back.action,"backButton");
	}

	config.macros.forward = {};
	config.macros.forward.action = function() {
	       if (story.historyCurrentPos < story.tiddlerHistory.length -1) {
				if (story.currentTiddler) story.closeTiddler(story.currentTiddler);
				//story.historyCurrentPos = story.historyCurrentPos;
				story.displayTiddler(null,story.tiddlerHistory[story.historyCurrentPos+1]);
			} else {
				//if (story.currentTiddler) story.old_history_displayTiddler(null,story.currentTiddler);
			}
		return false;
	}
	config.macros.forward.handler = function(place,macroName,params)
	{
		createTiddlyButton(place, '>>', 'forward', config.macros.forward.action, "ibutton");
	}
//}}}
!Assignments:

# HW01: A 3 MB, babel genome library (due 27FEB)
# HW02: Directed model probabilities (due 27FEB)
<!--{{{-->
<div class='toolbar' macro='toolbar closeTiddler closeOthers +editTiddler > fields syncing permalink references jump'></div>
<div class='INTRO' macro='tiddler INTROSubtopicMenu'></div>
<div class='title' macro='view title'></div>
<div class='viewer' macro='view text wikified'></div><div class='tagClear'></div>
<!--}}}-->
{{{
<html><img src="00/xxxx.png" style="height:300px"></html>
}}}

{{{
<html><table><tr>
<td><img src="00/xxxx.png" style="height:300px"></td>
<td><img src="00/xxxx.png" style="height:300px"></td>
</tr></table></html>
}}}
/***
|Name|InlineJavascriptPlugin|
|Source|http://www.TiddlyTools.com/#InlineJavascriptPlugin|
|Documentation|http://www.TiddlyTools.com/#InlineJavascriptPluginInfo|
|Version|1.9.2|
|Author|Eric Shulman - ELS Design Studios|
|License|http://www.TiddlyTools.com/#LegalStatements <br>and [[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]|
|~CoreVersion|2.1|
|Type|plugin|
|Requires||
|Overrides||
|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
<<<
2008.03.03 [1.9.2] corrected declaration of wikifyPlainText() for 'TW 2.1.x compatibility fallback' (fixes Safari "parse error")
2008.02.23 [1.9.1] in onclick function, use string instead of array for 'bufferedHTML' attribute on link element (fixes IE errors)
2008.02.21 [1.9.0] 'onclick' scripts now allow returned text (or document.write() calls) to be wikified into a span that immediately follows the onclick link.  Also, added default 'return false' handling if no return value provided (prevents HREF from being triggered -- return TRUE to allow HREF to be processed).  Thanks to Xavier Verges for suggestion and preliminary code.
|please see [[InlineJavascriptPluginInfo]] for additional revision details|
2005.11.08 [1.0.0] initial release
<<<
!!!!!Code
***/
//{{{
version.extensions.inlineJavascript= {major: 1, minor: 9, revision: 2, date: new Date(2008,3,3)};

config.formatters.push( {
	name: "inlineJavascript",
	match: "\\<script",
	lookahead: "\\<script(?: src=\\\"((?:.|\\n)*?)\\\")?(?: label=\\\"((?:.|\\n)*?)\\\")?(?: title=\\\"((?:.|\\n)*?)\\\")?(?: key=\\\"((?:.|\\n)*?)\\\")?( 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) { // load a script library
				// make script tag, set src, add to body to execute, then remove for cleanup
				var script = document.createElement("script"); script.src = src;
				document.body.appendChild(script); document.body.removeChild(script);
			}
			if (code) { // there is script code
				if (show) // show inline script code in tiddler output
					wikify("{{{\n"+lookaheadMatch[0]+"\n}}}\n",w.output);
				if (label) { // create a link to an 'onclick' script
					// add a link, define click handler, save code in link (pass 'place'), set link attributes
					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){"+fixup+"\n};_out(this);"
					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 inline script code
					var fixup=code.replace(/document.write\s*\(/gi,'place.innerHTML+=(');
					var code="function _out(place){"+fixup+"\n};_out(w.output);"
					try { var out=eval(code); } 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();
}
//}}}
!Basic instructions
#Download the file to your hard drive by [[right-clicking and saving the link / target as...|webviewtw.html]] to the filename and location of your choice. Close this page and open your new file.
#Replace the title in the upper left by editing MainMenu.
#Add topics to MainMenu. Click on those topics to create the tiddlers for those topics. To your uninitiated web viewers they will appear to be separate webpages, but you and I know better!
#Edit DefaultTiddlers to include the names of the tiddlers that you want to appear when the ~TiddlyWiki is opened.
#If you want different colorpalettes than the ones provided, check [[here|http://www.giffmex.org/webviewtwexample.html#MoreColorPalettes!]] for more. Just import them from that file to this file.
#If you want to temporarily suspend the single-page-only feature, I recommend the toggle singlepage mode bookmarklet from ~TiddlyTools [[(link here)|http://www.tiddlytools.com/#InstantBookmarklets.]]
#Upload to your site using the UploadPlugin. [[Instructions here|http://www.giffmex.org/twfortherestofus.html#%5B%5BSimple%20instructions%20for%20BidiX's%20UploadPlugin%5D%5D]]
!Lecture 1: Recombinatorial Diversity
# [[Combinometrics: Library of Babel|L01.00]]
# [[Unimaginable Mathematics|L01.01]]
# [[Babel Library of Genomes?|L01.02]]
# [[Computational Challenge|L01.03]]
# [[Computational Advantage|L01.04]]
# [[Recombinatorial Proofreading|L01.05]]
# [[Emergence/Entropy|L01.06]]
# [[BioInformatics is more than just counting|L01.07]]
# [[Simplified Model Systems|L01.08]]
# [[Babel Gallery|L01.09]]
# [[Genetic Algorithms|L01.10]]
# [[Babel Model|L01.11]]
# [[Shakespeare's Monkeys|L01.12]]
!

<[[BACK|Lecture Index]]|[[NEXT|L01.01]]>
!!!
!Combinometric Diversity

Reading Assignment: [[Library of Babel]]

''Borges:'' keen interests in theology and geometry

//Library of Babel// essay written in 1941 describing the combinometrics of 22 letters and three punctuation characters (space, comma, period). 25 orthographic symbols in the total set of characters.
!!!
Each book is:
{{engindent{410 pages
40 lines per page
80 characters per line}}}

Total characters in a book:  410 x 40 x 80 = 1,312,000 total characters
!!!
How many different books are there?

{{engindent{25^^1,312,000^^}}}
OR
{{engindent{10^^1,834,097^^}}}
(//note: this number is a digit 1 followed by 1,834,097 "0" digits, which is a number too large to even represent within a book of 410 pages x 40 lines per page x 80 characters per line//). 
!!!
   

<[[BACK|L01]]|[[MAIN|L01]]|[[NEXT|L01.02]]>
!!!
!Unimaginable Mathematics
William Goldbloom Bloch, "The Unimaginable Mathematics of Borges' Library of Babel".
<html><img src="01/bookcover.jpg" style="height:300px"></html>

Bloch provides some interesting mathematical insights into the "structure" of Library of Babel. 

''How big would it be?''
1. Assume that you could fit 1000 (10^^3^^) books into one cubic meter. This is an admittedly large over-estimate. 
2. Our known universe is ~1.5 x 10^^26^^ meters across. Round up to again be generous and call it 10^^27^^ meters. 
3. Make a generous estimate of the size of the universe by assuming it is a cube, 10^^27^^ meters on a side, giving a total volume of 10^^81^^ m^^3^^

SO . . . . given a universe of 10^^81^^ m^^3^^ and 10^^3^^ books per m^^3^^, our universe could physically contain 10^^84^^ such books. 

Far short of the 10^^1,834,097^^ total books in the library.

In fact, it would take 10^^1,834,013^^ parallel universes to ours in order to fit all these combinatorial books.

!!!
<[[BACK|L01.01]]|[[MAIN|L01]]|[[NEXT|L01.03]]>
!!!
!Babel Library of Genomes?

Given that there are only 4 DNA nucleotides, would a recombinatorial library of genomes be more manageable?

Imagine such a "GenBank" where every genome that has existed, or now exists, or would exist in the future, would be accessible . . . . if you could find them.

Take an average bacterial genome of 3 MB. 
How many possible genomes would there be?

{{engindent{4^^3,000,000^^}}}
OR
{{engindent{10^^1,806,180^^}}}

How different does this number look to you from: 10^^1,834,097^^

OK, but bacteria are much smaller than books. Assume the average size of a bacterium to be ~ 5 cubic microns  or 5 x10^^-18^^ m^^3^^. Then you could fit ~ 2 x 10^^17^^ bacteria in one m^^3^^. 

In a universe of 10^^81^^ m^^3^^, then you could fit a total of 10^^98^^ bacteria.

(//for scale, remember that the age of our solar system is only 10^^18^^ seconds//)

!!!
<[[BACK|L01.02]]|[[MAIN|L01]]|[[NEXT|L01.04]]>
!!!
!Computational Challenge

As biologists, you are faced with the daunting task of trying to decipher biological patterns in sequence data but with only being able to see a infinitesmally small limited myopic unfocused biased fraction of sequence data.

''BioInformatics:'' discerning patterns of system organization against a background of disorganization. 

//We are all "babel librarians" wandering the stacks, flipping through pages in books looking for signs or hints of sense.//

!!! 

<[[BACK|L01.03]]|[[MAIN|L01]]|[[NEXT|L01.05]]>
!!!
!Computational Advantage

Biological systems are NOT random recombinatorial systems. 

Consider the calculation that there are 10^^1,806,180^^ possible bacterial genomes of 3 MB in size. 

What fraction of that total genome "space" would be occupied by "viable" genomes of bacteria that have existed, or currently exist, or could possibly exist in the future?

Well, if you can only fit 10^^90^^ in the universe, then that would be:

{{engindent{10^^90^^/10^^1,806,180^^ = 10^^-1,806,090^^}}}

Yes, that is a very small fraction, regardless of how rough the estimates above may be.

So biological system organization bypasses all the potential phenotype space. Evolution proceeds down a narrow path . . . . canalization. 

The importance of this simple realization is that we know a GREAT deal about what biological systems are NOT like. We call these random or null models or distributions and our computational goals are basically to statistically test if observed features in a biological system are best described by a null or random process (we attempt to affirm a null hypothesis).

!!!
<[[BACK|L01.04]]|[[MAIN|L01]]|[[NEXT|L01.06]]>
!!!
!Recombinatorial Proofreading

In Bloch's book __The Unimaginable Mathematics of Borges' Library of Babel__, he ends his presentation with a metaphor of the librarian as a Turing machine. A simple, linear processor running through the text of each book programmed only to look for "words." 

So consider a simple system in which a computer program was tasked to parse through the library, looking for books in which all the orthographic entries were "words" determined by matching against a language dictionary (rule 1)?

And if the processing rule was optimized so that when the first non-word was encountered, the rest of the book was skipped (rule 2).

Obviously the task of the Librarian would be greatly accelerated.

If a third rule was imposed to select only those books in which there were no grammatical errors, the search for books with meaning would be even more tightly focused and efficient.

So for biological systems, Natural Selection is like a great Turing machine to efficiently retain only those units that "qualify" as making sense as defined by these 3 simple rules.







  

<[[BACK|L01.05]]|[[MAIN|L01]]|[[NEXT|L01.07]]>
!!!
!Emergence

Complex systems can evolve from simple rule sets (solar systems, mammalian circulatory systems, a squid eye . . . . )

This is possible only when there is an "unimaginable" amount of recombinatorial space (//phenotypes//) that could potentially exist. Then a series of simple rules for parsing or selecting a path through that space has a high probability of "reaching" the end of that path.

In considering how systems are organized, we often use "entropy" as a measure of organization or more succinctly, predictability. 

[[WHAT IS ENTROPY?|Entropy01]]

DNA Sequence Entropy: http://icewater.cms.udel.edu/IntroPerl/#L07


!!!
<[[BACK|L01.06]]|[[MAIN|L01]]|[[NEXT|L01.08]]>
!!!
!BioInformatics is more than just counting

The idea of a Babel Genome Library is intriguing because of the wealth of information it would contain about past life, present life and future life. 

''Home Work Assignment #1: [[HW01]]''  
|@@How big a hard drive would you need to store a Babel Library of 3 MB bacterial genomes?@@|

To make this a more manageable task, what if we devised a filtering algorithm as the genomes were being generated to only allow those that made "sense" into the library? 

What would be the rule set?
What would be gained?
What would be lost?
What would be the size of the final library?
Could you search through it within your life time?
Do you need to search through the whole library?

!
<[[BACK|L01.07]]|[[MAIN|L01]]|[[NEXT|L01.09]]>
!!!
!Simplified Model

!!!Is this LIFE?
^^MSSQNRPLRIYYSRRHRIGECCGTGSRRTPSAGTVVGISTKDLAKKEERDRFRQLFSARLSWDRRTPLICAVAVLIYPTR
IGDEWGTRGAIGPGTGSRAMRDFMGKPEPVQCSSWHRCRRNDTHEMLARSGIIVERCDHDSLDPRSRNERRISNRVVAPVLVPPCLMRN
MKPHLTPGEENRLSLSSQPVRDPTRVGKNPFERGGWNRDPVLRDSPEGRRVLWWEFRVPHTVRTVFRRSQPKYVIYNGSTEMEEH
STFRWLPRGATGAGWLRGRGQKQSMSVRTTPVKTPADGRASAGPPVLMRYRSLGAIGYRYRSINAQIRDG
NRIKRNGPAMLPLQGVGYKQYHRVEIVPLAAGRSSRNSKQMECLISLVMIWVSGLATSIVPALRILTDLDGLLDQAVFHSRRMLR
RTQSCSSHMLELVRCKKCSGRVGMIRGSVPRLSAQICHITLERNTQSPKELDSVRRARTTKTNVETRRWPSMLRFRRPRLP^^
!!!Is This ART?
<html><img src="01/Claude_Monet_Nympheas_Marmottan.jpg" style="height:200px"></html>

!

<[[BACK|L01.08]]|[[MAIN|L01]]|[[NEXT|L01.10]]>
!!!
!Babel Gallery

As a more tangible model of generating a directed library via recombinatorial diversity, consider a babel gallery of images each 80 x 60 pixels in size. 

Each pixel is reproduced as a color tile so the image size is larger. 
Each pixel has three integers that determine color: R, G, B channels
Each channel can hold an integer from 0 to 255.

Inside this gallery, would be a representation of every 2D artwork that has ever been produced and that will ever be produced. All paintings, prints, lithographs, photographs . . . . European, Eastern, Inuit, Roman, Norse,  . . . . 
| @@How many images would be contained in this babel gallery?@@|
!!Randomized Color Map:
<html><img src="01/Babel-090220.png" style="height:400px"></html>
//Is this ART?//

!
<[[BACK|L01.09]]|[[MAIN|L01]]|[[NEXT|L01.11]]>
!!!
!Genetic Algorithms
Class of models for solving computational problems "de novo"

Example: de novo bicycle design http://www.wreck.devisland.net/ga/
<html><img src="01/bicycle-ga.png" style="height:200px"></html>

!!!Simple Logic:
# Create ANCESTOR object
# Ancestor object replicates to form DESCENDANT object
# DESCENDANT object mutates during the replication process
# DESCENDANT object is functionally evaluated
# If DESCENDANT is better than ANCESTOR, then the DESCENDANT becomes the new ANCESTOR of the next generation
# If DESCENDANT is not better than ANCESTOR, it is discarded and the existing ANCESTOR is replicated for the next generation

Run through a million generations, and a very complex, functionally intricate DESCENDANT can evolve from a simple ANCESTOR. 

|@@Although the recombinatorial space may be unimaginable in total, the descendants will trace a single path through the expanse of possibilities@@|
!
<[[BACK|L01.10]]|[[MAIN|L01]]|[[NEXT|L01.12]]>
!!!
!Babel Model
{{{
while(lineage < 40000):    
      # Generate new descendant from ancestor image
      descendant = copy.deepcopy(ancestor)
      descendant.mutate()
      descendant.evaluate()
      if (descendant.cvscore > ancestor.cvscore):
            descendant.save_current_image_data(namestr)
            del(ancestor)
            ancestor = copy.deepcopy(descendant)
            lineage = lineage + 1 
      del(descendant)
}}}

The only tricky part of this model is the "evaluation" function. How do you evaluate an image to decide if it is a better image or not? 

Could use Entropy . . . . 
Could use color pallete . . . . 
Could use . . . . . 

In this implementation, I have just chosen to use a simple metric that scores each pixel for how different the R, G and B values are from the pixels that surround it. The idea is to select for some degree of localized color uniformity.

<html><table><tr>
<td><img src="01/Alpha-090115-start.png" style="height:250px"></td>
<td><img src="01/Alpha-090115-end.png" style="height:250px"></td>
</tr></table></html>
//Final image is generation #940,891//
''Plot of functional scores for each descendant in a lineage''
<html><img src="01/PlotData-MuteScores.png" style="height:300px"></html>

''Image Evolution Examples:''
http://icewater.cms.udel.edu/babel/


!
<[[BACK|L01.11]]|[[MAIN|L01]]>
!!!
!Shakespeare's Monkeys
A different class of models are described as directed selection in which the end-goal is already established and the model is essentially studying the process or mechanics by which that end-goal is achieved.

Simple PERL script to look at how long it would take to randomly fit a given text pattern following the rule that once a character in the evolving string was matched to the target string, it is fixed and stops changing. Code: MonkeysTyping

{{{
----------------------------------------------------------
Would it really take a thousand years for a thousand monkeys 
typing on a thousand typewriters to compose Hamlet's soliloquy?
----------------------------------------------------------
}}}
Enter a starting target string that the monkeys have to type. 
{{{
Here's what you entered:
      F o u r   s c o r e   a n d   s e v e n   y e a r s   
a g o   o u r f o r e f a t h e r s   c r e a t e d   a   
n e w   n a t i o n
}}}
Final count for how many generations it took to match the initial input string:
{{{
It took 256 bananas to find 67 correct letters.
}}}
!

Home Work Assignment #2: HW02
|@@Plot the average number of generations it takes to reproduce a target string AGAINST the starting length of the target string@@|
!
!Lecture 2: Integrating Programming Tools


# [[HW01 Babel Bacterial Genome Library|L02.00]]
# [[Monkeys Typing: History|L02.01]]
# [[The Weasel: Directed Evolution Script|L02.02]]
# [[Monkeys Typing: PERL HW02|L02.03]]
# [[Monkey Statistical Mechanics|L02.04]]
# [[Monkey Typing: Python |L02.05]]
# [[Python Modules: Rpy|L02.06]]
# [[Python Modules: NumPy|L02.07]]
# [[Python Modules: PyLab|L02.08]]
# [[Directed Evolution Model: Python under the hood|L02.09]]
# [[Alphabet Soup|L02.10]]
# [[Coin Toss Model|L02.11]]
# [[Nucleotide Model|L02.12]]
# [[Integrating Software Tools|L02.13]]
!
<[[MAIN|L02]]>
!!!
!HW01 Babel Genome Library

''From Brian:''
A Babel Library of bacterial genomes would be just under 10^^1806180^^ bytes large or 10^^1806168^^ PB. However, since there are only four letters, letter could be encoded by 2 bits instead of the 7 required for ASCII, which would bring the file size down 64 fold, to around 10^^1806178.2^^ bytes.

Ever wonder how  genomes have evolved with just 4 nucleotides? 
4^^3,000,000^^ is a big enough number to cover the necessary sequence diversity.

!

<[[MAIN|L02]]|[[NEXT|L02.02]]>
!!!
!Monkeys Typing: History
The INFINITE MONKEY THEOREM:
[img[02/250px-Monkey-typing.jpg]]
^^http://en.wikipedia.org/wiki/Infinite_monkey_theorem^^

!!Émile Borel's 1913, French Physicist 
In his article "Mécanique Statistique et Irréversibilité" (Statistical mechanics and irreversibility), and in his book "Le Hasard" (1914), he uses "monkeys" as a metaphor for a process by which large, random sequence of letters could be generated. Borel used the metaphor as a rhetorical device, saying that if a million monkeys typed ten hours a day, it was extremely unlikely that their output would exactly equal all the books of the richest libraries of the world; and yet, in comparison, it was even more unlikely that the laws of statistical mechanics would ever be violated, even briefly.
!!Sir Arthur Eddington in 1927
In a 1927 lecture, Eddington stated: "If I let my fingers wander idly over the keys of a typewriter it might happen that my screed made an intelligible sentence. If an army of monkeys were strumming on typewriters they might write all the books in the British Museum. The chance of their doing so is decidedly more favourable than the chance of the molecules returning to one half of the vessel."
^^(Arthur S. Eddington. The Nature of the Physical World: The Gifford Lectures, 1927. N.Y., Macmillan, 1929)^^

!!Sir James Hopwood Jeans 1930
"It was, I think, Huxley who said that six monkeys, set to strum unintelligently on typewriters for millions of millions of years, would be bound in time to write all the books in the British Museum."
^^The Mysterious Universe, 1st
edition, The MacMillan Copany, New York and At the University
Press, Cambridge, England, 163 pp.^^

!!Jorge Luis Borge 1939/1941
By 1939, the idiom was "that a half-dozen monkeys provided with typewriters would, in a few eternities, produce all the books in the British Museum." In his 1939 essay "The Total Library", Borges adds: ''"Strictly speaking, one immortal monkey would suffice."'' In this work he traces the infinite recombinatorial diversity problem back to Aristotle.
! 

<[[BACK|L02.01]]|[[MAIN|L02]]|[[NEXT|L02.03]]>
!!!
!The WEASEL Directed Evolution Script
<html><img src="02/dawkinsBWM.png" style="height:200px"></html>
Richard Dawkins (The Blind Watchmaker, 1986) employs the typing monkey concept to demonstrate the abilities of natural selection in producing biological complexity out of random mutations. //In a simulation experiment, Dawkins has his ''Weasel program'' produce the Hamlet phrase METHINKS IT IS LIKE A WEASEL by typing random phrases but fixing those characters that match the goal.//
^^(http://en.wikipedia.org/wiki/Weasel_program)^^

!!!The Weasel Applet:
The weasel program is a computer software simulation written by ethologist Richard Dawkins in order to demonstrate the relative power of cumulative selection in an artificial evolutionary system.
LINK: http://home.pacbell.net/s-max/scott/weasel.html

!
<[[BACK|L02.02]]|[[MAIN|L02]]|[[NEXT|L02.04]]>
!!!
!Monkeys Typing: PERL HW02
So everyone in the class used the same starting script and just added some iteration loops . . . . 
<html>
<img src="02/hw/Assing1-Jixian.jpg" style="height:300px"><br>
<img src="02/hw/Data-plot_Monkey_script_SGK.jpg" style="height:300px"><br>
<img src="02/hw/HW2-Huang.png" style="height:300px"><br>
<img src="02/hw/Eddie-HW2.jpg" style="height:300px"><br>
<img src="02/hw/Guidaplot.png" style="height:300px"><br>
</html>

!
<[[BACK|L02.03]]|[[MAIN|L02]]|[[NEXT|L02.05]]>
!!!
!Monkey Typing: Statistical Mechanics
<html><img src="02/DEquarter.jpg" style="height:100px"><img src="02/US_quarter_back.png" style="height:100px"><img src="02/DEquarter.jpg" style="height:100px"><img src="02/DEquarter.jpg" style="height:100px"><img src="02/US_quarter_back.png" style="height:100px"><img src="02/DEquarter.jpg" style="height:100px"><img src="02/US_quarter_back.png" style="height:100px">
</html>
# Given a fair coin, what is the probable outcome of an air toss for Heads or Tails?
## P(H) = 0.50; P(T) = 0.5
## What is the difference between a probability and a frequency?
# How many times do you have to flip the coin to be 95% sure that it will land heads-up at least once?
# Given two fair coins, how many times do you have to flip both to be 95% sure that both will land heads-up at least once?
## Is this a different number than the certainty associated with flipping just one coin?
# What if ten people were each flipping one coin . . . . how many times do they have to flip them to be 95% sure that all coins will land heads-up at least once?

|{{blue{The P of ten heads in a row is 0.5^^10^^. But the probability that each coin would be a head on the first toss is still 0.5.}}} |

The crux of the monkey typing idiom is recognizing that although it is highly unlikely that an immortal monkey could ever type out 130,000+ characters in a row representing Shakespeare's //Hamlet// in total, every character position still maintains the same probability of selection. And if a mechanism is in place to fix those characters that are "functional" independently, ''then the process of evolution does not defy the statistical mechanics molecular organization.'' 

|@@NATURAL SELECTION establishes a strong filter for function against an otherwise infinite expanse of possibilities@@|

!
<[[BACK|L02.04]]|[[MAIN|L02]]|[[NEXT|L02.06]]>
!!!
!Monkey Typing: Python

So why are the results for the [[Monkey Typing PERL scripts|MonkeysTyping]] so variable?
<html>
<img src="02/hw/Assing1-Jixian.jpg" style="height:100px">
<img src="02/hw/Data-plot_Monkey_script_SGK.jpg" style="height:100px">
<img src="02/hw/HW2-Huang.png" style="height:100px">
<img src="02/hw/Eddie-HW2.jpg" style="height:100px">
<img src="02/hw/Guidaplot.png" style="height:100px">
</html>

Let's simplify the objective of the script. Instead of trying to randomly match alphabet letters to a target sentence, we are instead interested in taking two random strings of characters from a defined set, and then seeing how many turns (cycles or generations or loops) it takes for one of those strings to mutate into the other. The only selection rule is when a character in the mutating string is identical to the character in the same sequential position in the target string, it no longer mutates.
  
Because we ant a more quantitative look at the selection process, we'll utilize a python script that will call upon functions from [[R|r]], [[NumPy|Npy]], and [[PyLab|MatPlotLib]] (see [[Resources|Resource Index]]).

The MAIN working part of this directed evolution script (DirectedEvoPy) is very easy to grasp in terms of the program logic:
{{{
# 1. MODEL DATA COLLECTION . . . . . . . .
for i in range(NumberLengths):    
      # A. Initialize a target sequence . . . .
      LENGTH = InitialSeqLen + (i*IncrementLength)
      Target = TOOLS.sequence_mosaic(CHARset,LENGTH,BOOT,outdir)
      
      # B. Iterate directed evolution . . . . . .
      for j in range(BOOT):
            Target.fisheryates_randomize()
            Target.evolution(j)

      # C. Evaluate iterations . . . . . . . . . .
      Target.evaluate(i,LENGTH,Scores,CHARset,PlotScale)
      print "> Seq Length = ", LENGTH

# 2. MODEL DATA ANALYSIS . . . . . . . . . . . . .
flag = 0               # flag: 0=all, 1=mean, 2=var, 3=max 
Informatics = TOOLS.evolution_analysis(Scores, InitialSeqLen, outdir)
Informatics.regression(flag)           
Informatics.plot(flag,CHARset)
print "\n\n* * * *  D O N E  * * * *\n\n"
}}}

The beauty of Python is that much of the programming nuts-n-bolts can be separated away from the main logic pathway. 

!
<[[BACK|L02.05]]|[[MAIN|L02]]|[[NEXT|L02.07]]>
!!!
!Python Modules: Rpy

''Rpy'': R package module so python scripts can execute R functions.

Here's the PCA analysis of Fischer's Iris data presented by ~DMiller:
[[IRISpca.py|02/IRISpca.py]]
{{{
#!/usr/bin/python
import rpy

# DMiller's IRIS PCA in R example - - - - - - - - - - - - - - - 
r('''
library(ggplot2)
fit <- princomp(iris[,1:4],cor=TRUE)
IRISdm = cbind(fit$scores[,1],fit$scores[,2],iris$Species)
IRISdm = data.frame(IRISdm)
p <- ggplot(data=IRISdm, aes(x=X1, y=X2)) +
      geom_point(aes(colour=as.factor(X3))) +
      scale_x_continuous("PCA1") +
      scale_y_continuous("PCA2")
p$title<-c("IRIS PCA")
print(p)
''')
# DMiller's IRIS PCA in R example - - - - - - - - - - - - - - - 

print "***   DONE   ***\n\n\n"

}}}

!
<[[BACK|L02.06]]|[[MAIN|L02]]|[[NEXT|L02.08]]>
!!!
!Python Modules: ~NumPy

Numerical Python or Scientific Python

Adds numeric and matrix computational functions to python scripts. Most importantly is that NumPy arrays behave very differently than Python lists.

{{{
# logical test indexing . . . . . 
bignums = np.array(100, 125, 150, 175, 200, 12, 300, 400, 700, .....)
goodvals = bignums > 99
bignums[goodvals] = bignums * scalefactor ......

# for-loop mapping
newnums = (bignums * littlenums)/(middlenums)**0.5
}}}

!
<[[BACK|L02.07]]|[[MAIN|L02]]|[[NEXT|L02.09]]>
!!!
!Python Modules: ~PyLab

~PyLab = matplotlib

{{{
#!/usr/bin/python

import numpy as np
import pylab as p
#-------------------------
colormatrix = np.random.random_sample((100,100,3))
p.imshow(colormatrix, interpolation='nearest')
p.show()
#--------------------------
print "***  DONE  ***\n\n\n"
#EOF---------------------------
}}}
Color Map generated by function "imshow":
<html><img src="02/colormap.png" style="height:300px"></html>

!
<[[BACK|L02.08]]|[[MAIN|L02]]|[[NEXT|L02.10]]>
!!!
!Directed Evolution Model: Python under the hood

There are two files. One is the actual python script that is run ''"~DirectedEvo.py"'', the other is a file containing the variables and methods that contain the executing code ''"~DirectedEvoTools.py"'' (see DirectedEvolutionPy).

The actual run script appears so simplistic because all the execution code is really compartmentalized into the tools file so that the program logic is clear AND all the code functions have a modular structure
{{{
# 1. MODEL DATA COLLECTION . . . . . . . .
for i in range(NumberLengths):    
      # A. Initialize a target sequence . . . .
      LENGTH = InitialSeqLen + (i*IncrementLength)
      Target = TOOLS.sequence_mosaic(CHARset,LENGTH,BOOT,outdir)
      
      # B. Iterate directed evolution . . . . . .
      for j in range(BOOT):
            Target.fisheryates_randomize()
            Target.evolution(j)

      # C. Evaluate iterations . . . . . . . . . .
      Target.evaluate(i,LENGTH,Scores,CHARset,PlotScale)
      print "> Seq Length = ", LENGTH

# 2. MODEL DATA ANALYSIS . . . . . . . . . . . . .
flag = 0               # flag: 0=all, 1=mean, 2=var, 3=max 
Informatics = TOOLS.evolution_analysis(Scores, InitialSeqLen, outdir)
Informatics.regression(flag)           
Informatics.plot(flag,CHARset)
print "\n\n* * * *  D O N E  * * * *\n\n"
}}}

!!!The Tools file has this structure:
# ''class sequence_mosaic(object):''
## INITIALIZE . . . . . . . . . . . . . . . . . . . . . . . . . . . . 
*** def __init__(self,char,length, boot, dir):
## ESTABLISH TARGET CHARACTER SEQUENCE . . . . . . . . . . . .       
*** def seed(self):
## SHUFFLE SEQUENCE . . . . . . . . . . . . . . . . . . . . . . . . . . . . 
*** def fisheryates_randomize(self):
## Mutate new seq until it matches target sequence . . . . . . .
*** def evolution(self, iteration):
## Data Analysis
*** def evaluate(self, i, L, ~ScoreMatrix, charset, LIMITS):
**** GENERAL STATS . . . . . . . . . .
**** DISTRIBUTION PLOT . . . . . . . . . . . . . . . . . . . . . . .
**** Frequncy Histogram of all iteration data . . . . . . . .
**** Calculate the normal probability density function . . . . . . . 
**** Plot mean ref line . . . . . . . . . . . .
**** Pretty-up plot . . . . . . . . . . . . . . . . . . 
# ''class evolution_analysis(object):''
## INITIALIZE . . . . . . . . . . . . . . . . . . . . . . . . . . . . 
*** def __init__(self, DATA, n, dir):
## R correlation stats 
*** def regression(self,flag):
## XY plot
*** def plot(self, flag, char):
!
<[[BACK|L02.09]]|[[MAIN|L02]]|[[NEXT|L02.11]]>
!!!
!Alphabet Soup

Using a 52 letter character set (upper and lower case), with 100 bootstrap iterations at each length, there is a significant positive correlation between the number of characters in the sequence and the Min, Mean and Max generation cycles or turns that were required for one random string to converge on another. 
!!!
<html><img src="02/00-DataPlot-ALL-ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz.png" style="height:400px"></html>
!!!
To achieve this result in one script, ''R'' functions were called to compute the correlation and regression statistics, ~NumPy arrays were used for string handling (mutation, randomization), and ~PyLab was used to produce the XY plot (snippets):
{{{
# R calls:
ls_fit = r.lsfit(self.Nchar,self.DATA[:,i])
result = r.cor_test(x=self.Nchar,y=self.DATA[:,i],method='pearson')

# NumPy arrays:
self.seq = np.zeros((length),dtype='S1')
newseq = np.random.random_integers(0,self.N-1,L)

# PyLab plots:
Yheight, Xbins, patches = p.hist(self.allcounts, bars, normed=1)
p.plot(self.Nchar, self.DATA[:,i],'o',markerfacecolor=color[i-1])
}}}

|@@NOTE:  The count of 700 maximum turns for a 250 char sequence to match another is far less than 52^^250^^ permutations that would be required to find the match via combinometrics.@@|

{{blue{But WHY the positive slope?  If all character positions have the same probability of reaching fixation independently, why does sequence length matter?}}}

!
<[[BACK|L02.10]]|[[MAIN|L02]]|[[NEXT|L02.12]]>
!!!
!Coin Toss Model

To better understand the "statistical mechanics" behind probabilities, frequencies and selection fixation, let's use a simple system and model a fair coin toss. 

Now, by being good programmers and thinking broadly when we write scripts, we can often tackle several tasks from one basic code block. Here, the Directed Evolution script was initially written around an alphabet of 52 characters, but by just changing one line in the input section, it now becomes a coin toss model evaluating two possibilities: H = heads, T = tails:
{{{
#------------------------------------
#   U S E R     V A R I A B L E S 
#------------------------------------
CHARset = "HT"
. . . . . 
}}}

!!!Mutation Cycles:
<html><img src="02/00-DataPlot-ALL-HT.png" style="height:400px"></html>

!!!What is happening among the iterations at each individual seq length?
<html><table><tr>
<td><img src="02/00-DistributionPlot-000005-HT.png" style="height:250px"></td>
<td><img src="02/00-DistributionPlot-000250-HT.png" style="height:250px"></td>
</tr></table></html>
Distributions appear skewed at both short and long ends of the spectrum.
!
<[[BACK|L02.11]]|[[MAIN|L02]]|[[NEXT|L02.13]]>
!!!
!Nucleotide Model

Yep . . . . just change the input char set to have a nucleotide directed evolution model.  
{{{
#------------------------------------
#   U S E R     V A R I A B L E S 
#------------------------------------
CHARset = "GATC"
. . . . . 
}}}

Now because we want to focus more on how the distribution of mutation cycles or generations may be varying within the iterations of a specific sequence length, we'll add the distribution plot routines to the Tools script so that EVERY seq length has its own distribution plot.

!!!Mutation Cycles:
<html><img src="02/00-DataPlot-ALL-GATC.png" style="height:400px"></html>

!!!Distributions at Seq Length 5 and 2500 (@1000 bootstrap iterations each)?
<html><table><tr>
<td><img src="02/00-DistributionPlot-000005-GATC.png" style="height:250px"></td>
<td><img src="02/00-DistributionPlot-002500-GATC.png" style="height:250px"></td>
</tr></table><br>
Distributions still appear skewed. Effectively, there are no "minimum" outliers, just "maximum" outliers. Here's a look at all the plots in between 5 and 2500:<br> 
<u><a href="02/GATC-090226a.mov" target="_blank"> QuickTime Movie Summary (small 3.5 MB) </a></u>
or <u><a href="02/GATC-090226b.mov" target="_blank"> QuickTime Movie Summary (large 24.3 MB) </a></u>
</html>

!
<[[BACK|L02.12]]|[[MAIN|L02]]>
!!!
!Integrating Software Tools

# Many tools available, all have their unique strengths and weaknesses.
# Working in a Python environment allows you to pick the strengths of each.
# Having a question and developing a broad tool to tackle it will often open up numerous new avenues of inquiry or application.
# Treat every script you write as if it were a new hammer and bash it around looking for nails.

!
<[[BACK|L02.13]]|[[MAIN|L02]]|[[NEXT|L02.14]]>
!!!
!title
body
!
!Lecture 3: Modeling and Bootstrapping
# [[What is a model? Celestial Navigation|L03.01]]
# [[Models and Mirrors|L03.02]]
# [[Models as Tools|L03.03]]
# [[Basic Genetic Algorithm|L03.04]]
# [[Color Map Genetic Algorithm|L03.05]]
# [[Protein Genetic Algorithm|L03.06]]
# [[BootStrap Model|L03.07]]
# [[Simple GA Model Bootstrap|L03.08]]

!


!!!
<[[MAIN|L03]]|[[NEXT|L03.02]]>
!!!
!What is a model?

<html>
<div style="color: rgb(100, 100, 150); font-family: Monaco;">
<big><big><b>
Celestial Navigation
</html>

''1. Ptolemy Universe:''
~120 AD
<html><img src="03/PtolemyUniverse.jpg" style="height:300px"></html>

''2. Copernicus Universe:''
1543 //De revolutionibus orbium coelestium// (On the Revolutions of the Heavenly Spheres)
<html><img src="03/CopernicusUniverse.jpg" style="height:300px"></html>

# Revolutionized "natural" science
# Revolutionized celestial navigation
## stars are not fixed
## ocean sailing vessels updated with new navigation tables: 1650-1700

!
!!!
<[[BACK|L03.01]]|[[MAIN|L03]]|[[NEXT|L03.03]]>
!!!
!Models and Mirrors

Which of the following statements do you believe to be TRUE:

{{engindent{
''A.'' models are quantitative methods for describing system structures. 

''B.'' models are experimental tools to answer questions about how systems works.

''C.'' models are experimental tools to ask better questions about how systems works.  

}}}

!!!Models and You
# Actually, models are all about you. 
# They don't test systems. 
# Instead, they test your conception of a system. 
# The use of models should be explicitly focused on not answering questions, but instead on bettering your understanding of the questions that should be asked.
# They are an experimental tool, but what they really test is your mind and not the system being studied.

!

!!!
<[[BACK|L03.02]]|[[MAIN|L03]]|[[NEXT|L03.04]]>
!!!
!Models as Tools

!!!Population Dynamics:  Models

<html>
<img src="03/Lotka-Volterra.png" style="height:350px"><br>
<img src="03/Volterra_lotka_dynamics.png" style="height:150px">
</html>

!!!Population Dynamics: Reality

<html><img src="03/CapitellaPopDynamics.png" style="height:400px"></html>
^^//Chesney & Tenore, MEPS, 1985//^^

!
''The Question:''

<html>
<div style="color: rgb(100, 100, 150); font-family: Monaco;">
<big><big><b>
Should a model mimic reality?
</html>
!

!!!
<[[BACK|L03.03]]|[[MAIN|L03]]|[[NEXT|L03.05]]>
!!!
!Basic Genetic Algorithm
These can be very simple models but extremely powerful in terms of the "response" space that can be explored across millions of iterations.

''GOAL:''  Find a fixed number of factors whose product equals a set amount.
''MODEL:'' The rule set that you believe is active in reaching that goal.

//What are you testing? . . . . your expectation that you understand the system.//

Main code loop for DirectedGAPy:
{{{
while (done == 0):
      descendant = copy.deepcopy(ancestor)
      descendant.mutation()
      descendant.evaluation()
      if (descendant.score > ancestor.score and descendant.score < target):
            print "> ", count, " = ", descendant.score
            del(ancestor)
            TOOLS.write_stats(count, descendant.score)
            TOOLS.plot_score(target)
            # make new ancestor . . . . . . . . . . . . . 
            ancestor = copy.deepcopy(descendant)
            del(descendant)
      count += 1
      if (ancestor.score > target*0.999):
            done = 1
}}}

And the essential tools code (system rules coded here):
{{{
class GA_model(object):
      # INITIALIZE . . . . . . . . . . . . . . . . . . . . . . . . . . . . 
      def __init__(self, F, T):
            self.N = F
            self.target = T
            self.factors = np.random.random((self.N))
            self.score = 0
            self.evaluation()
      
      # Mutate new seq until it matches target sequence . . . . . . .
      def mutation(self):
            mute_rate = np.random.random((self.N))/100
            mute_dir  = np.random.random((self.N))
            down = mute_dir < 0.5
            up = mute_dir >= 0.5
            mute_dir[up] = 1
            mute_dir[down] = -1
            # mutation calculation . . . . . 
            self.factors = self.factors + (10*mute_rate*mute_dir)

      # Evaluate the new sequence . . . . . . 
      def evaluation(self):
            self.score = np.product(self.factors)
}}}
{{blue{//''Evaluation is the critical operation. The "functional" performance of the descendant object is made here. This is the crux of the rule set (your rule set) that shows you what you know about the system.''//}}} 
<html><img src="03/ScorePlotExample.png" style="height:300px"></html>
{{{
Target  20  reached:
[ 2.21385941  1.90462787  2.33971599  2.02660601]
}}}


!

!!!
<[[BACK|L03.04]]|[[MAIN|L03]]|[[NEXT|L03.06]]>
!!!
!Color Map Genetic Algorithm
''The Babel Gallery'' from [[Lecture 01|L01.11]]: the idea was assessing a simple rule set to use as a primary filter in generating random images.

''GOAL:''   Generate color images with compositional organization.
''MODEL:'' Minimizing the differences in RGB channel values between one pixel and the 8 pixels surrounding it will yield local-scale color organization. 
<html><table><tr>
<td><img src="03/Delta-090302-080x060-00000-00000-000000000.png" style="height:250px"></td>
<td><img src="03/Delta-090302-080x060-05325-01325-000292505.png" style="height:250px"></td>
</tr></table></html>

!!!Evaluation:
{{{
    def evaluate(self):
    # Use pixel rgb coefficient of variation . . . . .
        H = self.H - 1  
        W = self.W - 1
        self.cvscore = 0
        for i in range(1,H):      
            for j in range(1,W):    
                for k in range(3):
    # A. Score for channel variance in color among neighboring pixels . . . . .
                    rgb = np.array(self.matrix[i-1:i+2, j-1:j+2, k])
                    rgbdiff = np.abs(rgb - self.matrix[i,j,k])
                    rgbcv = (np.sum(rgbdiff)/8)/0.9 + 0.005
    # B. Gray penalty: scores for equivalent channel values at pixel i,j . . . .
                    k1 = 1
                    k2 = 2
                    if (k == 1):
                        k1 = 2
                        k2 = 0
                    elif (k == 2):
                        k1 = 0
                        k2 = 1
                    dx = np.abs(self.matrix[i,j,k] - self.matrix[i,j,k1])
                    dy = np.abs(self.matrix[i,j,k] - self.matrix[i,j,k2])
                    if (dx < 0.1 and dy < 0.1):
                        rgbcv = rgbcv * (1 + self.rgbcv_graypenalty)
    # C. Value check . . . . . . . . . . . . . . . . . . . . . . . . 
                    if (rgbcv > 1):
                        rgbcv = 1
    # Set fixation index level . . . . . . . . . . . . . . . . . . .
                    self.fixation[i,j,k] = rgbcv
}}}

!
!!!
<[[BACK|L03.05]]|[[MAIN|L03]]|[[NEXT|L03.07]]>
!!!
!Protein Genetic Algorithm

''Project X: The Babel Genome Project'' 

''GOAL:''   Generate genes/proteins with nt/aa sequence organization.
''MODEL:''  Local sequence organization guides total system organization. 
<html><table><tr>
<td><img src="03/Ecoli-090218-638aa-00000-00000-00000000.png" style="height:250px"></td>
<td><img src="03/Ecoli-090218-638aa-00151-01854-00004272.png" style="height:250px"></td>
</tr></table></html>

''TEST:''  Can //E.coli//-like proteins be generated from random nt sequences?  BLAST. 

!
!!!
<[[BACK|L03.06]]|[[MAIN|L03]]|[[NEXT|L03.08]]>
!!!
!Bootstrap Model
Uses iterative power of a program/script to generate a "population" of results to usually ascertain the contribution of random effects on a model result.

# What is the probability that your "understanding" of a system (model) does not differ from a random or neutral or null system? 
# Does your understanding provide you with more information than you would have if you just believed it was a random or neutral or null system?

''Linear Discriminate Analysis of bacterial genomes: free-living vs. pathogens'' 
<html>
<img src="03/Fig03-LDA.png" style="height:300px"><br>
<br>
<b>Build a response distribution by randomizing the input data over and over and over . . . . <br>
<img src="03/LDAdistribution.png" style="height:300px">
</html>

!
!!!
<[[BACK|L03.07]]|[[MAIN|L03]]|[[NEXT|L03.09]]>
!!!
!Simple GA Model Bootstrap
{{red{
Build iteration support into all of your model analyses.}}}

<html>
<img src="03/ScorePlotExample.png" style="height:300px"><br><br>
10 iterations is all it takes. Here 10% of the runs appear as outliers:
<img src="03/ScorePlotBoot.png" style="height:300px">
</html>


!
!!!
<[[BACK|L03.08]]|[[MAIN|L03]]|[[NEXT|L03.10]]>
!!!
!Title

Body

!
!!!
<[[BACK|L03.09]]|[[MAIN|L03]]|[[NEXT|L03.11]]>
!!!
!Title

Body

!
!!!
<[[BACK|L03.10]]|[[MAIN|L03]]|[[NEXT|L03.12]]>
!!!
!Title

Body

!
!!!
<[[BACK|L03.11]]|[[MAIN|L03]]|[[NEXT|L03.13]]>
!!!
!Title

Body

!
!Lecture 4: Graphics
# [[matplotlib|L04.01]]
# [[matplotlib documentation|L04.02]]
# [[matplotlib: animation|L04.08]]
# [[matplotlib: editing graphic objects|L04.10]]
# [[R: ggplot2|L04.03]]
# [[ggplot2: plotting data|L04.04]]
# [[ggplot2: data manipulation|L04.05]]
# [[ggplot2: boxplot|L04.06]]
# [[ggplot2: black & white|L04.07]]
# [[pylab vs. ggplot2|L04.09]]
!
!!!
<[[MAIN|L04]]|[[NEXT|L04.02]]>
!!!
!matplotlib

1. Data File: [[Download|04/mpl/01-RunStats.txt]]
2. Simple pylab plotting script: [[Download|04/mpl/matplotlib01.py]]

{{{
#!/usr/bin/python
'''
matplotlib 
'''
import pylab as p          # matplotlib plotting libraries
import numpy as np         # numpy/scipy numerical matrix indexing
import re

X = []
Y = []
file = "01-RunStats.txt"
IN = open(file,"r")
Lines  = IN.readlines()
IN.close()

# INPUT XY data . . . . . . . . . . . . . . . . . . 
for line in Lines:
      line = line.rstrip()
      obs = line.split('\t')
      X.append(float(re.sub("\s+","",obs[0])))
      Y.append(float(re.sub("\s+","",obs[1])))

# PLOT . . . . . . . . . . . . . . . . . . .
p.plot(X, Y, linestyle='-', color="b", linewidth=2)
p.ylabel('Factor Product',fontsize=12,fontweight='bold')
p.xlabel('Generation',fontsize=12,fontweight='bold')
p.show()

# Now save figure to file . . . . . . .
file = "03-TestPlot.png"
p.savefig(file)

print "\n\n\n * * * * *   D O N E   * * * * * \n\n\n"
# EOF ------------------------------------------------ 
}}}

<html><img src="04/mpl/03-TestPlot.png" style="height:300px"></html>


!
!!!
<[[BACK|L04.01]]|[[MAIN|L04]]|[[NEXT|L04.08]]>
!!!
!matplotlib documentation
http://matplotlib.sourceforge.net/contents.html
<html><img src="04/mpl/mpldoc.png" style="height:450px"></html>

!!What is pylab?
This is a subgroup of plotting functions within the larger matplotlib module. When these functions are loaded with:
{{engindent{@@{{{import pylab}}}@@}}}

''pylab'' is a reference handle for: ''matplotlib.pyplot''.  

Most of the plotting you will want to do will be accessed through pyplot functions. 

!
!!!
<[[BACK|L04.02]]|[[MAIN|L04]]|[[NEXT|L04.04]]>
!!!
!R: ggplot2
ggplot2 is a powerful system of advanced plotting procedures. It uses the R "plot" functions but essentially contains a library of sophisticated default settings. Although it is described as an advanced graphics development tool, it still just uses the R plot functionality.

Rule #1: When in doubt, go to the [[ggplot2 website|http://had.co.nz/ggplot2/]]
<html><img src="04/ggp/ggplotpage.png" style="height:200px"></html>

!!Installing:
{{engindent{@@{{{install.packages('ggplot2')}}}@@}}}

!!Three primary elements:
# Layers
** seperate graphic elements
# Aesthetics
** customize each graphic element
# Grobs
** hard-code editing of graphic elements
!
!!!
<[[BACK|L04.03]]|[[MAIN|L04]]|[[NEXT|L04.05]]>
!!!

!Plotting Data
Example plotting data for respiration rates in Antarctic sea urchin embryos during development at two different salinities. 
{{{
d=read.table("http://icewater.cms.udel.edu/InfoResearch/04/ggp/Sn-RespDevoSalinity.txt", sep='\t', header=T)
summary(d)
d$Salinity <- as.factor(d$Salinity)
names(d)[3] <- c("Resp")
D <- d[which(d$Resp < 500),]
}}}
There are TWO salinity treatments with a time vector and a data vector of respiration rates.

<html><img src="04/ggp/shot_01.png" style="height:150px"></html>

!Simple Plots
{{{
# startup ggplot routines - - - - - - - - - - - - - - - - - - - - 
	library(ggplot2)
	
# import dataframe - - - - - - - - - - - - - - - - - - - - 
setwd("/Users/agm/01-WORK/05-Courses/2009.1-BioInfoResearch/04/ggp")
d=read.table("http://icewater.cms.udel.edu/InfoResearch/04/ggp/Sn-RespDevoSalinity.txt", sep='\t', header=T)
summary(d)
d$Salinity <- as.factor(d$Salinity)
names(d)[3] <- c("Resp")
D <- d[which(d$Resp < 500),]
summary(D)
}}}
!!!
<html><img src="04/ggp/plot001.png" style="height:400px"></html>
{{{
# first data plot - - - - - - - - - - - - - - - - - - - 
p <- ggplot(data=D, aes(y=Resp,x=HPF)) + geom_point()
p
}}}
!!!
<html><img src="04/ggp/plot002.png" style="height:400px"></html>
{{{
# second data plot - - - - - - - - - - - - - - - - - - - 
p <- ggplot(data=D, aes(y=Resp,x=HPF)) + 
	geom_point(aes(colour=Salinity))
p
}}}
!!!
<html><img src="04/ggp/plot003.png" style="height:400px"></html>
{{{
# third data plot - - - - - - - - - - - - - - - - - - - 
p <- ggplot(data=D, aes(y=Resp,x=HPF)) +
	geom_point(aes(colour=Salinity)) +
	facet_grid(Salinity~.)
p
}}}
!
!!!
<[[BACK|L04.04]]|[[MAIN|L04]]|[[NEXT|L04.06]]>
!!!
!ggplot2: Data Manipulation
To get the full power of ggplot2 functions in plotting your data, it often takes some heavy manipulation of your matrices to get them formatted. Just as you might format your data for a specific statistical test, you'll likely have to format your data for specific plots. 

!!Is a simple mean plot all that simple?

{{{
# create new dataframe with means and sd by trts - - - - - - - - - 
Dx  = aggregate(D$Resp, list(D$Salinity,D$HPF), mean)
names(Dx)[1] <- c("Salinity")
names(Dx)[2] <- c("HPF")
names(Dx)[3] <- c("Resp")
Dsd = aggregate(D$Resp, list(D$Salinity,D$HPF), sd)
names(Dsd)[3] <- c("sd")
Dx$sd <- Dsd$sd
Dx$high <- Dx$Resp+Dx$sd
Dx$low  <- Dx$Resp-Dx$sd
}}}

<html><img src="04/ggp/plot004.png" style="height:400px"></html>
{{{
# xy mean plot - - - - - - - - - - - - - - -
p <-ggplot(data=Dx, aes(y=Resp,x=HPF)) +
	geom_errorbar(aes(max=high, min=low),width=0.2,colour="black") +
	geom_line(aes(colour=Salinity),size=1.5) +
	geom_point(aes(colour=as.factor(HPF)),size=4) +
	scale_y_continuous("Respiration Rate") +
	scale_x_continuous("Hours Post-Fertilization") +
	facet_grid(Salinity~.) +
    opts(legend.position="none")	
p
}}}
!!GROBS
Variable names for "graphics objects" that allow you to hard-edit them directly
{{{
# list the GRID objects in the plot
grid.ls(grobs=TRUE)
}}}

{{{
grid.gedit("label", gp=gpar(fontsize=12, col="black"))
grid.gedit("ylabel", gp=gpar(fontsize=16, col="black"))
grid.gedit("xlabel", gp=gpar(fontsize=16, col="black"))
grid.gedit(gPath("xaxis","label"), gp=gpar(fontsize=18, col="black"))
}}}
!
!!!
<[[BACK|L04.05]]|[[MAIN|L04]]|[[NEXT|L04.07]]>
!!!
!Boxplot
''Data from L.Kendall for genome methylation levels of different marine invertebrates.''
Data File: [[Download|04/ggp/PhylumMethylation-LRK.txt]]
<html>
<img src="04/ggp/080604-PhyloMethylationBoxPlots.png" style="height:300px">
</html>
{{{
# import dataframe - - - - - - - - - - - - - - - - - - - - 
d=read.table('http://icewater.cms.udel.edu/InfoResearch/04/ggp/PhylumMethylation-LRK.txt', sep='\t', header=T)

# data setup . . . . . . . . 
m=melt(d)
names(m) <- c("phylum","methylation")
m$phylum <- as.factor(m$phylum)
D <- m[ which(m$methylation > '0'), ]
summary(D)

# boxplot - - - - - - - - - - - - - - - - - - - - 
p <- ggplot(data=D, aes(y=methylation,x=phylum)) +
   geom_boxplot(aes(fill=phylum), colour="black", outlier.colour="green", outlier.size=3) +    
   scale_y_continuous("% Genome Methylation") +
   opt(legend.position="none") 
p
}}}
!
!!!
<[[BACK|L04.06]]|[[MAIN|L04]]|[[NEXT|L04.09]]>
!!!
!Black & White Publication Figures
"ggplot2" allows for THEMES to be added to plots as a separate layer. There is a theme for black and white publication figures called "theme_bw"
<html><img src="04/ggp/080911-Fig6A.png" style="height:300px"></html>
{{{
# boxplot - - - - - - - - - - - - - - - - - - - - 
p<-NULL
theme_bw$grid.colour="white"
p <-ggplot(data=D, aes(y=OBS,x=GRP)) +
	geom_boxplot(aes(fill=mOsm), colour="black", size=2) +
	scale_fill_grey(end=0.6) + 
	scale_y_continuous("Ratio Value") +
	scale_x_discrete("") +
	theme_bw
p$legend.position <- c(0.3,0.9)
p
grid.gedit("label", gp=gpar(fontsize=12, col="black"))
grid.gedit("ylabel", gp=gpar(fontsize=16, col="black"))
grid.gedit("xlabel", gp=gpar(fontsize=16, col="black"))
grid.gedit(gPath("xaxis","label"), gp=gpar(fontsize=18, col="black"))
}}}

!!BW XY plot with linear regression:
The black outline on points was achieved by double-plotting the data set, first in size 5 black circles and then with size 4 fill-color circles, which leaves a black edge visible.
<html><img src="04/ggp/080911-Fig6B.png" style="height:300px"></html>
{{{
p <-ggplot(data=d, aes(y=PO,x=RCR)) +
	geom_point(colour="black",size=5) +
	geom_point(aes(colour=mOsm),size=3) +
	stat_smooth(method="lm") +
	scale_colour_grey(end=0.6) + 
	scale_x_continuous("Respiratory Control Ratio") +
	scale_y_continuous("ADP:O") +
	theme_bw 
p$legend.position<-c(0.3,0.9)
p
grid.gedit("label", gp=gpar(fontsize=12, col="black"))
grid.gedit("ylabel", gp=gpar(fontsize=16, col="black"))
grid.gedit("xlabel", gp=gpar(fontsize=16, col="black"))
}}}

!
!!!
<[[BACK|L04.02]]|[[MAIN|L04]]|[[NEXT|L04.10]]>
!!!
!Animating plot images

animation: http://matplotlib.sourceforge.net/examples/animation/movie_demo.html
<html><img src="04/mpl/mplanimation.png" style="height:400px"></html>

Uses the MENCODER stand-alone compression routine to generate the final format. Mencoder is called through a system command in a separate execution thread (subprocess):
{{{
command = ('mencoder',
           'mf://*.png',
           '-mf',
           'type=png:w=800:h=600:fps=25',
           '-ovc',
           'lavc',
           '-lavcopts',
           'vcodec=mpeg4',
           '-oac',
           'copy',
           '-o',
           'output.avi')

subprocess.check_call(command)

}}}
!
!!!
<[[BACK|L04.07]]|[[MAIN|L04]]>
!!!
!pylab vs. ggplot2

''R'' uses an X11 graphic window for building plots in what is called a "grid" environment. You must have X11 installed and running on a machine in order to call any plot routines.

''matplotlib'' uses an internal 'canvas' object for compiling draw objects. There are no external dependencies for graphic device parameters.

!!Passing variables . . . . 
To move data from arrays/lists within a python script to ''R'' requires more code overhead than ''pylab''.
<html><img src="04/scoreplot/PlotData-MuteScores.png" style="height:400px"></html>
{{{
#    Setup the columns that will be added to the R dataframe . . . . . 
r.assign('Row', Row)
r.assign('ID', ID)
r.assign('GenNum', GenNum)
r.assign('Score', Score)

#  Now invoke R for ggplot call . . . . . . . . . . .
r('''
MELTED = data.frame(ID, GenNum, Score, row.names=Row ) 
library(ggplot2)
p <- ggplot(data=MELTED, aes(x=GenNum, y=Score, group=ID)) +
	geom_line(aes(colour=ID), size=1) +
	scale_x_continuous("Generation Number x 1000") +
	scale_y_continuous("Genetic Algorithm Score")
p$title<-c("Image Functional Score")
print(p)
grid.gedit("key", gp=gpar(lwd=4) )
ggsave(p, file="PlotData-TestScore.pdf")
''')
# EXIT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 
print "\nWaiting for Godot . . . "
wait = input()

print "\n\n\n * * * * *    D O N E     * * * * * \n\n"
}}}
! 
!!!
<[[BACK|L04.08]]|[[MAIN|L04]]|[[NEXT|L04.03]]>
!!!
!matplotlib: editing graphic objects

The ''matplotlibrc'' file contains many useful parameters for editing graphic object attributes. Using the ''pylab'' //rcParams// dictionary or ''rc()'' and ''rcdefaults()'' functions lets you make and revert changes on the fly. You can review a list of current graphic settings and variables in the ''rc'' parameters module:
{{{
import pylab as p
print p.rcParams
}}}

!!Editing matplotlibrc defaults
The ''matplotlibrc'' file contains most of the graphic settings for plots generated by pylab functions. You can make //hard-coded// changes to these default graphics settings by editing this file. The file is likely located in a system folder like: 
@@{{{/usr/lib/python2.5/site-packages/matplotlib/mpl-data/matplotlibrc}}}@@ 

If you want to customize the defaults, {{red{FIRST}}} copy this system-level file and make a user-local copy by putting it in your home folder in @@{{{~/.matplotlib/matplotlibrc}}}@@. Editing this local file will make changes that are in effect every time you use matplotlib.

!!Setting runtime parameters 
To access graphic objects while a script is running, use the ''pylab.rc'' function or set values in the ''rcParams'' dictionary (which is like a PERL hash).

For example, if you want to make a series of plots for a manuscript but the default font size is a too small when the figure size will be reduced at publication, you can set label size options so that the font size for every plot generated by your script will be the same. Look at your ''rc'' options: @@{{{ print p.rcParams }}}@@. Among a large number of options, you will see some that control the font size of different labels:
{{{
...
'axes.labelsize': 12.0,
...
'xtick.labelsize': 12.0,
...
'ytick.labelsize': 12,0,
...
}}}

There are two ways to change settings. It’s personal preference which one you use. Either way, you only have to do this once. From then on, all plots will use these new parameters.

First, note that the parameters are setup as a python dictionary where '''key' = value''. Using this ''rcParams'' dictionary, you set __//keys//__ to different __//values//__ with a simple list assignment statement:
{{{
p.rcParams['axes.labelsize'] = 16.0
p.rcParams['xtick.labelsize'] = 16.0
p.rcParams['ytick.labelsize'] = 16.0
}}}
The second alternative: you could use the ''rc'' function, which allows you set to set multiple parameters to the same value in one statement:
{{{
p.rc(('xtick','ytick','axes'), labelsize=16.0)
}}}
All other figure you make will this script is running will have the same text size.

To reset, plot variables back to their default settings:
{{{
p.rcdefaults()
}}}

!!Another example:
If you wanted to increase the separation between tick-labels and the tick marks on the axes:
{{{
p.rc(('xtick.major','xtick.minor','ytick.major','ytick.minor'), pad=10)
}}}

If you only want to change one of the tick labels, say, the x major ticks, use:
{{{
p.rc((’xtick.major), pad=10)
}}}

!



!
!Subjects

4. [[Lecture 04|L04]]: 
{{engindent{ {{blue{''Graphics''}}}
Homework Assignment: none
(//Here's the link for Miller's multivariate stats lecture//: [[DOWNLOAD|04/MILLER_13mar09-6.ppt]])}}}

3. [[Lecture 03|L03]]: 
{{engindent{ {{blue{''Modeling and Bootstrapping''}}}
Homework Assignment: none
(//Here's the link for Miller's multivariate stats lecture//: [[DOWNLOAD|03/MILLER-820_multivar_06mar09-2.ppt]])}}}

2. [[Lecture 02|L02]]: 
{{engindent{ {{blue{''Integrating Programming Tools''}}}
Homework Assignment: [[HW02]]
(//Here's the link for Miller's PCA lecture//: [[DOWNLOAD|02/MILLER-820_multivar_27feb09-4.ppt]])}}}

1. [[Lecture 01|L01]]: 
{{engindent{ {{blue{''Recombinometrics and natural system diversity and complexity''}}}
Reading Assignment: [[Library of Babel]]
(//Here's the link for Miller's Multivariate Statistics overview//: [[DOWNLOAD|01/Miller_multivar.ppt]])}}}


!
!Lecture X: title
# [[a|L0x.01]]
# [[b|L0x.02]]
# [[c|L0x.03]]
# [[e|L0x.04]]
# [[f|L0x.05]]
# [[g|L0x.06]]
# [[h|L0x.07]]
# [[i|L0x.08]]
# [[j|L0x.09]]
# [[k|L0x.10]]
# [[l|L0x.11]]
# [[m|L0x.12]]
!!!
<[[BACK|L0x.01]]|[[MAIN|L0x]]|[[NEXT|L0x.03]]>
!!!
!Title

Body

!
/***
|''Name:''|LegacyStrikeThroughPlugin|
|''Description:''|Support for legacy (pre 2.1) strike through formatting|
|''Version:''|1.0.2|
|''Date:''|Jul 21, 2006|
|''Source:''|http://www.tiddlywiki.com/#LegacyStrikeThroughPlugin|
|''Author:''|MartinBudden (mjbudden (at) gmail (dot) com)|
|''License:''|[[BSD open source license]]|
|''CoreVersion:''|2.1.0|
***/

//{{{
// Ensure that the LegacyStrikeThrough Plugin is only installed once.
if(!version.extensions.LegacyStrikeThroughPlugin) {
version.extensions.LegacyStrikeThroughPlugin = {installed:true};

config.formatters.push(
{
	name: "legacyStrikeByChar",
	match: "==",
	termRegExp: /(==)/mg,
	element: "strike",
	handler: config.formatterHelpers.createElementAndWikify
});

} //# end of "install only once"
//}}}
!Recombinatorial Diversity

Borges was a writer and philosopher with a large interest in classical theology and mathematics. But his day job was as a librarian and in this 1941 essay one can see a very well developed day-dream of his as he roamed the book stacks of the Argentine National Library in Buenos Ares. 
[[Borges' essay: Library of Babel|01/Borges-LibraryBabel.pdf]]

!!!Borge
http://en.wikipedia.org/wiki/Jorge_Luis_Borges
''Jorge Francisco Isidoro Luis Borges'' (24 August 1899 – 14 June 1986) was an Argentine writer born on 24 August 1899 in Buenos Aires, Argentina. He was brought up bilingual in Spanish and English. In 1914 his family moved to Switzerland where he attended school, then traveled around Spain. On return to Argentina in 1921, Borges began his career as a writer with the publication of poems and essays in Surrealism literary journals. He worked as a librarian, suffering political persecution at the hands of the Peron administration. He then became a public lecturer.

Due to a hereditary condition, Borges became blind in his late fifties. In 1955 he was appointed director of the National Public Library (Biblioteca Nacional) and professor of Literature at the University of Buenos Aires. In 1961 he came to international attention when he received the first International Publishers' Prize Prix Formentor. His work was translated and published widely in the United States and in Europe. He died in Geneva, Switzerland, in 1986.

!!!Theology and Geometry
http://en.wikipedia.org/wiki/Combinatorics
''Combinatorics'' is a branch of pure mathematics concerning the study of discrete (and usually finite) objects. It is related to many other areas of mathematics, such as algebra, probability theory, ergodic theory and geometry, as well as to applied subjects in computer science and statistical physics. Aspects of combinatorics include "counting" the objects satisfying certain criteria (enumerative combinatorics), deciding when the criteria can be met, and constructing and analyzing objects meeting the criteria (as in combinatorial designs and matroid theory), finding "largest", "smallest", or "optimal" objects (extremal combinatorics and combinatorial optimization), and finding algebraic structures these objects may have (algebraic combinatorics).

Combinatorics is as much about problem solving as theory building, though it has developed powerful theoretical methods, especially since the later twentieth century. One of the oldest and most accessible parts of combinatorics is graph theory, which also has numerous natural connections to other areas. Combinatorics is used frequently in computer science to obtain estimates on the number of elements of certain sets. 
!!!
Go to FrontPage
{{menubox2{Bioinformatics}}}{{menubox3{R you}}}
<<search>>
!OUTLINE:
''FrontPage''
[[1. What's New?|What's New?]]
[[2. Syllabus|Syllabus]]
[[3. Lectures|Lecture Index]]
[[4. Resources|Resource Index]]
[[5. Working Code|CodeWorks]]
[[6. Home Work|HomeWork]]
!!
{{tuduSlider{<<slider chkToolbox Toolbox 'Toolbox »'>>}}}
!AGM Tools:
[[Setup|Welcome to the Webview TiddlyWiki]]
[[SubTopics|ConfigSubTopics]]
[[Insert Figure|InFig]]
[[Emphasis Text|TextMonaco]]
!!























<!--{{{-->
<link rel='alternate' type='application/rss+xml' title='RSS' href='index.xml'/>
<!--}}}-->

<style type="text/css">#contentWrapper {display:none;}</style><div id="SplashScreen" style="border: 3px solid #ccc; display: block; text-align: center; width: 320px; margin: 100px auto; padding: 50px; color:#000; font-size: 28px; font-family:Tahoma; background-color:#eee;"><b>LOADING</b>: <blink> ...</blink><br><br></div>
[[BACK to Resources|Resource Index]]
!!!
!~PyLab: matplotlib
Get MatPlotLib [[HERE | http://matplotlib.sourceforge.net/]]
[img[00/matpy01.png]]
!!
<!--{{{-->
<div class='toolbar' macro='toolbar closeTiddler closeOthers +editTiddler > fields syncing permalink references jump'></div>
<div class='MicroGen' macro='tiddler MicroGenSubtopicMenu'></div><div class='title' macro='view title'></div>
<div class='viewer' macro='view text wikified'></div><div class='tagClear'></div>
<!--}}}-->
[[(RETURN to Lecture 1)|L01.12]]
!!!
!Combinametrics Script:
Simple PERL script to assess how long it takes to randomly match a string of characters to a target sentence.

{{{
#!/usr/bin/perl
use strict;

#--- AGM 2006 ---------------------------------------------------------
print "\n\n\n----------------------------------------------------------\n";
print "Would it really take a thousand years for a thousand monkeys \n";
print "typing on a thousand typewriters to compose Hamlet's soliloquy?\n\n";



my $MonkeysUncle = "false";
my @Keys  = qw | A B C D E F G H I J K L M N O P Q R S T U V W X Y Z 
                 a b c d e f g h i j k l m n o p q r s t u v w x y z |;
push @Keys," ";
my $alphabet = $#Keys;

print "\n";
print "Enter a sentence for the monkeys to type (no punctuation): \n";
my $shakespeare = <STDIN>;
chomp($shakespeare);
my $monkeys = int(length($shakespeare));
my $typewriter = "-" x $monkeys;
my @Shakespeare = split(//,$shakespeare);
my @Typewriter  = split(//,$typewriter);

print "\nHere's what you entered:\n";
print "      @Shakespeare\n";
print "\n... and here's what the monkeys start with:\n";
print "      @Typewriter\n\n";

print "Hit enter to release the monkeys into the typewriter room . . . ";
my $wait=<STDIN>;
print "\n\n";
 
my $bananas = 0;
my $KeyStrokes = 0;
while ($MonkeysUncle eq 'false')
{   #print " ~ ";
	$KeyStrokes += 1;
	my $Hits = 0;
    foreach my $chimp (0..$monkeys-1)
    {   	
	    my $keypunch = int(rand($alphabet+1));
	    if ($Typewriter[$chimp] eq "-")
		{   if ($Shakespeare[$chimp] eq $Keys[$keypunch])
		    {   $Typewriter[$chimp] = $Keys[$keypunch];
		        $Hits += 1;
		    }
		}               	    
    }

	if ($Hits > 0)
	{   print "\n$KeyStrokes. @Typewriter\n";
	    $bananas += $Hits;
	    sleep 1;   
	}
    
    if ($bananas == $monkeys)
    {   $MonkeysUncle = "true"; }
	
} # end WHILE(!Done)

print "\n\nIt took $KeyStrokes bananas to get those monkeys to find $monkeys correct letters.\n\n\n";
}}}
[[BACK to Resources|Resource Index]]
!!!
!Numerical or Scientific Python
The ''NumPy'' home is here: http://numpy.scipy.org/
[img[00/numpy.png]]
!!
//{{{
config.options.chkSearchTitles=true;
config.options.chkSearchText=true;
config.options.chkSearchTags=true;
config.options.chkSearchFields=true;
config.options.chkSearchTitlesFirst=false;
config.options.chkSearchList=true;
config.options.chkSearchByDate=false;
config.options.chkSearchIncremental=true;
config.options.chkSearchShadows=false; 
//}}}
[[BACK to Ressources|Resource Index]]
!!!
!What is PERL:
In computer programming, Perl is a high-level, general-purpose, interpreted, dynamic programming language. Perl was originally developed by Larry Wall, a linguist working as a systems administrator for NASA, in 1987, as a general purpose Unix scripting language to make @@ report processing easier.@@ The language provides powerful text processing facilities without the arbitrary data length limits of many contemporary Unix tools, making it the ideal language for manipulating text files. (from http://en.wikipedia.org/wiki/PERL)

Does your computer have PERL installed? All unix-type operating systems (Linux and OS X) have a PERL version installed by default. In contrast,  MS Windows verisons (2000, XP, Vista) do not.  You can check by opening a terminal window and at the command prompt (here just designated "prompt>") enter "perl -v" and hit <enter>:
{{{
prompt> perl -v
}}}
If PERL is installed, then you will get a brief summary of the current version index that is on your machine. If you need to install PERL, two common sources are listed below:

''PERL Sources:''
1. PERL Org - http://www.perl.org
<html><img src="00/perlorg.png" style="height:150px"></html>

2. For Windows (2000, XP, Vista): Active State - http://www.activestate.com/Products/activeperl/
<html><img src="00/activeperl.png" style="height:150px"></html>
''You will need the Windows x86 MSI file. Here is a local link to the current version available from Active state: [[EASY DOWNLOAD|00/ActivePerl-5.10.0.1003-MSWin32-x86-285500.msi]]
Full instructions for the install are described here: 
| [[Windows PERL Install]] |

!

<!--{{{-->
<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>
<!--}}}-->
/***
|''Name:''|PasswordOptionPlugin|
|''Description:''|Extends TiddlyWiki options with non encrypted password option.|
|''Version:''|1.0.2|
|''Date:''|Apr 19, 2007|
|''Source:''|http://tiddlywiki.bidix.info/#PasswordOptionPlugin|
|''Author:''|BidiX (BidiX (at) bidix (dot) info)|
|''License:''|[[BSD open source license|http://tiddlywiki.bidix.info/#%5B%5BBSD%20open%20source%20license%5D%5D ]]|
|''~CoreVersion:''|2.2.0 (Beta 5)|
***/
//{{{
version.extensions.PasswordOptionPlugin = {
	major: 1, minor: 0, revision: 2, 
	date: new Date("Apr 19, 2007"),
	source: 'http://tiddlywiki.bidix.info/#PasswordOptionPlugin',
	author: 'BidiX (BidiX (at) bidix (dot) info',
	license: '[[BSD open source license|http://tiddlywiki.bidix.info/#%5B%5BBSD%20open%20source%20license%5D%5D]]',
	coreVersion: '2.2.0 (Beta 5)'
};

config.macros.option.passwordCheckboxLabel = "Save this password on this computer";
config.macros.option.passwordInputType = "password"; // password | text
setStylesheet(".pasOptionInput {width: 11em;}\n","passwordInputTypeStyle");

merge(config.macros.option.types, {
	'pas': {
		elementType: "input",
		valueField: "value",
		eventName: "onkeyup",
		className: "pasOptionInput",
		typeValue: config.macros.option.passwordInputType,
		create: function(place,type,opt,className,desc) {
			// password field
			config.macros.option.genericCreate(place,'pas',opt,className,desc);
			// checkbox linked with this password "save this password on this computer"
			config.macros.option.genericCreate(place,'chk','chk'+opt,className,desc);			
			// text savePasswordCheckboxLabel
			place.appendChild(document.createTextNode(config.macros.option.passwordCheckboxLabel));
		},
		onChange: config.macros.option.genericOnChange
	}
});

merge(config.optionHandlers['chk'], {
	get: function(name) {
		// is there an option linked with this chk ?
		var opt = name.substr(3);
		if (config.options[opt]) 
			saveOptionCookie(opt);
		return config.options[name] ? "true" : "false";
	}
});

merge(config.optionHandlers, {
	'pas': {
 		get: function(name) {
			if (config.options["chk"+name]) {
				return encodeCookie(config.options[name].toString());
			} else {
				return "";
			}
		},
		set: function(name,value) {config.options[name] = decodeCookie(value);}
	}
});

// need to reload options to load passwordOptions
loadOptionsCookie();

/*
if (!config.options['pasPassword'])
	config.options['pasPassword'] = '';

merge(config.optionsDesc,{
		pasPassword: "Test password"
	});
*/
//}}}
/***
|''Name:''|PlasticCalendarPlugin|
|''Description:''|This plugin creates a custom Gregorian calendar|
|''Version:''|1.3.1|
|''Date:''|Mar 13, 2007|
|''Source:''|http://www.math.ist.utl.pt/~psoares/addons.html|
|''Documentation:''|[[PlasticCalendarPlugin Documentation|PlasticCalendarPluginDoc]]|
|''Author:''|Paulo Soares|
|''License:''|[[Creative Commons Attribution-Share Alike 3.0 License|http://creativecommons.org/licenses/by-sa/3.0/]]|
|''~CoreVersion:''|2.1.0|
***/
{{{
// --------------------------------------------------------------------
// Calendar
// --------------------------------------------------------------------

config.macros.calendar = {holidays: []};
config.macros.calendar.options = {
 // day week starts from (normally 0-Su or 1-Mo)
 calendarWeekStart: 0,
 calendarToday: "Today",
 calendarHoliday: "Holiday: ",
 calendarLongDateFormat: "0DD/0MM/YYYY",
 calendarShortDateFormat: "0DD/0MM",
 calendarTag: ["journal"]
};

/***************************************************************************
** Internal functions
***************************************************************************/
var cldTag;

config.macros.calendar.calendarIsHoliday = function(date) {
 var cm = config.macros.calendar;
 var longHoliday = date.formatString(cm.options.calendarLongDateFormat);
 var shortHoliday = date.formatString(cm.options.calendarShortDateFormat);
 for(var i = 0; i < cm.holidays.length; i++) {
 if(cm.holidays[i][0] == longHoliday || cm.holidays[i][0] == shortHoliday) {
 return cm.holidays[i];
 }
 }
 return null;
}

config.macros.calendar.onClickOtherDay = function(e) {
 var day = this.getAttribute('tiddlylink');
 story.displayTiddler(null,day,DEFAULT_EDIT_TEMPLATE);
 for(var i=0; i<cldTag.length;i++){
 story.setTiddlerTag(day, cldTag[i], 0);
 }
 story.focusTiddler(day,"text");
}

config.macros.calendar.getPopupText = function(title) {
 var popup_entries = store.getTiddlerText(title).split("\n");
 var popup = popup_entries[0];
 if(popup_entries.length>1) popup += " ...";
 return popup;
}

config.macros.calendar.findCalendar = function(child) {
 var parent;
 while (child && child.parentNode) {
 parent = child.parentNode;
 if (parent.id == "calendarWrapper") {
 return parent;
 }
 child = parent;
 }
 return null;
}

config.macros.calendar.selectDate = function(e) {
 if (!e) var e = window.event;
 var cm = config.macros.calendar;
 var calendar = cm.findCalendar(this);
 if (calendar) {
 var d = this.getAttribute("date");
 if (d != null) cm.makeCalendar(calendar, new Date(new Number(d)));
 }
 e.cancelBubble = true;
 if (e.stopPropagation) e.stopPropagation();
 return false;
}

config.macros.calendar.makeCalendar = function(calendar, dt_current) {
 var cm = config.macros.calendar;
 var currentDay = new Date(new Number(calendar.getAttribute("currentDay")));
 var setControls = calendar.getAttribute("setControls");
 calendar.setAttribute("date", dt_current.valueOf());

 while (calendar.hasChildNodes())
 calendar.removeChild(calendar.firstChild);

if(setControls==1){
 // get same date in the previous year
 var dt_prev_year = new Date(dt_current);
 dt_prev_year.setFullYear(dt_prev_year.getFullYear() - 1);
 if (dt_prev_year.getDate() != dt_current.getDate())
 dt_prev_year.setDate(0);

 // get same date in the next year
 var dt_next_year = new Date(dt_current);
 dt_next_year.setFullYear(dt_next_year.getFullYear() + 1);
 if (dt_next_year.getDate() != dt_current.getDate())
 dt_next_year.setDate(0);

 // get same date in the previous month
 var dt_prev_month = new Date(dt_current);
 dt_prev_month.setMonth(dt_prev_month.getMonth() - 1);
 if (dt_prev_month.getDate() != dt_current.getDate())
 dt_prev_month.setDate(0);

 // get same date in the next month
 var dt_next_month = new Date(dt_current);
 dt_next_month.setMonth(dt_next_month.getMonth() + 1);
 if (dt_next_month.getDate() != dt_current.getDate())
 dt_next_month.setDate(0);
}

 // get first day to display in the grid for current month
 var dt_firstday = new Date(dt_current);
 dt_firstday.setDate(1);
 dt_firstday.setDate(1 - (7 + dt_firstday.getDay() - cm.options.calendarWeekStart) % 7);

 var area, header;
 var line, cell, i;

 // 1 - calendar header table
 // 2 - print weekdays titles
 // 3 - calendar days table 
calendar.cellPadding = 0;
calendar.cellSpacing = 0;
area = createTiddlyElement(calendar, "tbody");

 // 1 - calendar header table
 header = createTiddlyElement(area,"tr", "calendarHeader");
 header.cellPadding = 0;
 header.cellSpacing = 0;

if(setControls==1){ 
var headerValues = [
 [ "<<", "selectYear", dt_prev_year.valueOf() ],
 [ "<", "selectMonth", dt_prev_month.valueOf() ],
 [ config.messages.dates.months[dt_current.getMonth()] + ' ' + dt_current.getFullYear(),
 "selectToday", currentDay.valueOf() ],
 [ ">", "selectMonth", dt_next_month.valueOf() ],
 [ ">>", "selectYear", dt_next_year.valueOf() ]
 ];

 for (i = 0; i < headerValues.length; ++i) {
 var link = createTiddlyElement(header,"td", null, null, headerValues[i][0]);
 if(i==2) link.colSpan=3;
 link.onclick = cm.selectDate;
 link.setAttribute("date", headerValues[i][2]);
 }
} else {
 var link = createTiddlyElement(header,"td", null, null, 
config.messages.dates.months[dt_current.getMonth()] + ' ' + dt_current.getFullYear());
link.colSpan=7;
}

 // 2 - print weekdays titles
 line = createTiddlyElement(area, "tr", "weekNames");
 for (var n = 0; n < 7; ++n) {
 createTiddlyElement(line, "td", null, null, config.messages.dates.shortDays[(cm.options.calendarWeekStart + n)%7]);
 }

 // 3 - calendar days table
 var dt_current_day = new Date(dt_firstday);
 var day_class;
 var title;
 var holiday;
 var popup;
 var clickHandler;

 while (dt_current_day.getMonth() == dt_current.getMonth() ||
 dt_current_day.getMonth() == dt_firstday.getMonth()) {

 // print row header
 line = createTiddlyElement(area, "tr", "calendarLine", null, null);
 for (var n_current_wday = 0; n_current_wday < 7; ++n_current_wday) {
 title = dt_current_day.formatString(cm.options.calendarLongDateFormat);
 clickHandler = cm.onClickOtherDay;
 popup = null;
 holiday = cm.calendarIsHoliday(dt_current_day);

 if (holiday != null) {
 // holidays
 day_class = (holiday.length==3)? holiday[2]: "holiDay";
 popup = cm.options.calendarHoliday + holiday[1];
 } else if (dt_current_day.getDay() == 0 || dt_current_day.getDay() == 6) {
 // weekend days
 day_class = "weekDay";
 } else {
 // print working days of current month
 day_class = "workingDay";
 }

if(dt_current_day.getMonth() == dt_current.getMonth()){
 if (currentDay.valueOf() == dt_current_day.valueOf()) {
 // print current date
 if (store.tiddlerExists(title)){
 // day has a tiddler associated with it
 day_class += " currentscheduledDay";
 clickHandler = onClickTiddlerLink;
 popup = cm.options.calendarToday + ": "+ cm.getPopupText(title);
 } else {
 day_class += " currentDay";
 popup = cm.options.calendarToday;
}
}


 if (store.tiddlerExists(title) && store.getTiddler(title).isTagged(cldTag[0]))  {
 // day has a tiddler associated with it
 day_class += " scheduledDay";
 clickHandler = onClickTiddlerLink;
 popup = cm.getPopupText(title);
 }
}

 // extra formatting for days of previous or next month
 if (dt_current_day.getMonth() != dt_current.getMonth()) {
 day_class += " otherMonthDay";
 }

 var text = dt_current_day.getDate();
 var cell = createTiddlyElement(line, "td", null, day_class, text);
 cell.onclick=clickHandler;
 cell.setAttribute("date", dt_current_day.valueOf());
 cell.setAttribute("tiddlyLink", title);
 if(popup) cell.setAttribute("title", popup);
 dt_current_day.setDate(dt_current_day.getDate()+1);
 }
 }
}

config.macros.calendar.handler = function(place,macroName,params,wikifier,paramString,tiddler) {
 var start_date = new Array();
 var date = new Date();
 var cldParams = paramString.parseParams('calendarParams', null, true);
 var cldYear = (cldParams[0].year)?parseFloat(cldParams[0].year[0]): date.getFullYear();
 var cldMonth = (cldParams[0].month)?parseFloat(cldParams[0].month[0]): date.getMonth();
 var n_months = (cldParams[0].numberMonths)?parseFloat(cldParams[0].numberMonths[0]): 1;
 var n_cols = (cldParams[0].numberColumns)?parseFloat(cldParams[0].numberColumns[0]): 3;
 cldTag = (cldParams[0].tag)?cldParams[0].tag[0].split("#"): config.macros.calendar.options.calendarTag;
 for(var i = 0; i < n_months; i++){
 start_date[i] = new Date(cldYear, cldMonth+i, 1);
 }
 var n_rows = Math.max(1,Math.ceil(n_months/n_cols));
 n_cols = Math.min(n_cols,n_months);
 var setControls=(n_months>1)? 0: 1;
 var currentDay = new Date();
 currentDay = new Date(currentDay.getFullYear(), currentDay.getMonth(), currentDay.getDate());
 var holder = createTiddlyElement(place, "table", null,"calendarHolder");
 var holderTable = createTiddlyElement(holder, "tbody");
 for(var i = 0; i < n_rows; i++){
 var holderLine = createTiddlyElement(holderTable, "tr");
 for(var j = 0; j < n_cols; j++){
 var holderCell = createTiddlyElement(holderLine, "td");
 if(n_cols*i+j+1<=n_months){
 var calendar = createTiddlyElement(holderCell, "table", "calendarWrapper");
 calendar.setAttribute("name", "calendarWrapper");
 calendar.setAttribute("setControls", setControls);
 calendar.setAttribute("currentDay", currentDay.valueOf());
 config.macros.calendar.makeCalendar(calendar, start_date[n_cols*i+j]);
 }
 }
 }
}

function refreshCalendars(hint) {
 var calendars = document.getElementsByName("calendarWrapper");
 var i, c;
 for (i = 0; i < calendars.length; ++i) {
 c = calendars.item(i);
 if (c.id == "calendarWrapper") {
 config.macros.calendar.makeCalendar(c, new Date(new Number(c.getAttribute("date"))));
 }
 }
}

store.addNotification(null, refreshCalendars);

setStylesheet("/***\n!Calendar Styles\n***/\n/*{{{*/\n .viewer .calendarHolder {\n margin-left: auto;\n margin-right: auto;\n border: none;\n}\n\n .viewer .calendarHolder table {\n border: none;\n margin: 0;\n}\n\n .viewer .calendarHolder tr {\n border: none;\n vertical-align: top;\n}\n\n .viewer .calendarHolder td {\n border: none;\n vertical-align: top;\n}\n\n .viewer #calendarWrapper {\n width: 21em;\n border: 2px solid #4682b4;\n cursor: pointer;\n}\n\n #calendarWrapper #calendarLine td {\n height: 2.5em;\n}\n\n #calendarWrapper tr {\n border:none;\n}\n\n #calendarWrapper td {\n text-align: center;\n vertical-align: middle;\n width: 14.28%;\n border:none;\n}\n\n #calendarWrapper #calendarHeader td{\n color: #ffffff;\n background-color: #4682b4;\n height: 2em;\n}\n\n #calendarWrapper #weekNames td {\n color: #ffffff;\n background-color: #87cefa;\n height: 2em;\n}\n\n #calendarWrapper .weekDay {\n background-color: #ccff99;\n}\n\n #calendarWrapper .holiDay {\n background-color: #9acd32;\n}\n\n #calendarWrapper .currentDay {\n border: solid #ff0000 2px;\n font-weight: bold;\n}\n\n #calendarWrapper .currentscheduledDay {\n border: solid #ff0000 2px;\n font-weight: bold;\n}\n\n #calendarWrapper .workingDay {\n background-color: #ffffff;\n}\n\n #calendarWrapper .scheduledDay {\n border: solid orange 2px;\n}\n\n #calendarWrapper .otherMonthDay {\n background-color: #999;\n}\n\n/*}}}*/","CalendarStyles");

config.shadowTiddlers.PlasticCalendarPluginDoc="The documentation is missing. It is available [[here|http://www.math.ist.utl.pt/~psoares/addons.html#PlasticCalendarPluginDoc]].";
}}}
version.extensions.Holidays = {
 major: 1, minor: 1, revision: 0,
 date: new Date(2006, 4, 18), 
 type: 'config'
};

config.macros.calendar.holidays = [ ["01/01", "New Year's day"], ["25/12", "Christmas day", "Christian"] ];
!!!Combined logical testing for matrix indexing:
index = (A < c1) & (D > c2)
!Course Resources:
# [[PERL]]
# [[Running PERL]]
# [[Python|python]]
# [[''R'': Open Statistics Software|r]]
** Here's a simple R Tutorial: [[Tutorial-Verzani-SimpleR.pdf|00/Tutorial-Verzani-SimpleR.pdf]]
** Here's a simple R guide: [[QUICK-R Guide|http://www.statmethods.net/index.html]]
# [[Code editors|Editors]]
# [[MatLab|matlab]]
# [[DBI Bioinformatic Cluster, Biowolf|Biowolf]]
# [[Secure Shell File Transfer|SSH]]
# [[SSH-Setup|SSHsetup]]
# [[PC command window summary (E. Maung)|00/EmilyBasicWindowsStuff.pdf]]
# [[NCBI GenBank|GenBank]]
# [[CD-HIT|cdhit]]
# [[BioPython]]
** Bioinformatics tutorial online: http://www.pasteur.fr/recherche/unites/sis/formation/python/index.html
** ~BioPython Tutorial: [[Tutorial-Biopython.pdf|00/Tutorial-Biopython.pdf]]
# [[MatPlotLib (python tool)|MatPlotLib]]
# [[Rpy2 (python interface for R functions)|Rpy]]
# [[NumPy/SciPy|Npy]]
[[BACK to Resources|Resource Index]]
!!!
!R module for python
The ''Rpy2'' Home is here: http://rpy.sourceforge.net/rpy2.html
[img[00/rpy2.png]]
!!
[[BACK to Ressources|Resource Index]]
!!!
!PERL on a MS Windows operating system
Active PERL ([[Active State|http://www.activestate.com/Products/activeperl/]]) is provided in an Microsoft Installer Package that will handle most of the details of the install. The default install location is "C:\Perl". It doesn't matter where PERL is installed, what matters is that you know where it is. Also, the installer should add the perl path statement (which with a default install is "C:\Perl\bin") to the PATH environmental variable. Instructions for checking this can be found [[HERE| http://www.computerhope.com/issues/ch000549.htm]]. You can check if PERL is installed by opening a terminal window and at the command prompt (here just designated "prompt>") enter "perl -v" and hit <enter>:
{{{
prompt> perl -v
}}}
If PERL is installed, then you will get a brief summary of the current version index that is on your machine. If you need to install PERL, two common sources are listed below:

!PERL test script
Here's the archetypical "hello world" program to test your perl skills at this point. 
''1.'' Copy the lines below and paste them into a new text file via your favorite flavor of text editor.
{{{
#!PATH-2-PERL
# - - - - - M A I N - - - - - - - - - 
print "\n\n\nLeft a good job in the city,\n";
print "workin for the man every night and day\n\n\n";
# - - - - - EOF - - - - - - - - - - - 
}}}

''2.'' EDIT the "PATH-2-PERL" string by putting the exact path to where the perl.exe program resides on your machine. On a windows PC with a default Active Perl install, this should be "C:\Perl\bin". On unix-flavor machines, you can find where perl is installed by entering the following into a command window:
{{{
prompt> which perl
}}}

''3.'' SAVE the file as "00-TestPerl.pl"

''4.'' Open a command terminal window and navigate to the folder where you just saved "00-TestPerl.pl". This is usually accomplished using these two commands (where folder = the name of a folder within the current folder where the prompt is located):
{{{
prompt> cd folder  # go down one level to folder
propmt> cd ..        # go up one level in tree
}}}
For those of you with Windows PCs, more information about navigating in command mode can be found [[HERE| http://ourworld.compuserve.com/homepages/jsuebersax/dos.htm#paths]]

''5.'' Once you are in the folder where "00-TestPerl.pl" is located, you can run the script as follows:
@@FOR WINDOWS PCs@@
Enter the full filename at the command prompt:
{{{
prompt> 00-TestPerl.pl
}}}
@@FOR UNIX-FLAVORS@@
Before the script can be run, it has to be "given" permission to run as an executable file. This is accomplished with the //chmod// command:
{{{
prompt> chmod 755 00-TestPerl.pl
prompt> 00-TestPerl.pl
}}}

''6.'' The print statement should execute sending this message to the screen (or whatever message you put into the script):
{{{
Left a good job in the city, 
workin for the man every night and day
}}}

[[BACK|Resource Index]]
!
[[BACK to Resources|Resource Index]]
!!!
!SSH
@@. ''SSH is an encrypted file transfer protocol that replaces telnet or ftp'' .@@
!!1. For Windows OS: 
SSH and SSHclient are available from the UD Network software pages at http://www.udel.edu/network:
[img[00/udnetwork01.png]]
[img[00/udnetwork02.png]]


!!2. For Mac OS X:
It's already installed and running, but you in order to mount a remote system as a system drive, you need the macfuse update at (at least for Tiger): http://code.google.com/p/macfuse/
<html><img src="00/macfuse.png" style="height:400px"></html>


!!3. For linux/unix flavors:
It is already installed, running and can readily be mounted as a system drive. I like the KDE desktop file manager because it automatically mounts ssh connections as "drives".
!!!
[[BACK to Resources|Resource Index]]
!!!
!SSH setup for automatic login to Biowolf:
SSH has a system for allowing computers to recognize each other and bypass the exchange of a password when connecting them. The way it works is that your local computer (A) generates an encrypted KEY that is then put in a file in your home directory on Biowolf. Login authorization is then determined by the computers 'recognizing' each other using this key.

First, start an SSH-client (command) terminal window on local computer (here named 'LOCAL'). Then generate the ssh key by following these commands, but do not enter a 'passphrase' when prompted. Just hit return twice.
{{{
LOCAL> ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/home/user/.ssh/id_rsa): 
Created directory '/home/user/.ssh'.
Enter passphrase (empty for no passphrase): 
Enter same passphrase again: 
Your identification has been saved in /home/user/.ssh/id_rsa.
Your public key has been saved in /home/user/.ssh/id_rsa.pub.
The key fingerprint is:
3e:4f:05:79:3a:9f:96:7c:3b:ad:e9:58:37:bc:37:e4 user@LOCAL
}}}
Now use ssh to create a directory ~/.ssh Biowolf. (The directory may already exist, which is fine). Use your classXX username. You will be prompted for your password:
{{{
LOCAL> ssh classXX@biowolf.dbi.udel.edu mkdir -p .ssh
}}}

Now we just add/append the public key from LOCAL to your Biowolf account in a file named "authorized_keys". Again use your classXX username and you will be prompted for your password:
{{{
LOCAL> cat .ssh/id_rsa.pub | ssh classXX@biowolf.dbi.udel.edu 'cat >> .ssh/authorized_keys'
}}}
From now on you can log into Biowolf from your LOCAL computer without entering a password. 

You can streamline the login process even more by establishing an 'alias' command in your shell profile. This is easy to do, but depends upon what shell you are running on your LOCAL computer. For a C shell (csh) add a line like this to the ''.cshrc'' file in your home directory on LOCAL (//note that this is a hidden file//):
{{{
alias biowolf ssh -l classXX biowolf.dbi.udel.edu
}}}

For a bash shell add a line like this to the ''.bash_profile'' file in your home directory on LOCAL (//note that this is a hidden file//):
{{{
alias biowolf='ssh -l classXX biowolf.dbi.udel.edu'
}}}

From a terminal window you need to restart the shell with either:
** prompt> source .cshrc
** prompt> source .bashrc
And then you can log into your Biowolf account with just the command:
{{{
LOCAL> biowolf
}}}
//{{{
window.reportSearchResults=function(text,matches)
{
	var title=config.macros.search.reportTitle
	var q = config.options.chkRegExpSearch ? "/" : "'";
	var body="\n";

	// numbered list of links to matching tiddlers
	body+="\n<<<";
	for(var t=0;t<matches.length;t++) {
		var date=config.options.chkSearchByDate?(matches[t].modified.formatString('YYYY.0MM.0DD 0hh:0mm')+" "):"";
		body+="\n# "+date+"[["+matches[t].title+"]]";
	}
	body+="\n<<<\n";

	// create/update the tiddler
	var tiddler=store.getTiddler(title); if (!tiddler) tiddler=new Tiddler();
	tiddler.set(title,body,config.options.txtUserName,(new Date()),"excludeLists excludeSearch");
	store.addTiddler(tiddler); story.closeTiddler(title);

	// use alternate "search again" label in <<search>> macro
	var oldprompt=config.macros.search.label;
	config.macros.search.label="search again";

	// render/refresh tiddler
	story.displayTiddler(null,title,1);
	store.notify(title,true);

	// restore standard search label
	config.macros.search.label=oldprompt;

}

//}}}
/***
|Name|SearchOptionsPlugin|
|Source|http://www.TiddlyTools.com/#SearchOptionsPlugin|
|Documentation|http://www.TiddlyTools.com/#SearchOptionsPluginInfo|
|Version|2.6.1|
|Author|Eric Shulman - ELS Design Studios|
|License|http://www.TiddlyTools.com/#LegalStatements <br>and [[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]|
|~CoreVersion|2.1|
|Type|plugin|
|Requires||
|Overrides|Story.prototype.search, TiddlyWiki.prototype.search, config.macros.search.onKeyPress|
|Description|extend core search function with additional user-configurable options|
Extend core search function with additional user-configurable options including generating a ''list of matching tiddlers'' instead of immediately displaying all matches.
!!!!!Documentation
>see [[SearchOptionsPluginInfo]]
!!!!!Configuration
<<<
<<option chkSearchTitles>> Search in titles
<<option chkSearchText>> Search in tiddler text
<<option chkSearchTags>> Search in tags
<<option chkSearchFields>> Search in data fields
<<option chkSearchShadows>> Search shadow tiddlers
<<option chkSearchTitlesFirst>> Show title matches first
<<option chkSearchByDate>> Sort matching tiddlers by date
<<option chkSearchList>> Show list of matches in [[SearchResults]]
<<option chkSearchIncremental>> Incremental (key-by-key) searching
<<<
!!!!!Revisions
<<<
2007.02.17 [2.6.1] added redefinition of config.macros.search.onKeyPress() to restore check to bypass key-by-key searching (i.e., when chkSearchIncremental==false), which had been unintentionally removed with v2.6.0
|please see [[SearchOptionsPluginInfo]] for additional revision details|
2005.10.18 [1.0.0] Initial Release
<<<
!!!!!Code
***/
//{{{
version.extensions.searchOptions = {major: 2, minor: 6, revision: 1, date: new Date(2007,2,17)};

if (config.options.chkSearchTitles===undefined) config.options.chkSearchTitles=true;
if (config.options.chkSearchText===undefined) config.options.chkSearchText=true;
if (config.options.chkSearchTags===undefined) config.options.chkSearchTags=true;
if (config.options.chkSearchFields===undefined) config.options.chkSearchFields=true;
if (config.options.chkSearchTitlesFirst===undefined) config.options.chkSearchTitlesFirst=false;
if (config.options.chkSearchList===undefined) config.options.chkSearchList=false;
if (config.options.chkSearchByDate===undefined) config.options.chkSearchByDate=false;
if (config.options.chkSearchIncremental===undefined) config.options.chkSearchIncremental=true;
if (config.options.chkSearchShadows===undefined) config.options.chkSearchShadows=false;

if (config.optionsDesc) {
	config.optionsDesc.chkSearchTitles="Search in tiddler titles";
	config.optionsDesc.chkSearchText="Search in tiddler text";
	config.optionsDesc.chkSearchTags="Search in tiddler tags";
	config.optionsDesc.chkSearchFields="Search in tiddler data fields";
	config.optionsDesc.chkSearchShadows="Search in shadow tiddlers";
	config.optionsDesc.chkSearchTitlesFirst="Search results show title matches first";
	config.optionsDesc.chkSearchList="Search results show list of matching tiddlers";
	config.optionsDesc.chkSearchByDate="Search results sorted by modification date ";
	config.optionsDesc.chkSearchIncremental="Incremental searching";
} else {
	config.shadowTiddlers.AdvancedOptions += "\n<<option chkSearchTitles>> Search in tiddler titles"
		+"\n<<option chkSearchText>> Search in tiddler text"
		+"\n<<option chkSearchTags>> Search in tiddler tags"
		+"\n<<option chkSearchFields>> Search in tiddler data fields"
		+"\n<<option chkSearchShadows>> Search in shadow tiddlers"
		+"\n<<option chkSearchTitlesFirst>> Search results show title matches first"
		+"\n<<option chkSearchList>> Search results show list of matching tiddlers"
		+"\n<<option chkSearchByDate>> Search results sorted by modification date"
		+"\n<<option chkSearchIncremental>> Incremental searching";
}

if (config.macros.search.reportTitle==undefined)
	config.macros.search.reportTitle="SearchResults";

config.macros.search.onKeyPress = function(e)
{
	if(!e) var e = window.event;
	switch(e.keyCode)
		{
		case 13: // Ctrl-Enter
		case 10: // Ctrl-Enter on IE PC
			config.macros.search.doSearch(this);
			break;
		case 27: // Escape
			this.value = "";
			clearMessage();
			break;
		}
	if (config.options.chkSearchIncremental) {
		if(this.value.length > 2)
			{
			if(this.value != this.getAttribute("lastSearchText"))
				{
				if(config.macros.search.timeout)
					clearTimeout(config.macros.search.timeout);
				var txt = this;
				config.macros.search.timeout = setTimeout(function() {config.macros.search.doSearch(txt);},500);
				}
			}
		else
			{
			if(config.macros.search.timeout)
				clearTimeout(config.macros.search.timeout);
			}
	}
}
//}}}

//{{{
Story.prototype.search = function(text,useCaseSensitive,useRegExp)
{
	highlightHack = new RegExp(useRegExp ? text : text.escapeRegExp(),useCaseSensitive ? "mg" : "img");
	var matches = store.search(highlightHack,config.options.chkSearchByDate?"modified":"title","excludeSearch");
	if (config.options.chkSearchByDate) matches=matches.reverse(); // most recent changes first
	var q = useRegExp ? "/" : "'";
	clearMessage();
	if (!matches.length) {
		if (config.options.chkSearchList) discardSearchResults();
		displayMessage(config.macros.search.failureMsg.format([q+text+q]));
	} else {
		if (config.options.chkSearchList) 
			reportSearchResults(text,matches);
		else {
			var titles = []; for(var t=0; t<matches.length; t++) titles.push(matches[t].title);
			this.closeAllTiddlers(); story.displayTiddlers(null,titles);
			displayMessage(config.macros.search.successMsg.format([matches.length, q+text+q]));
		}
	}
	highlightHack = null;
}

TiddlyWiki.prototype.search = function(searchRegExp,sortField,excludeTag)
{
	var candidates = this.reverseLookup("tags",excludeTag,false,sortField);

	// scan for matching titles first...
	var results = [];
	if (config.options.chkSearchTitles) {
		for(var t=0; t<candidates.length; t++)
			if(candidates[t].title.search(searchRegExp)!=-1)
				results.push(candidates[t]);
		if (config.options.chkSearchShadows)
			for (var t in config.shadowTiddlers)
				if ((t.search(searchRegExp)!=-1) && !store.tiddlerExists(t))
					results.push((new Tiddler()).assign(t,config.shadowTiddlers[t]));
	}
	// then scan for matching text, tags, or field data
	for(var t=0; t<candidates.length; t++) {
		if (config.options.chkSearchText && candidates[t].text.search(searchRegExp)!=-1)
			results.pushUnique(candidates[t]);
		if (config.options.chkSearchTags && candidates[t].tags.join(" ").search(searchRegExp)!=-1)
			results.pushUnique(candidates[t]);
		if (config.options.chkSearchFields && store.forEachField!=undefined) // requires TW2.1 or above
			store.forEachField(candidates[t],
				function(tid,field,val) { if (val.search(searchRegExp)!=-1) results.pushUnique(candidates[t]); },
				true); // extended fields only
	}
	// then check for matching text in shadows
	if (config.options.chkSearchShadows)
		for (var t in config.shadowTiddlers)
			if ((config.shadowTiddlers[t].search(searchRegExp)!=-1) && !store.tiddlerExists(t))
				results.pushUnique((new Tiddler()).assign(t,config.shadowTiddlers[t]));

	// if not 'titles first', or sorting by modification date,  re-sort results to so titles, text, tag and field matches are mixed together
	if(!sortField) sortField = "title";
	var bySortField=function (a,b) {if(a[sortField] == b[sortField]) return(0); else return (a[sortField] < b[sortField]) ? -1 : +1; }
	if (!config.options.chkSearchTitlesFirst || config.options.chkSearchByDate) results.sort(bySortField);

	return results;
}

// REPORT GENERATOR
if (!window.reportSearchResults) window.reportSearchResults=function(text,matches)
{
	var title=config.macros.search.reportTitle
	var q = config.options.chkRegExpSearch ? "/" : "'";
	var body="\n";

	// summary: nn tiddlers found matching '...', options used
	body+="''"+config.macros.search.successMsg.format([matches.length,q+"{{{"+text+"}}}"+q])+"''\n";
	body+="^^//searched in:// ";
	body+=(config.options.chkSearchTitles?"''titles'' ":"");
	body+=(config.options.chkSearchText?"''text'' ":"");
	body+=(config.options.chkSearchTags?"''tags'' ":"");
	body+=(config.options.chkSearchFields?"''fields'' ":"");
	body+=(config.options.chkSearchShadows?"''shadows'' ":"");
	if (config.options.chkCaseSensitiveSearch||config.options.chkRegExpSearch) {
		body+=" //with options:// ";
		body+=(config.options.chkCaseSensitiveSearch?"''case sensitive'' ":"");
		body+=(config.options.chkRegExpSearch?"''text patterns'' ":"");
	}
	body+="^^";

	// numbered list of links to matching tiddlers
	body+="\n<<<";
	for(var t=0;t<matches.length;t++) {
		var date=config.options.chkSearchByDate?(matches[t].modified.formatString('YYYY.0MM.0DD 0hh:0mm')+" "):"";
		body+="\n# "+date+"[["+matches[t].title+"]]";
	}
	body+="\n<<<\n";

	// open all matches button
	body+="<html><input type=\"button\" href=\"javascript:;\" ";
	body+="onclick=\"story.displayTiddlers(null,["
	for(var t=0;t<matches.length;t++)
		body+="'"+matches[t].title.replace(/\'/mg,"\\'")+"'"+((t<matches.length-1)?", ":"");
	body+="],1);\" ";
	body+="accesskey=\"O\" ";
	body+="value=\"open all matching tiddlers\"></html> ";

	// discard search results button
	body+="<html><input type=\"button\" href=\"javascript:;\" ";
	body+="onclick=\"story.closeTiddler('"+title+"'); store.deleteTiddler('"+title+"'); store.notify('"+title+"',true);\" ";
	body+="value=\"discard "+title+"\"></html>";

	// search again
	body+="\n\n----\n";
	body+="<<search \""+text+"\">>\n";
	body+="<<option chkSearchTitles>>titles ";
	body+="<<option chkSearchText>>text ";
	body+="<<option chkSearchTags>>tags";
	body+="<<option chkSearchFields>>fields";
	body+="<<option chkSearchShadows>>shadows";
	body+="<<option chkCaseSensitiveSearch>>case-sensitive ";
	body+="<<option chkRegExpSearch>>text patterns";
	body+="<<option chkSearchByDate>>sort by date";

	// create/update the tiddler
	var tiddler=store.getTiddler(title); if (!tiddler) tiddler=new Tiddler();
	tiddler.set(title,body,config.options.txtUserName,(new Date()),"excludeLists excludeSearch temporary");
	store.addTiddler(tiddler); story.closeTiddler(title);

	// use alternate "search again" label in <<search>> macro
	var oldprompt=config.macros.search.label;
	config.macros.search.label="search again";

	// render/refresh tiddler
	story.displayTiddler(null,title,1);
	store.notify(title,true);

	// restore standard search label
	config.macros.search.label=oldprompt;

}

if (!window.discardSearchResults) window.discardSearchResults=function()
{
	// remove the tiddler
	story.closeTiddler(config.macros.search.reportTitle);
	store.deleteTiddler(config.macros.search.reportTitle);
}
//}}}
<<<
# [[DirectedEvolutionPy]]
# [[DirectedGAPy]]
# [[Entropy01]]
# [[FrontPage]]
# [[L01]]
# [[L01.00]]
# [[L01.01]]
# [[L01.02]]
# [[L01.03]]
# [[L01.04]]
# [[L01.05]]
# [[L01.06]]
# [[L01.07]]
# [[L01.08]]
# [[L01.09]]
# [[L01.10]]
# [[L01.11]]
# [[L01.12]]
# [[L02]]
# [[L02.00]]
# [[L02.01]]
# [[L02.02]]
# [[L02.03]]
# [[L02.04]]
# [[L02.05]]
# [[L02.06]]
# [[L02.07]]
# [[L02.08]]
# [[L02.09]]
# [[L02.10]]
# [[L02.11]]
# [[L02.12]]
# [[L02.13]]
# [[L02.14]]
# [[L03]]
# [[L03.01]]
# [[L03.02]]
# [[L03.03]]
# [[L03.04]]
# [[L03.05]]
# [[L03.06]]
# [[L03.07]]
# [[L03.08]]
# [[L03.09]]
# [[L03.10]]
# [[L03.11]]
# [[L03.12]]
# [[Lecture Index]]
# [[Lecture Template]]
# [[Library of Babel]]
# [[MainMenu]]
# [[MonkeysTyping]]
# [[Syllabus]]
# [[What's New?]]
<<<
/***
Quick and dirtly palette switcher for 2.1.x
<<selectPalette>>
WARNING this will overwrite your ColorPalette tiddler.
***/

//{{{

merge(config.macros,{

	setPalette: {

		handler: function(place,macroName,params,wikifier,paramString,tiddler) {
			var paletteName = params[0] ? params[0] : tiddler.title;
			createTiddlyButton(place,"apply","Apply this palette",function(e) {
				config.macros.selectPalette.updatePalette(tiddler.title);
				return false;
			});
		}
	},

	selectPalette: {

		handler: function(place,macroName,params,wikifier,paramString,tiddler) {
			createTiddlyDropDown(place,this.onPaletteChange,this.getPalettes());
		},

		getPalettes: function() {
			var result = [
				{caption:"-select palette-", name:""},
				{caption:"(Default)", name:"(default)"}
			];
			var tagged = store.getTaggedTiddlers("palette","title");
			for(var t=0; t<tagged.length; t++)
				result.push({caption:tagged[t].title, name:tagged[t].title});
			return result;
		},

		onPaletteChange: function(e) {
			config.macros.selectPalette.updatePalette(this.value);
			return true;
		},

		updatePalette: function(title) {
			if (title != "") {
				store.deleteTiddler("ColorPalette");
				if (title != "(default)")
					store.saveTiddler("ColorPalette","ColorPalette",store.getTiddlerText(title),
								config.options.txtUserName,undefined,"");
				this.refreshPalette();
				if(config.options.chkAutoSave)
					saveChanges(true);
			}
		},

		refreshPalette: function() {
			config.macros.refreshDisplay.onClick();
		}
	}
});

//}}}
<<search>><<closeAll>><<permaview>><<newTiddler>><<newTiddler title:"tagnameSubtopicMenu" tag:"SubtopicMenu" label:"new subtopic menu" text:"{{tableindex{
|[[subtopic1]]|[[subtopic2]]|[[subtopic3]]|
}}}">><<newTiddler title:"tagnameViewTemplate" tag:"excludeLists" label:"new viewtemplate" text:"<!--{{{-->
<div class='toolbar' macro='toolbar closeTiddler closeOthers +editTiddler > fields syncing permalink references jump'></div>
<div class='xxxx' macro='tiddler xxxxSubtopicMenu'></div><div class='title' macro='view title'></div>
<div class='viewer' macro='view text wikified'></div><div class='tagClear'></div>
<!--}}}-->
">><<saveChanges>>[[Formatting cheatsheet]]<<selectPalette>><<slider chkSliderOptionsPanel OptionsPanel "options »" "Change TiddlyWiki advanced options">>

<<tabs txtMainTab "Timeline" "Timeline" TabTimeline "All" "All tiddlers" TabAll "Tags" "All tags" TabTags "More" "More lists" TabMore>>
/***
|Name|SinglePageModePlugin|
|Source|http://www.TiddlyTools.com/#SinglePageModePlugin|
|Documentation|http://www.TiddlyTools.com/#SinglePageModePluginInfo|
|Version|2.8.2|
|Author|Eric Shulman - ELS Design Studios|
|License|http://www.TiddlyTools.com/#LegalStatements <br>and [[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]|
|~CoreVersion|2.1|
|Type|plugin|
|Requires||
|Overrides|Story.prototype.displayTiddler(), Story.prototype.displayTiddlers()|
|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 chkSinglePageKeepFoldedTiddlers>> Don't auto-close folded tiddlers
><<option chkSinglePagePermalink>> Automatically permalink current tiddler
<<option chkTopOfPageMode>> Always open tiddlers at the top of the page
<<option chkBottomOfPageMode>> Always 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
<<<
2008.03.14 [2.8.2] in displayTiddler(), if editing specified tiddler, just move it to top/bottom of story *without* re-rendering (prevents discard of partial edits).
| 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.SinglePageMode= {major: 2, minor: 8, revision: 2, date: new Date(2008,3,14)};
//}}}
//{{{
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.chkSinglePageKeepFoldedTiddlers==undefined) config.options.chkSinglePageKeepFoldedTiddlers=true;
if (config.options.chkSinglePagePermalink==undefined) config.options.chkSinglePagePermalink=true;
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=true;

if (config.optionsDesc) {
	config.optionsDesc.chkSinglePageMode="Display one tiddler at a time";
	config.optionsDesc.chkSinglePageKeepFoldedTiddlers="Don't auto-close folded tiddlers";
	config.optionsDesc.chkSinglePagePermalink="Automatically permalink current tiddler";
	config.optionsDesc.chkSinglePageAutoScroll="Automatically scroll tiddler into view (if needed)";
	config.optionsDesc.chkTopOfPageMode="Always open tiddlers at the top of the page";
	config.optionsDesc.chkBottomOfPageMode="Always open tiddlers at the bottom of the page";
} else {
	config.shadowTiddlers.AdvancedOptions += "\
		\n<<option chkSinglePageMode>> Display one tiddler at a time \
		\n<<option chkSinglePageKeepFoldedTiddlers>> Don't auto-close folded tiddlers \
		\n<<option chkSinglePagePermalink>> Automatically permalink current tiddler \
		\n<<option chkSinglePageAutoScroll>> Automatically scroll tiddler into view (if needed) \
		\n<<option chkTopOfPageMode>> Always open tiddlers at the top of the page \
		\n<<option chkBottomOfPageMode>> Always open tiddlers at the bottom of the page";
}
//}}}
//{{{
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=convertUTF8ToUnicode(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,title,template,animate,slowly)
{
	var opt=config.options;
	if (opt.chkSinglePageMode) {
		// close all tiddlers except current tiddler, tiddlers being edited, and tiddlers that are folded (optional)
		story.forEachTiddler(function(tid,elem) {
			if (	tid==title
				|| elem.getAttribute("dirty")=="true"
				|| (opt.chkSinglePageKeepFoldedTiddlers && elem.getAttribute("folded")=="true"))
				return;
			story.closeTiddler(tid);
		});
	}
	else if (opt.chkTopOfPageMode)
		arguments[0]=null;
	else if (opt.chkBottomOfPageMode)
		arguments[0]="bottom";
	if (opt.chkSinglePageMode && opt.chkSinglePagePermalink && !config.browser.isSafari) {
		window.location.hash = encodeURIComponent(convertUnicodeToUTF8(String.encodeTiddlyLink(title)));
		config.lastURL = window.location.hash;
		document.title = wikifyPlain("SiteTitle") + " - " + title;
		if (!config.SPMTimer) config.SPMTimer=window.setInterval(function() {checkLastURL();},1000);
	}
	var tiddlerElem=document.getElementById(story.idPrefix+title); // ==null unless tiddler is already display
	if (tiddlerElem && tiddlerElem.getAttribute("dirty")=="true") { // editing... move tiddler without re-rendering
		var isTopTiddler=(tiddlerElem.previousSibling==null);
		if (!isTopTiddler && (opt.chkSinglePageMode || opt.chkTopOfPageMode))
			tiddlerElem.parentNode.insertBefore(tiddlerElem,tiddlerElem.parentNode.firstChild);
		else if (opt.chkBottomOfPageMode)
			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=document.getElementById(story.idPrefix+title);
	if (tiddlerElem&&opt.chkSinglePageAutoScroll) {
		var yPos=ensureVisible(tiddlerElem); // scroll to top of tiddler
		var isTopTiddler=(tiddlerElem.previousSibling==null);
		if (opt.chkSinglePageMode||opt.chkTopOfPageMode||isTopTiddler)
			yPos=0; // scroll to top of page instead of top of tiddler
		if (opt.chkAnimate) // defer scroll until 200ms after animation completes
			setTimeout("window.scrollTo(0,"+yPos+")",config.animDuration+200); 
		else
			window.scrollTo(0,yPos); // scroll immediately
	}
}

if (Story.prototype.SPM_coreDisplayTiddlers==undefined)
	Story.prototype.SPM_coreDisplayTiddlers=Story.prototype.displayTiddlers;

Story.prototype.displayTiddlers = function() {
	// suspend single-page mode (and/or top/bottom display options) 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;
}
//}}}

MAST867 Bioinformatics Research
/***
|''Name:''|SparklinePlugin|
|''Description:''|Sparklines macro|
***/
//{{{
if(!version.extensions.SparklinePlugin) {
version.extensions.SparklinePlugin = {installed:true};

//--
//-- Sparklines
//--

config.macros.sparkline = {};
config.macros.sparkline.handler = function(place,macroName,params)
{
	var data = [];
	var min = 0;
	var max = 0;
	var v;
	for(var t=0; t<params.length; t++) {
		v = parseInt(params[t]);
		if(v < min)
			min = v;
		if(v > max)
			max = v;
		data.push(v);
	}
	if(data.length < 1)
		return;
	var box = createTiddlyElement(place,"span",null,"sparkline",String.fromCharCode(160));
	box.title = data.join(",");
	var w = box.offsetWidth;
	var h = box.offsetHeight;
	box.style.paddingRight = (data.length * 2 - w) + "px";
	box.style.position = "relative";
	for(var d=0; d<data.length; d++) {
		var tick = document.createElement("img");
		tick.border = 0;
		tick.className = "sparktick";
		tick.style.position = "absolute";
		tick.src = "data:image/gif,GIF89a%01%00%01%00%91%FF%00%FF%FF%FF%00%00%00%C0%C0%C0%00%00%00!%F9%04%01%00%00%02%00%2C%00%00%00%00%01%00%01%00%40%02%02T%01%00%3B";
		tick.style.left = d*2 + "px";
		tick.style.width = "2px";
		v = Math.floor(((data[d] - min)/(max-min)) * h);
		tick.style.top = (h-v) + "px";
		tick.style.height = v + "px";
		box.appendChild(tick);
	}
};


}
//}}}
/***

''Inspired by [[TiddlyPom|http://www.warwick.ac.uk/~tuspam/tiddlypom.html]]''

|Name|SplashScreenPlugin|
|Created by|SaqImtiaz|
|Location|http://tw.lewcid.org/#SplashScreenPlugin|
|Version|0.21 |
|Requires|~TW2.08+|
!Description:
Provides a simple splash screen that is visible while the TW is loading.

!Installation
Copy the source text of this tiddler to your TW in a new tiddler, tag it with systemConfig and save and reload. The SplashScreen will now be installed and will be visible the next time you reload your TW.

!Customizing
Once the SplashScreen has been installed and you have reloaded your TW, the splash screen html will be present in the MarkupPreHead tiddler. You can edit it and customize to your needs.

!History
* 20-07-06 : version 0.21, modified to hide contentWrapper while SplashScreen is displayed.
* 26-06-06 : version 0.2, first release

!Code
***/
//{{{
var old_lewcid_splash_restart=restart;

restart = function()
{   if (document.getElementById("SplashScreen"))
        document.getElementById("SplashScreen").style.display = "none";
      if (document.getElementById("contentWrapper"))
        document.getElementById("contentWrapper").style.display = "block";
    
    old_lewcid_splash_restart();
   
    if (splashScreenInstall)
       {if(config.options.chkAutoSave)
			{saveChanges();}
        displayMessage("TW SplashScreen has been installed, please save and refresh your TW.");
        }
}


var oldText = store.getTiddlerText("MarkupPreHead");
if (oldText.indexOf("SplashScreen")==-1)
   {var siteTitle = store.getTiddlerText("SiteTitle");
   var splasher='\n\n<style type="text/css">#contentWrapper {display:none;}</style><div id="SplashScreen" style="border: 3px solid #ccc; display: block; text-align: center; width: 320px; margin: 100px auto; padding: 50px; color:#000; font-size: 28px; font-family:Tahoma; background-color:#eee;"><b>'+siteTitle +'</b> is loading<blink> ...</blink><br><br><span style="font-size: 14px; color:red;">Requires Javascript.</span></div>';
   if (! store.tiddlerExists("MarkupPreHead"))
       {var myTiddler = store.createTiddler("MarkupPreHead");}
   else
      {var myTiddler = store.getTiddler("MarkupPreHead");}
      myTiddler.set(myTiddler.title,oldText+splasher,config.options.txtUserName,null,null);
      store.setDirty(true);
      var splashScreenInstall = true;
}
//}}}
/*{{{*/
/*FONT ADJUSTMENTS*/
body {font-family: Trebuchet MS; font-size: 10pt;}
#mainMenu .tiddlyLinkExisting, #mainMenu .tiddlyLinkNonExisting {font-family: Trebuchet MS; font-size: 10pt;}
#mainMenu {font-family: Trebuchet MS; font-size: 10pt;}
#mainMenu h1 {font-size: 10pt;}
#mainMenu th {background-color:[[ColorPalette::SecondaryPale]]; color:[[ColorPalette::SecondaryDark]];}
#mainMenu table {border:none;}
#mainMenu tr {background-color:white;}
#mainMenu {background-color:[[ColorPalette::PrimaryLight]];}
.viewer {line-height: 1.7em;}
/*WIDEN MAINMENU*/
#mainMenu {width: 14.5em;}
#mainMenu {text-align: left;}
#displayArea {margin: 0em 17em 0em 17em;}
.teeny {font-size: 9pt; text-align: center;}
/*TABLE HEADER*/
.viewer th {color: #000; background-color: #eeeeee;} 
/*TIDDLER TOPMARGIN AND BUTTON BORDER*/
a.button{border: 0;} 
.viewer { margin-top: 1em; }
/*UNORDERED and ORDERED LISTS TWEAK*/
.viewer li {padding-top: 0.0em; padding-bottom: 0.0em;} 
/*LINELESS BLOCKQUOTES*/
.viewer blockquote {border-left: 0px; margin-top:0em; margin-bottom:0em; }
/*HEADLINE COLOR, etc*/
h1,h2,h3,h4,h5 { color: #000; background: none; font-family: Trebuchet MS;}
/*TuDuSlider*/
.tuduSlider .button{font-family: Trebuchet MS; font-weight: bold; font-size: 10pt; color: black;}
/* GIFFMEX TWEAKS TO STYLESHEETPRINT (so that nothing but tiddler title and text are printed) */
@media print {#mainMenu {display: none ! important;}}
@media print {#topMenu {display: none ! important;}}
@media print {#sidebar {display: none ! important;}}
@media print {#messageArea {display: none ! important;}} 
@media print {#toolbar {display: none ! important;}}
@media print {.header {display: none ! important;}}
@media print {.tiddler .subtitle {display: none ! important;}}
@media print {.tiddler .toolbar {display; none ! important; }}
@media print {.tiddler .tagging {display; none ! important; }}
@media print {.tiddler .tagged {display; none ! important; }}
@media print {#displayArea {margin: 1em 1em 0em 1em;}}
@media print {.pageBreak {page-break-before: always;}}
/*CSS FOR BIBLE FORMATTING*/
.engindent {margin-left: 2em; display:block;}
.gkindent {font-family: Gentium; font-size: 16pt; margin-left: 2em; display:block;}
.greek {font-family: Gentium; font-size: 16pt;}
.hebrewNoAlign{font-family: Gentium; font-size: 20pt;}
.hebrewRightAlign{text-align:right; font-family: Gentium; font-size: 20pt; display:block;}
.hebAlignAndIndent{text-align:right; font-family: Gentium; font-size: 20pt; margin-right: 2em; display:block;}
.red {color: #ff3300; font-weight: bold;}
.blue {color: #0000cc; font-weight: bold;}
.green {color: #22bb00; font-weight: bold;}
.gold {color: #bbaa55; font-weight: bold;}
.purple {color: #9922ff; font-weight: bold;}
.gray {color: #777777; font-weight: bold;}
.magenta{color: #cc0066; font-weight: bold;}
.teal {color: #008888; font-weight: bold;}
.burgundy {color: #990000; font-weight: bold;}
.orange {color: #ff8866; font-weight: bold;}
/*INVISIBLE TABLE*/
.viewer .invisiblecomm table {border-color: white;}
.viewer .invisiblecomm table td { font-size: 1em; font-family: Verdana; border-color: white; padding: 10px 20px 10px 0px; text-align: left; vertical-align: top; padding-bottom: 20px;} 
.viewer .invisiblecomm table th {color:[[ColorPalette::PrimaryMid]]; background-color: white; border-color: white; font-family: Verdana; font-size: 1.2em; font-weight: bold; padding: 10px 20px 10px 0px; text-align: left; vertical-align: top;} 
.viewer .invisiblecomm table tr.leftColumn { background-color: #bbbbbb; }
/*OTHER TABLES*/
.menubox { display:block; padding:1em; -moz-border-radius:1em; border:1px solid; background:[[ColorPalette::TertiaryDark]]; color:#000; }
.menubox2 { display:block; padding: .25em; border:none; margin: 0; background:[[ColorPalette::TertiaryDark]]; [[ColorPalette::SecondaryDark]]; text-align: center; font-size: 1.6em;}
.menubox3 { display:block; padding:.25em; border:none; margin: 0; background:[[ColorPalette::TertiaryDark]]; [[ColorPalette::SecondaryDark]]; text-align: center; font-size: 2.5em;}
.viewer th {background-color:[[ColorPalette::SecondaryPale]]; [[ColorPalette::SecondaryDark]]}
.tableindex table, .tableindex td, .tableindex tr { font-size: 1em; border: solid white; background-color:[[ColorPalette::SecondaryPale]]; [[ColorPalette::SecondaryDark]]}
/*}}}*/
/*{{{*/
* 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 0em 1em 1em; left:-1px; top:-1px;}
.headerForeground {position:absolute; padding:4.5em 0em 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:0em 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 .3em 0;}
#sidebarTabs .tabContents {width:15em; overflow:hidden;}

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

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

.tiddlerPopupButton {padding:0.2em 0.2em 0.2em 0.2em;}
.popupTiddler {position: absolute; z-index:300; padding:1em 1em 1em 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 0em;}
.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 0em 0em 0.5em;}
.tab {margin:0em 0em 0em 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 0em 14em;}

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

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

.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:0em 0.25em; padding:0em 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.0em; line-height:1.0em; overflow:auto;}
.viewer code {font-size:1.0em; line-height:1.0em;}

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

.fieldsetFix {border:0; padding:0; margin:1px 0px 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 0.3em 0.5em;}
#backstageToolbar {position:relative;}
#backstageArea a {font-weight:bold; margin-left:0.5em; padding:0.3em 0.5em 0.3em 0.5em;}
#backstageButton {display:none; position:absolute; z-index:175; top:0em; right:0em;}
#backstageButton a {padding:0.1em 0.4em 0.1em 0.4em; margin:0.1em 0.1em 0.1em 0.1em;}
#backstage {position:relative; width:100%; z-index:50;}
#backstagePanel {display:none; z-index:100; position:absolute; margin:0em 3em 0em 3em; padding:1em 1em 1em 1em;}
.backstagePanelFooter {padding-top:0.2em; float:right;}
.backstagePanelFooter a {padding:0.2em 0.4em 0.2em 0.4em;}
#backstageCloak {display:none; z-index:20; position:absolute; width:100%; height:100px;}

.whenBackstage {display:none;}
.backstageVisible .whenBackstage {display:block;}
/*}}}*/
Subtopic menus are menus at the top of the topic tiddlers, like the one above, which has three subtopics: "Welcome", "Instructions", and "Subtopic menu instructions". You can have a separate subtopic menu for as many topics as you add to your mainmenu. There are three steps to creating a new subtopic menu. You may do these steps in any order you wish:
#''Create tiddlers for each of the subtopics within a topic.'' Tag them all with one appropriate tag pertaining to the topic. This will link them all so that they appear in the subtopic menu.
#''Create a subtopic menu tiddler.'' This will be the tiddler where the menu that appears above the other tiddlers is stored. In the Sidebar, click on 'new subtopic menu'. Replace 'tagname' in the title with the name of the tag you added to the tiddlers above. Then add the title of your subtopic tiddlers in the table provided, within the double brackets {{{[[ ]]}}}. Three table cells have been provided. Delete or add table cells as needed.
#''Create a custom ~ViewTemplate for your topic.'' This will tell ~TiddlyWiki to show your subtopic menu at the top of all the tiddlers that you have tagged with that topic's tag. In the Sidebar, click on 'new viewtemplate'. Replace 'tagname' with the tag you added to the tiddlers above. Do this for the title of the tiddler, as well as in the two instances of 'tagname' in the viewtemplate's code (it will look like the line shown below before you change it).
<!--{{{-->
<div class='tagnameMacro='tiddler tagnameSubtopicmenu'></div>
<!--}}}-->
That's it. A menu of links to the tiddlers you have tagged and added to your subtopic menu tiddler should appear above the tiddler title of each of those tiddlers.
!Computational Requirements:
* You will need a user account on [[Biowolf]]
* Biowolf will provide you access to these following programs (see [[Resources|Resource Index]]):
** [[Perl|PERL]], [[Python|python]], [[R Statistics Package|r]], [[Rpy|Rpy]], [[NumPy|Npy]], [[PyLab|MatPlotLib]]
* It is @@HIGHLY@@ recommended that you have these programs also installed and configured on your own computer:
** A laptop so that when we meet in class you can work on code
** AND it would also be a good idea to find an old PC desktop that wasn't being used and installed a linux distro on it ([[Ubuntu|http://www.ubuntu.com]]), and then put these python modules on it and used the linux box as your programming/working machine. 

!Course Summary:
For the first 4 lectures, we will meet jointly with Prof. Miller's course in Multivariate Statistics. On March 20th, students will present their research proposal ideas for class feedback. The remainder of the semester will involve an individual project discussion with me each week to be scheduled at a time of mutual convenience. Presentations of the research projects will be on 15MAY, with final reports due during Finals week.  
|! DATE |! Statistics |! Informatics |
|FEB 20 | Multivariate Data | [[Recombinatorial Diversity|L01]] |
|FEB 27 | Principal Component Analysis | Programming Tools |
|MAR 06 | Multidimensional Scaling | Modeling & Bootstrapping |
|MAR 13 | Correspondence Analysis | Graphics Tools |
|MAR 20 | | Project Proposals |
|MAR 27 | | Project Discussions |
|APR 03 |>|bgcolor(yellow): SPRING BREAK |
|APR 10 | | Project Discussions |
|APR 17 | | Project Discussions |
|APR 24 | | Project Discussions |
|MAY 01 | | Project Discussions |
|MAY 08 | | Project Discussions |
|MAY 15 |>|bgcolor(lightgreen): Project Presentations |
|MAY 22 |>|bgcolor(lightgreen): Project Reports |
/***
|Name|TaggedTemplateTweak|
|Source|http://www.TiddlyTools.com/#TaggedTemplateTweak|
|Documentation|http://www.TiddlyTools.com/#TaggedTemplateTweakInfo|
|Version|1.1.0|
|Author|Eric Shulman - ELS Design Studios|
|License|http://www.TiddlyTools.com/#LegalStatements <br>and [[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]|
|~CoreVersion|2.1|
|Type|plugin|
|Requires||
|Overrides|Story.prototype.chooseTemplateForTiddler()|
|Description|use alternative ViewTemplate/EditTemplate for tiddler's tagged with specific tag values|
This tweak extends story.chooseTemplateForTiddler() so that ''whenever a tiddler is marked with a specific tag value, it can be viewed and/or edited using alternatives to the standard tiddler templates.'' 
!!!!!Documentation
>see [[TaggedTemplateTweakInfo]]
!!!!!Revisions
<<<
2008.01.22 [*.*.*] plugin size reduction - documentation moved to [[TaggedTemplateTweakInfo]]
2007.06.23 [1.1.0] re-written to use automatic 'tag prefix' search instead of hard coded check for each tag.  Allows new custom tags to be used without requiring code changes to this plugin.
| please see [[TaggedTemplateTweakInfo]] for previous revision details |
2007.06.11 [1.0.0] initial release
<<<
!!!!!Code
***/
//{{{
version.extensions.taggedTemplate= {major: 1, minor: 1, revision: 0, date: new Date(2007,6,23)};
Story.prototype.taggedTemplate_chooseTemplateForTiddler = Story.prototype.chooseTemplateForTiddler
Story.prototype.chooseTemplateForTiddler = function(title,template)
{
	// get default template from core
	var template=this.taggedTemplate_chooseTemplateForTiddler.apply(this,arguments);

	// if the tiddler to be rendered doesn't exist yet, just return core result
	var tiddler=store.getTiddler(title); if (!tiddler) return template;

	// look for template whose prefix matches a tag on this tiddler
	for (t=0; t<tiddler.tags.length; t++) {
		var tag=tiddler.tags[t];
		if (store.tiddlerExists(tag+template)) { template=tag+template; break; }
		// try capitalized tag (to match WikiWord template titles)
		var cap=tag.substr(0,1).toUpperCase()+tag.substr(1);
		if (store.tiddlerExists(cap+template)) { template=cap+template; break; }
	}

	return template;
}
//}}}
{{{
<html>
<div style="color: rgb(100, 100, 150); font-family: Monaco;">
<big><big><b>
xxxx
</html>
}}}
/%
|Name|ToggleRightSidebar|
|Source|http://www.TiddlyTools.com/#ToggleRightSidebar|
|Version|1.0.0|
|Author|Eric Shulman - ELS Design Studios|
|License|http://www.TiddlyTools.com/#LegalStatements <br>and [[Creative Commons Attribution-ShareAlike 2.5 License|http://creativecommons.org/licenses/by-sa/2.5/]]|
|~CoreVersion|2.1|
|Type|script|
|Requires|InlineJavascriptPlugin|
|Overrides||
|Description|show/hide right sidebar (SideBarOptions)|

Usage: <<tiddler ToggleRightSidebar>>

Config settings:
	config.options.txtToggleRightSideBarLabelShow (◄)
	config.options.txtToggleRightSideBarLabelHide (►)
	config.options.txtToggleRightSideBarTipShow ("show right sidebar")
	config.options.txtToggleRightSideBarTipHide ("hide right sidebar")

%/<script label="show/hide right sidebar">
	var sb=document.getElementById('sidebar'); if (!sb) return;
	var show=sb.style.display=='none';
	if (!show) { sb.style.display='none'; var margin='1em'; }
	else { sb.style.display='block'; var margin=config.options.txtDisplayAreaRightMargin||''; }
	if (typeof(place)!='undefined') {
		place.innerHTML=show?
			config.options.txtToggleRightSideBarLabelHide:config.options.txtToggleRightSideBarLabelShow;
		place.title=show?
			config.options.txtToggleRightSideBarTipHide:config.options.txtToggleRightSideBarTipShow;
	}
	document.getElementById('displayArea').style.marginRight=margin;
	config.options.chkShowRightSidebar=show;
	saveOptionCookie('chkShowRightSidebar');
	var sm=document.getElementById('storyMenu'); if (sm) config.refreshers.content(sm);
	return false;
</script><script>
	if (config.options.chkShowRightSidebar==undefined)
		config.options.chkShowRightSidebar=true;
	if (!config.options.txtDisplayAreaRightMargin||!config.options.txtDisplayAreaRightMargin.length)
		config.options.txtDisplayAreaRightMargin="18em";
	if (config.options.txtToggleRightSideBarLabelShow==undefined)
		config.options.txtToggleRightSideBarLabelShow=config.browser.isSafari?"&#x25c0;":"&#x25c4;";
	if (config.options.txtToggleRightSideBarLabelHide==undefined)
		config.options.txtToggleRightSideBarLabelHide="&#x25ba;";
	if (config.options.txtToggleRightSideBarTipShow==undefined)
		config.options.txtToggleRightSideBarTipShow="show right sidebar";
	if (config.options.txtToggleRightSideBarTipHide==undefined)
		config.options.txtToggleRightSideBarTipHide="hide right sidebar";

	var show=config.options.chkShowRightSidebar;
	document.getElementById('sidebar').style.display=show?"block":"none";
	document.getElementById('displayArea').style.marginRight=show?
		config.options.txtDisplayAreaRightMargin:"1em";
	place.lastChild.innerHTML=show?
		config.options.txtToggleRightSideBarLabelHide:config.options.txtToggleRightSideBarLabelShow;
	place.lastChild.title=show?
		config.options.txtToggleRightSideBarTipHide:config.options.txtToggleRightSideBarTipShow;
	place.lastChild.style.fontWeight="normal";
</script>
|!History:|!<<back>>|>|!<<history>>|>|!<<forward>>|
|!Font size:|>|>|>|>|! <<fontSize>>|
|!Sidebar:|>|>|>|>|!<<tiddler ToggleRightSidebar>>|
/***
|''Name:''|UploadPlugin|
|''Description:''|Save to web a TiddlyWiki|
|''Version:''|4.1.3|
|''Date:''|Feb 24, 2008|
|''Source:''|http://tiddlywiki.bidix.info/#UploadPlugin|
|''Documentation:''|http://tiddlywiki.bidix.info/#UploadPluginDoc|
|''Author:''|BidiX (BidiX (at) bidix (dot) info)|
|''License:''|[[BSD open source license|http://tiddlywiki.bidix.info/#%5B%5BBSD%20open%20source%20license%5D%5D ]]|
|''~CoreVersion:''|2.2.0|
|''Requires:''|PasswordOptionPlugin|
***/
//{{{
version.extensions.UploadPlugin = {
	major: 4, minor: 1, revision: 3,
	date: new Date("Feb 24, 2008"),
	source: 'http://tiddlywiki.bidix.info/#UploadPlugin',
	author: 'BidiX (BidiX (at) bidix (dot) info',
	coreVersion: '2.2.0'
};

//
// Environment
//

if (!window.bidix) window.bidix = {}; // bidix namespace
bidix.debugMode = false;	// true to activate both in Plugin and UploadService
	
//
// Upload Macro
//

config.macros.upload = {
// default values
	defaultBackupDir: '',	//no backup
	defaultStoreScript: "store.php",
	defaultToFilename: "index.html",
	defaultUploadDir: ".",
	authenticateUser: true	// UploadService Authenticate User
};
	
config.macros.upload.label = {
	promptOption: "Save and Upload this TiddlyWiki with UploadOptions",
	promptParamMacro: "Save and Upload this TiddlyWiki in %0",
	saveLabel: "save to web", 
	saveToDisk: "save to disk",
	uploadLabel: "upload"	
};

config.macros.upload.messages = {
	noStoreUrl: "No store URL in parmeters or options",
	usernameOrPasswordMissing: "Username or password missing"
};

config.macros.upload.handler = function(place,macroName,params) {
	if (readOnly)
		return;
	var label;
	if (document.location.toString().substr(0,4) == "http") 
		label = this.label.saveLabel;
	else
		label = this.label.uploadLabel;
	var prompt;
	if (params[0]) {
		prompt = this.label.promptParamMacro.toString().format([this.destFile(params[0], 
			(params[1] ? params[1]:bidix.basename(window.location.toString())), params[3])]);
	} else {
		prompt = this.label.promptOption;
	}
	createTiddlyButton(place, label, prompt, function() {config.macros.upload.action(params);}, null, null, this.accessKey);
};

config.macros.upload.action = function(params)
{
		// for missing macro parameter set value from options
		if (!params) params = {};
		var storeUrl = params[0] ? params[0] : config.options.txtUploadStoreUrl;
		var toFilename = params[1] ? params[1] : config.options.txtUploadFilename;
		var backupDir = params[2] ? params[2] : config.options.txtUploadBackupDir;
		var uploadDir = params[3] ? params[3] : config.options.txtUploadDir;
		var username = params[4] ? params[4] : config.options.txtUploadUserName;
		var password = config.options.pasUploadPassword; // for security reason no password as macro parameter	
		// for still missing parameter set default value
		if ((!storeUrl) && (document.location.toString().substr(0,4) == "http")) 
			storeUrl = bidix.dirname(document.location.toString())+'/'+config.macros.upload.defaultStoreScript;
		if (storeUrl.substr(0,4) != "http")
			storeUrl = bidix.dirname(document.location.toString()) +'/'+ storeUrl;
		if (!toFilename)
			toFilename = bidix.basename(window.location.toString());
		if (!toFilename)
			toFilename = config.macros.upload.defaultToFilename;
		if (!uploadDir)
			uploadDir = config.macros.upload.defaultUploadDir;
		if (!backupDir)
			backupDir = config.macros.upload.defaultBackupDir;
		// report error if still missing
		if (!storeUrl) {
			alert(config.macros.upload.messages.noStoreUrl);
			clearMessage();
			return false;
		}
		if (config.macros.upload.authenticateUser && (!username || !password)) {
			alert(config.macros.upload.messages.usernameOrPasswordMissing);
			clearMessage();
			return false;
		}
		bidix.upload.uploadChanges(false,null,storeUrl, toFilename, uploadDir, backupDir, username, password); 
		return false; 
};

config.macros.upload.destFile = function(storeUrl, toFilename, uploadDir) 
{
	if (!storeUrl)
		return null;
		var dest = bidix.dirname(storeUrl);
		if (uploadDir && uploadDir != '.')
			dest = dest + '/' + uploadDir;
		dest = dest + '/' + toFilename;
	return dest;
};

//
// uploadOptions Macro
//

config.macros.uploadOptions = {
	handler: function(place,macroName,params) {
		var wizard = new Wizard();
		wizard.createWizard(place,this.wizardTitle);
		wizard.addStep(this.step1Title,this.step1Html);
		var markList = wizard.getElement("markList");
		var listWrapper = document.createElement("div");
		markList.parentNode.insertBefore(listWrapper,markList);
		wizard.setValue("listWrapper",listWrapper);
		this.refreshOptions(listWrapper,false);
		var uploadCaption;
		if (document.location.toString().substr(0,4) == "http") 
			uploadCaption = config.macros.upload.label.saveLabel;
		else
			uploadCaption = config.macros.upload.label.uploadLabel;
		
		wizard.setButtons([
				{caption: uploadCaption, tooltip: config.macros.upload.label.promptOption, 
					onClick: config.macros.upload.action},
				{caption: this.cancelButton, tooltip: this.cancelButtonPrompt, onClick: this.onCancel}
				
			]);
	},
	options: [
		"txtUploadUserName",
		"pasUploadPassword",
		"txtUploadStoreUrl",
		"txtUploadDir",
		"txtUploadFilename",
		"txtUploadBackupDir",
		"chkUploadLog",
		"txtUploadLogMaxLine"		
	],
	refreshOptions: function(listWrapper) {
		var opts = [];
		for(i=0; i<this.options.length; i++) {
			var opt = {};
			opts.push();
			opt.option = "";
			n = this.options[i];
			opt.name = n;
			opt.lowlight = !config.optionsDesc[n];
			opt.description = opt.lowlight ? this.unknownDescription : config.optionsDesc[n];
			opts.push(opt);
		}
		var listview = ListView.create(listWrapper,opts,this.listViewTemplate);
		for(n=0; n<opts.length; n++) {
			var type = opts[n].name.substr(0,3);
			var h = config.macros.option.types[type];
			if (h && h.create) {
				h.create(opts[n].colElements['option'],type,opts[n].name,opts[n].name,"no");
			}
		}
		
	},
	onCancel: function(e)
	{
		backstage.switchTab(null);
		return false;
	},
	
	wizardTitle: "Upload with options",
	step1Title: "These options are saved in cookies in your browser",
	step1Html: "<input type='hidden' name='markList'></input><br>",
	cancelButton: "Cancel",
	cancelButtonPrompt: "Cancel prompt",
	listViewTemplate: {
		columns: [
			{name: 'Description', field: 'description', title: "Description", type: 'WikiText'},
			{name: 'Option', field: 'option', title: "Option", type: 'String'},
			{name: 'Name', field: 'name', title: "Name", type: 'String'}
			],
		rowClasses: [
			{className: 'lowlight', field: 'lowlight'} 
			]}
};

//
// upload functions
//

if (!bidix.upload) bidix.upload = {};

if (!bidix.upload.messages) bidix.upload.messages = {
	//from saving
	invalidFileError: "The original file '%0' does not appear to be a valid TiddlyWiki",
	backupSaved: "Backup saved",
	backupFailed: "Failed to upload backup file",
	rssSaved: "RSS feed uploaded",
	rssFailed: "Failed to upload RSS feed file",
	emptySaved: "Empty template uploaded",
	emptyFailed: "Failed to upload empty template file",
	mainSaved: "Main TiddlyWiki file uploaded",
	mainFailed: "Failed to upload main TiddlyWiki file. Your changes have not been saved",
	//specific upload
	loadOriginalHttpPostError: "Can't get original file",
	aboutToSaveOnHttpPost: 'About to upload on %0 ...',
	storePhpNotFound: "The store script '%0' was not found."
};

bidix.upload.uploadChanges = function(onlyIfDirty,tiddlers,storeUrl,toFilename,uploadDir,backupDir,username,password)
{
	var callback = function(status,uploadParams,original,url,xhr) {
		if (!status) {
			displayMessage(bidix.upload.messages.loadOriginalHttpPostError);
			return;
		}
		if (bidix.debugMode) 
			alert(original.substr(0,500)+"\n...");
		// Locate the storeArea div's 
		var posDiv = locateStoreArea(original);
		if((posDiv[0] == -1) || (posDiv[1] == -1)) {
			alert(config.messages.invalidFileError.format([localPath]));
			return;
		}
		bidix.upload.uploadRss(uploadParams,original,posDiv);
	};
	
	if(onlyIfDirty && !store.isDirty())
		return;
	clearMessage();
	// save on localdisk ?
	if (document.location.toString().substr(0,4) == "file") {
		var path = document.location.toString();
		var localPath = getLocalPath(path);
		saveChanges();
	}
	// get original
	var uploadParams = new Array(storeUrl,toFilename,uploadDir,backupDir,username,password);
	var originalPath = document.location.toString();
	// If url is a directory : add index.html
	if (originalPath.charAt(originalPath.length-1) == "/")
		originalPath = originalPath + "index.html";
	var dest = config.macros.upload.destFile(storeUrl,toFilename,uploadDir);
	var log = new bidix.UploadLog();
	log.startUpload(storeUrl, dest, uploadDir,  backupDir);
	displayMessage(bidix.upload.messages.aboutToSaveOnHttpPost.format([dest]));
	if (bidix.debugMode) 
		alert("about to execute Http - GET on "+originalPath);
	var r = doHttp("GET",originalPath,null,null,username,password,callback,uploadParams,null);
	if (typeof r == "string")
		displayMessage(r);
	return r;
};

bidix.upload.uploadRss = function(uploadParams,original,posDiv) 
{
	var callback = function(status,params,responseText,url,xhr) {
		if(status) {
			var destfile = responseText.substring(responseText.indexOf("destfile:")+9,responseText.indexOf("\n", responseText.indexOf("destfile:")));
			displayMessage(bidix.upload.messages.rssSaved,bidix.dirname(url)+'/'+destfile);
			bidix.upload.uploadMain(params[0],params[1],params[2]);
		} else {
			displayMessage(bidix.upload.messages.rssFailed);			
		}
	};
	// do uploadRss
	if(config.options.chkGenerateAnRssFeed) {
		var rssPath = uploadParams[1].substr(0,uploadParams[1].lastIndexOf(".")) + ".xml";
		var rssUploadParams = new Array(uploadParams[0],rssPath,uploadParams[2],'',uploadParams[4],uploadParams[5]);
		var rssString = generateRss();
		// no UnicodeToUTF8 conversion needed when location is "file" !!!
		if (document.location.toString().substr(0,4) != "file")
			rssString = convertUnicodeToUTF8(rssString);	
		bidix.upload.httpUpload(rssUploadParams,rssString,callback,Array(uploadParams,original,posDiv));
	} else {
		bidix.upload.uploadMain(uploadParams,original,posDiv);
	}
};

bidix.upload.uploadMain = function(uploadParams,original,posDiv) 
{
	var callback = function(status,params,responseText,url,xhr) {
		var log = new bidix.UploadLog();
		if(status) {
			// if backupDir specified
			if ((params[3]) && (responseText.indexOf("backupfile:") > -1))  {
				var backupfile = responseText.substring(responseText.indexOf("backupfile:")+11,responseText.indexOf("\n", responseText.indexOf("backupfile:")));
				displayMessage(bidix.upload.messages.backupSaved,bidix.dirname(url)+'/'+backupfile);
			}
			var destfile = responseText.substring(responseText.indexOf("destfile:")+9,responseText.indexOf("\n", responseText.indexOf("destfile:")));
			displayMessage(bidix.upload.messages.mainSaved,bidix.dirname(url)+'/'+destfile);
			store.setDirty(false);
			log.endUpload("ok");
		} else {
			alert(bidix.upload.messages.mainFailed);
			displayMessage(bidix.upload.messages.mainFailed);
			log.endUpload("failed");			
		}
	};
	// do uploadMain
	var revised = bidix.upload.updateOriginal(original,posDiv);
	bidix.upload.httpUpload(uploadParams,revised,callback,uploadParams);
};

bidix.upload.httpUpload = function(uploadParams,data,callback,params)
{
	var localCallback = function(status,params,responseText,url,xhr) {
		url = (url.indexOf("nocache=") < 0 ? url : url.substring(0,url.indexOf("nocache=")-1));
		if (xhr.status == httpStatus.NotFound)
			alert(bidix.upload.messages.storePhpNotFound.format([url]));
		if ((bidix.debugMode) || (responseText.indexOf("Debug mode") >= 0 )) {
			alert(responseText);
			if (responseText.indexOf("Debug mode") >= 0 )
				responseText = responseText.substring(responseText.indexOf("\n\n")+2);
		} else if (responseText.charAt(0) != '0') 
			alert(responseText);
		if (responseText.charAt(0) != '0')
			status = null;
		callback(status,params,responseText,url,xhr);
	};
	// do httpUpload
	var boundary = "---------------------------"+"AaB03x";	
	var uploadFormName = "UploadPlugin";
	// compose headers data
	var sheader = "";
	sheader += "--" + boundary + "\r\nContent-disposition: form-data; name=\"";
	sheader += uploadFormName +"\"\r\n\r\n";
	sheader += "backupDir="+uploadParams[3] +
				";user=" + uploadParams[4] +
				";password=" + uploadParams[5] +
				";uploaddir=" + uploadParams[2];
	if (bidix.debugMode)
		sheader += ";debug=1";
	sheader += ";;\r\n"; 
	sheader += "\r\n" + "--" + boundary + "\r\n";
	sheader += "Content-disposition: form-data; name=\"userfile\"; filename=\""+uploadParams[1]+"\"\r\n";
	sheader += "Content-Type: text/html;charset=UTF-8" + "\r\n";
	sheader += "Content-Length: " + data.length + "\r\n\r\n";
	// compose trailer data
	var strailer = new String();
	strailer = "\r\n--" + boundary + "--\r\n";
	data = sheader + data + strailer;
	if (bidix.debugMode) alert("about to execute Http - POST on "+uploadParams[0]+"\n with \n"+data.substr(0,500)+ " ... ");
	var r = doHttp("POST",uploadParams[0],data,"multipart/form-data; ;charset=UTF-8; boundary="+boundary,uploadParams[4],uploadParams[5],localCallback,params,null);
	if (typeof r == "string")
		displayMessage(r);
	return r;
};

// same as Saving's updateOriginal but without convertUnicodeToUTF8 calls
bidix.upload.updateOriginal = function(original, posDiv)
{
	if (!posDiv)
		posDiv = locateStoreArea(original);
	if((posDiv[0] == -1) || (posDiv[1] == -1)) {
		alert(config.messages.invalidFileError.format([localPath]));
		return;
	}
	var revised = original.substr(0,posDiv[0] + startSaveArea.length) + "\n" +
				store.allTiddlersAsHtml() + "\n" +
				original.substr(posDiv[1]);
	var newSiteTitle = getPageTitle().htmlEncode();
	revised = revised.replaceChunk("<title"+">","</title"+">"," " + newSiteTitle + " ");
	revised = updateMarkupBlock(revised,"PRE-HEAD","MarkupPreHead");
	revised = updateMarkupBlock(revised,"POST-HEAD","MarkupPostHead");
	revised = updateMarkupBlock(revised,"PRE-BODY","MarkupPreBody");
	revised = updateMarkupBlock(revised,"POST-SCRIPT","MarkupPostBody");
	return revised;
};

//
// UploadLog
// 
// config.options.chkUploadLog :
//		false : no logging
//		true : logging
// config.options.txtUploadLogMaxLine :
//		-1 : no limit
//      0 :  no Log lines but UploadLog is still in place
//		n :  the last n lines are only kept
//		NaN : no limit (-1)

bidix.UploadLog = function() {
	if (!config.options.chkUploadLog) 
		return; // this.tiddler = null
	this.tiddler = store.getTiddler("UploadLog");
	if (!this.tiddler) {
		this.tiddler = new Tiddler();
		this.tiddler.title = "UploadLog";
		this.tiddler.text = "| !date | !user | !location | !storeUrl | !uploadDir | !toFilename | !backupdir | !origin |";
		this.tiddler.created = new Date();
		this.tiddler.modifier = config.options.txtUserName;
		this.tiddler.modified = new Date();
		store.addTiddler(this.tiddler);
	}
	return this;
};

bidix.UploadLog.prototype.addText = function(text) {
	if (!this.tiddler)
		return;
	// retrieve maxLine when we need it
	var maxLine = parseInt(config.options.txtUploadLogMaxLine,10);
	if (isNaN(maxLine))
		maxLine = -1;
	// add text
	if (maxLine != 0) 
		this.tiddler.text = this.tiddler.text + text;
	// Trunck to maxLine
	if (maxLine >= 0) {
		var textArray = this.tiddler.text.split('\n');
		if (textArray.length > maxLine + 1)
			textArray.splice(1,textArray.length-1-maxLine);
			this.tiddler.text = textArray.join('\n');		
	}
	// update tiddler fields
	this.tiddler.modifier = config.options.txtUserName;
	this.tiddler.modified = new Date();
	store.addTiddler(this.tiddler);
	// refresh and notifiy for immediate update
	story.refreshTiddler(this.tiddler.title);
	store.notify(this.tiddler.title, true);
};

bidix.UploadLog.prototype.startUpload = function(storeUrl, toFilename, uploadDir,  backupDir) {
	if (!this.tiddler)
		return;
	var now = new Date();
	var text = "\n| ";
	var filename = bidix.basename(document.location.toString());
	if (!filename) filename = '/';
	text += now.formatString("0DD/0MM/YYYY 0hh:0mm:0ss") +" | ";
	text += config.options.txtUserName + " | ";
	text += "[["+filename+"|"+location + "]] |";
	text += " [[" + bidix.basename(storeUrl) + "|" + storeUrl + "]] | ";
	text += uploadDir + " | ";
	text += "[[" + bidix.basename(toFilename) + " | " +toFilename + "]] | ";
	text += backupDir + " |";
	this.addText(text);
};

bidix.UploadLog.prototype.endUpload = function(status) {
	if (!this.tiddler)
		return;
	this.addText(" "+status+" |");
};

//
// Utilities
// 

bidix.checkPlugin = function(plugin, major, minor, revision) {
	var ext = version.extensions[plugin];
	if (!
		(ext  && 
			((ext.major > major) || 
			((ext.major == major) && (ext.minor > minor))  ||
			((ext.major == major) && (ext.minor == minor) && (ext.revision >= revision))))) {
			// write error in PluginManager
			if (pluginInfo)
				pluginInfo.log.push("Requires " + plugin + " " + major + "." + minor + "." + revision);
			eval(plugin); // generate an error : "Error: ReferenceError: xxxx is not defined"
	}
};

bidix.dirname = function(filePath) {
	if (!filePath) 
		return;
	var lastpos;
	if ((lastpos = filePath.lastIndexOf("/")) != -1) {
		return filePath.substring(0, lastpos);
	} else {
		return filePath.substring(0, filePath.lastIndexOf("\\"));
	}
};

bidix.basename = function(filePath) {
	if (!filePath) 
		return;
	var lastpos;
	if ((lastpos = filePath.lastIndexOf("#")) != -1) 
		filePath = filePath.substring(0, lastpos);
	if ((lastpos = filePath.lastIndexOf("/")) != -1) {
		return filePath.substring(lastpos + 1);
	} else
		return filePath.substring(filePath.lastIndexOf("\\")+1);
};

bidix.initOption = function(name,value) {
	if (!config.options[name])
		config.options[name] = value;
};

//
// Initializations
//

// require PasswordOptionPlugin 1.0.1 or better
bidix.checkPlugin("PasswordOptionPlugin", 1, 0, 1);

// styleSheet
setStylesheet('.txtUploadStoreUrl, .txtUploadBackupDir, .txtUploadDir {width: 22em;}',"uploadPluginStyles");

//optionsDesc
merge(config.optionsDesc,{
	txtUploadStoreUrl: "Url of the UploadService script (default: store.php)",
	txtUploadFilename: "Filename of the uploaded file (default: in index.html)",
	txtUploadDir: "Relative Directory where to store the file (default: . (downloadService directory))",
	txtUploadBackupDir: "Relative Directory where to backup the file. If empty no backup. (default: ''(empty))",
	txtUploadUserName: "Upload Username",
	pasUploadPassword: "Upload Password",
	chkUploadLog: "do Logging in UploadLog (default: true)",
	txtUploadLogMaxLine: "Maximum of lines in UploadLog (default: 10)"
});

// Options Initializations
bidix.initOption('txtUploadStoreUrl','');
bidix.initOption('txtUploadFilename','');
bidix.initOption('txtUploadDir','');
bidix.initOption('txtUploadBackupDir','');
bidix.initOption('txtUploadUserName','');
bidix.initOption('pasUploadPassword','');
bidix.initOption('chkUploadLog',true);
bidix.initOption('txtUploadLogMaxLine','10');


// Backstage
merge(config.tasks,{
	uploadOptions: {text: "upload", tooltip: "Change UploadOptions and Upload", content: '<<uploadOptions>>'}
});
config.backstageTasks.push("uploadOptions");


//}}}

<!--{{{-->
<div class='toolbar' macro='toolbar closeTiddler closeOthers +editTiddler > fields syncing permalink references jump'></div>
<div class='title' macro='view title'></div>
<div class='viewer' macro='view text wikified'></div>
<div class='tagClear'></div>
<!--}}}-->
This is just a modest adaptation of ~TiddlyWiki for use as a webpage. I created it for my own use, but thought others might like an empty template of it. To see a working example of the Webview ~TiddlyWiki, [[see here|http://www.giffmex.org/webviewtwexample.html]]. ''Features of WebviewTW:''
*I have reduced as much clutter as possible, so as not to confuse first time visitors to your site: the header is gone, the sidebar hidden, and Tiddler elements such as author, date created, tagged and tagging have been removed. The mainmenu has a toolbox, which itself can be gutted if desired, when you are ready to upload.
*Only one tiddler opens at a time.
*There is a way to create a series of tiddlers linked in a colorful subtopic menu above the tiddler titles (the three squares above are an example of a subtopic menu and include the instructions necessary to create one). These are good just as subtopic menus, but are also meant for slideshows and linear tutorials and lessons. The idea is similar to the [[PresentationPlugin|http://lewcid.googlepages.com/presentation_empty_full.html#Documentation]], but this setup operates in a different way.
*Saving options have been set to ~SaveBackup:unchecked, and Animations:disabled, and the sidebar is hidden by default. (See [[z_configOptions]] to change these)
*In edit mode there are a number of easyEdit menus. See [[Formatting cheatsheet]] for details. There are also several color palettes to choose from (found in the Sidebar).
*The UploadPlugin and SplashScreenPlugin are installed. For directions for the UploadPlugin, see [[this external link|http://www.giffmex.org/twfortherestofus.html#%5B%5BSimple%20instructions%20for%20BidiX's%20UploadPlugin%5D%5D]]. My apologies to Alan Hecht, the creator of the ~WebViewPlugin - there is no relation between this adaptation and that plugin, which is not used here.
!Synopsis of site postings
!!!
<html><div style="color: rgb(100, 100, 150); font-family: Monaco;"><big><b>
Saturday 14MAR:</html>''Editing Pylab Graphs'': see @@[[Lecture 04|L04.10]]@@
* Simple instructions added for editing the ''rcParams'' that set graph attributes.
!!!
<html><div style="color: rgb(100, 100, 150); font-family: Monaco;"><big><b>
Friday 13MAR:</html>''Graphics'': see @@[[Lecture 04|L04]]@@
!!!
<html><div style="color: rgb(100, 100, 150); font-family: Monaco;"><big><b>
Friday 06MAR:</html>''Modeling & Bootstrapping'': see @@[[Lecture 03|L03]]@@
!!!
<html><div style="color: rgb(100, 100, 150); font-family: Monaco;"><big><b>
Thursday 26FEB:</html>''Programming Tools'': see @@[[Lecture 02|L02]]@@
!!!
<html><div style="color: rgb(100, 100, 150); font-family: Monaco;"><big><b>
Wednesday 25FEB:</html>''Computer Requirements'': see @@[[Syllabus]]@@
!!!
<html><div style="color: rgb(100, 100, 150); font-family: Monaco;"><big><b>
Friday 20FEB:</html>''Natural Recombinatorial Diversity'': see @@[[Lecture01|L01]]@@
* Read Borges' //Library of Babel Essay// : [[Library of Babel]]
* PERL code example for [[Monkeys on typewriters|MonkeysTyping]]
!!!
''* * * *   Active PERL for Windows PCs   * * * *''

If you are reading this page, you are likely having significant problems getting PERL running on your PC. So . . . . . . .

@@1.@@ Let's Start Over. Even if you already have a C:\Perl directory, let's pretend you don't.

@@2.@@ Here is a local link to the current Windows-x86-MSI version available from Active state: [[EASY DOWNLOAD|00/ActivePerl-5.10.0.1003-MSWin32-x86-285500.msi]]. After clicking on this link, if you are requested to do anything, select save and put it on your desktop. The file will be named: "ActivePerl-5.10.0.1003-MSWin32-x86-285500.msi"

@@3.@@ The "msi" extension on the file stands for "MicroSoft Installer". Double-click the file and it will start running an automatic installation routine. Just accept the default location ("C:\Perl") and on the options screen leave the boxes checked for: "Add Perl to PATH environmental variable" and "Create Perl file extension associations."

@@4.@@ Once the installer finishes, click START, click RUN, enter the command "cmd" (without quotations) and press RETURN to open a terminal window. 

@@5.@@ At the command prompt, enter "perl -v" (w/o quotes), hit RETURN and the current version number of the perl install should be displayed in the terminal window. You are now ready to run perl scripts.

''If this worked, then you are ready to go to the test script here:'' [[Running PERL]]

//If the "perl -v" command doesn't work, then we will have to contact Active State and try to troubleshoot what's wrong with your computer.//

[[BACK|Resource Index]]
!
Background: #fff
Foreground: #000
PrimaryPale: #ccccff
PrimaryLight: #ccccff
PrimaryMid: #333366
PrimaryDark: #014
SecondaryPale: #bbbbff
SecondaryLight: #fe8
SecondaryMid: #db4
SecondaryDark: #333366
TertiaryPale: #eee
TertiaryLight: #ccc
TertiaryMid: #999
TertiaryDark: #9999cc
Error: #f88
Background: #fff
Foreground: #000
PrimaryPale: #ffccff
PrimaryLight: #ffccff
PrimaryMid: #ff0066
PrimaryDark: #014
SecondaryPale: #ffcccc
SecondaryLight: #fe8
SecondaryMid: #db4
SecondaryDark: #ff0066
TertiaryPale: #eee
TertiaryLight: #ccc
TertiaryMid: #999
TertiaryDark: #ff99cc
Error: #f88
[[BACK to Resources|Resource Index]]
!!!
!Similarity Grouping
An incredibly well designed tool for parsing through large collections of sequences (fasta format) and organizing those sequences into "unique" groups or clusters. Provides a fast filter for duplicate or derivative sequences to be isolated from a larger sequence file.
[img[00/cdhit01.png]]
!!http://cd-hit.org
<html><img src="00/cdhit02.png" style="height:300px"></html>

!! Common usage for CD-HIT:
{{{
  prompt>  cd-hit -i infile.fasta -o outfile.txt -c 0.55 -t 5 -n 3 -d 1000
}}}
  (note that -c is the similarity threshold, -t tolerance, -n word length, -d number of characters output from the fasta file headers)
!!
/***An adaptation of [[easyFormat]]***/
//{{{
config.commands.Color = new TWkd.Ease('Color','change the color of selected text');

config.commands.Color.addMode({
 name:'Red',
 tooltip:'turns selection red',
 operation:function(){
config.commands.Color.putInPlace("{{red{"+TWkd.context.selection.content+"}}}",TWkd.context.selection);
 }
});
config.commands.Color.addMode({
 name:'Blue',
 tooltip:'turns selection blue',
 operation:function(){
config.commands.Color.putInPlace("{{blue{"+TWkd.context.selection.content+"}}}",TWkd.context.selection);
 }
});
config.commands.Color.addMode({
 name:'Green',
 tooltip:'turns selection green',
 operation:function(){
config.commands.Color.putInPlace("{{green{"+TWkd.context.selection.content+"}}}",TWkd.context.selection);
 }
});
config.commands.Color.addMode({
 name:'Gold',
 tooltip:'turns selection gold',
 operation:function(){
config.commands.Color.putInPlace("{{gold{"+TWkd.context.selection.content+"}}}",TWkd.context.selection);
 }
});
config.commands.Color.addMode({
 name:'Gray',
 tooltip:'turns selection gray',
 operation:function(){
config.commands.Color.putInPlace("{{gray{"+TWkd.context.selection.content+"}}}",TWkd.context.selection);
 }
});
config.commands.Color.addMode({
 name:'Magenta',
 tooltip:'turns selection magenta',
 operation:function(){
config.commands.Color.putInPlace("{{magenta{"+TWkd.context.selection.content+"}}}",TWkd.context.selection);
 }
});
config.commands.Color.addMode({
 name:'Purple',
 tooltip:'turns selection purple',
 operation:function(){
config.commands.Color.putInPlace("{{purple{"+TWkd.context.selection.content+"}}}",TWkd.context.selection);
 }
});
config.commands.Color.addMode({
 name:'Teal',
 tooltip:'turns selection teal',
 operation:function(){
config.commands.Color.putInPlace("{{teal{"+TWkd.context.selection.content+"}}}",TWkd.context.selection);
 }
});
config.commands.Color.addMode({
 name:'Burgundy',
 tooltip:'turns selection burgundy',
 operation:function(){
config.commands.Color.putInPlace("{{burgundy{"+TWkd.context.selection.content+"}}}",TWkd.context.selection);
 }
});
//}}}
/***
|!''Name:''|!easyFormat|
|''Description:''|the format command format selection according to your choice|
|''Version:''|0.1.0|
|''Date:''|13/01/2007|
|''Source:''|[[TWkd|http://yann.perrin.googlepages.com/twkd.html#easyFormat]]|
|''Author:''|[[Yann Perrin|YannPerrin]]|
|''License:''|[[BSD open source license]]|
|''~CoreVersion:''|2.x|
|''Browser:''|Firefox 1.0.4+; Firefox 1.5; InternetExplorer 6.0|
|''Requires:''|@@color:red;''E.A.S.E''@@|
***/
//{{{
config.commands.Format = new TWkd.Ease('Format','format selection accordingly to chosen mode');

config.commands.Format.addMode({
 name:'Bold',
 tooltip:'turns selection into bold text',
 operation:function(){
config.commands.Format.putInPlace("''"+TWkd.context.selection.content+"''",TWkd.context.selection);
 }
});
config.commands.Format.addMode({
 name:'Italic',
 tooltip:'turns selection into italic text',
 operation:function(){
config.commands.Format.putInPlace("//"+TWkd.context.selection.content+"//",TWkd.context.selection);
 }
});
config.commands.Format.addMode({
 name:'Underline',
 tooltip:'underlines selected text',
 operation:function(){
config.commands.Format.putInPlace("__"+TWkd.context.selection.content+"__",TWkd.context.selection);
 }
});
config.commands.Format.addMode({
 name:'Highlight',
 tooltip:'highlight selection',
 operation:function(){
config.commands.Format.putInPlace("@@"+TWkd.context.selection.content+"@@",TWkd.context.selection);
 }
});
config.commands.Format.addMode({
 name:'Hyperlink',
 tooltip:'turns selection into a link using double brackets',
 operation:function(){
config.commands.Format.putInPlace("[["+TWkd.context.selection.content+"]]",TWkd.context.selection);
 }
});
//}}}
/***An adaptation of [[easyFormat]]***/
//{{{
config.commands.Greek = new TWkd.Ease('Greek','formatting for Greek text');

config.commands.Greek.addMode({
 name:'Greek',
 tooltip:'formats Greek text correctly',
 operation:function(){
config.commands.Greek.putInPlace("{{greek{"+TWkd.context.selection.content+"}}}",TWkd.context.selection);
 }
});
config.commands.Greek.addMode({
 name:'GkIndent1x',
 tooltip:'formats Gk and indents text 1x',
 operation:function(){
config.commands.Greek.putInPlace("{{gkindent{"+TWkd.context.selection.content+"}}}",TWkd.context.selection);
 }
});
config.commands.Greek.addMode({
 name:'GkIndent2x',
 tooltip:'formats Gk and indents text 2x',
 operation:function(){
config.commands.Greek.putInPlace("{{gkindent{{{gkindent{"+TWkd.context.selection.content+"}}}}}}",TWkd.context.selection);
 }
});
config.commands.Greek.addMode({
 name:'GkIndent3x',
 tooltip:'formats Gk and indents text 3x',
 operation:function(){
config.commands.Greek.putInPlace("{{gkindent{{{gkindent{{{gkindent{"+TWkd.context.selection.content+"}}}}}}}}}",TWkd.context.selection);
 }
});
config.commands.Greek.addMode({
 name:'GkIndent4x',
 tooltip:'formats Gk and indents text 4x',
 operation:function(){
config.commands.Greek.putInPlace("{{gkindent{{{gkindent{{{gkindent{{{gkindent{"+TWkd.context.selection.content+"}}}}}}}}}}}}",TWkd.context.selection);
 }
});
config.commands.Greek.addMode({
 name:'GkIndent5x',
 tooltip:'formats Gk and indents text 5x',
 operation:function(){
config.commands.Greek.putInPlace("{{gkindent{{{gkindent{{{gkindent{{{gkindent{{{gkindent{"+TWkd.context.selection.content+"}}}}}}}}}}}}}}}",TWkd.context.selection);
 }
});
//}}}
/***An adaptation of [[easyFormat]]***/
//{{{
config.commands.Hebrew = new TWkd.Ease('Hebrew','formatting for Hebrew text');

config.commands.Hebrew.addMode({
 name:'HebrewNoAlign',
 tooltip:'formats Hebrew text correctly',
 operation:function(){
config.commands.Hebrew.putInPlace("{{hebrewNoAlign{"+TWkd.context.selection.content+"}}}",TWkd.context.selection);
 }
});
config.commands.Hebrew.addMode({
 name:'HebrewRightAlign',
 tooltip:'formats Hebrew text correctly and aligns text to the right',
 operation:function(){
config.commands.Hebrew.putInPlace("{{hebrewRightAlign{"+TWkd.context.selection.content+"}}}",TWkd.context.selection);
 }
});
config.commands.Hebrew.addMode({
 name:'HebIndent1x',
 tooltip:'formats Heb and indents text 1x',
 operation:function(){
config.commands.Hebrew.putInPlace("{{hebAlignAndIndent{"+TWkd.context.selection.content+"}}}",TWkd.context.selection);
 }
});
config.commands.Hebrew.addMode({
 name:'HebIndent2x',
 tooltip:'formats Heb and indents text 2x',
 operation:function(){
config.commands.Hebrew.putInPlace("{{hebAlignAndIndent{{{hebAlignAndIndent{"+TWkd.context.selection.content+"}}}}}}",TWkd.context.selection);
 }
});
config.commands.Hebrew.addMode({
 name:'HebIndent3x',
 tooltip:'formats Heb and indents text 3x',
 operation:function(){
config.commands.Hebrew.putInPlace("{{hebAlignAndIndent{{{hebAlignAndIndent{{{hebAlignAndIndent{"+TWkd.context.selection.content+"}}}}}}}}}",TWkd.context.selection);
 }
});
config.commands.Hebrew.addMode({
 name:'HebIndent4x',
 tooltip:'formats Heb and indents text 4x',
 operation:function(){
config.commands.Hebrew.putInPlace("{{hebAlignAndIndent{{{hebAlignAndIndent{{{hebAlignAndIndent{{{hebAlignAndIndent{"+TWkd.context.selection.content+"}}}}}}}}}}}}",TWkd.context.selection);
 }
});
config.commands.Hebrew.addMode({
 name:'HebIndent5x',
 tooltip:'formats Heb and indents text 5x',
 operation:function(){
config.commands.Hebrew.putInPlace("{{hebAlignAndIndent{{{hebAlignAndIndent{{{hebAlignAndIndent{{{hebAlignAndIndent{{{hebAlignAndIndent{"+TWkd.context.selection.content+"}}}}}}}}}}}}}}}",TWkd.context.selection);
 }
});
//}}}
/***
This is an adaptation of:
|!''Name:''|!easyFormat|
|''Description:''|the format command format selection according to your choice|
|''Version:''|0.1.0|
|''Date:''|13/01/2007|
|''Source:''|[[TWkd|http://yann.perrin.googlepages.com/twkd.html#easyFormat]]|
|''Author:''|[[Yann Perrin|YannPerrin]]|
|''License:''|[[BSD open source license]]|
|''~CoreVersion:''|2.x|
|''Browser:''|Firefox 1.0.4+; Firefox 1.5; InternetExplorer 6.0|
|''Requires:''|@@color:red;''E.A.S.E''@@|
***/
//{{{
config.commands.Highlighting = new TWkd.Ease('Highlighting','highlight selected text with a color chosen from the list');
config.commands.Highlighting.addMode({
 name:'Red',
 tooltip:'highlights selection red',
 operation:function(){
config.commands.Highlighting.putInPlace("@@bgcolor(#ff6666):"+TWkd.context.selection.content+"@@",TWkd.context.selection);
 }
});
config.commands.Highlighting.addMode({
 name:'Blue',
 tooltip:'highlights selection blue',
 operation:function(){
config.commands.Highlighting.putInPlace("@@bgcolor(#ccccff):"+TWkd.context.selection.content+"@@",TWkd.context.selection);
 }
});
config.commands.Highlighting.addMode({
 name:'Yellow',
 tooltip:'highlights selection yellow',
 operation:function(){
config.commands.Highlighting.putInPlace("@@"+TWkd.context.selection.content+"@@",TWkd.context.selection);
 }
});
config.commands.Highlighting.addMode({
 name:'Green',
 tooltip:'highlights selection green',
 operation:function(){
config.commands.Highlighting.putInPlace("@@bgcolor(#99ff99):"+TWkd.context.selection.content+"@@",TWkd.context.selection);
 }
});
config.commands.Highlighting.addMode({
 name:'Brown',
 tooltip:'highlights selection brown',
 operation:function(){
config.commands.Highlighting.putInPlace("@@bgcolor(#cc9966):"+TWkd.context.selection.content+"@@",TWkd.context.selection);
 }
});
config.commands.Highlighting.addMode({
 name:'Grey',
 tooltip:'highlight selection',
 operation:function(){
config.commands.Highlighting.putInPlace("@@bgcolor(#cccc99):"+TWkd.context.selection.content+"@@",TWkd.context.selection);
 }
});
config.commands.Highlighting.addMode({
 name:'Orange',
 tooltip:'turns selection into unicode text, for Greek characters',
 operation:function(){
config.commands.Highlighting.putInPlace("@@bgcolor(#ff9933):"+TWkd.context.selection.content+"@@",TWkd.context.selection);
 }
});
//}}}
/***An adaptation of [[easyFormat]]***/
//{{{
config.commands.Indent = new TWkd.Ease('Indent','indents selected text as a blockquote');

config.commands.Indent.addMode({
 name:'Indent1x',
 tooltip:'indents text 1x',
 operation:function(){
config.commands.Indent.putInPlace("{{engindent{"+TWkd.context.selection.content+"}}}",TWkd.context.selection);
 }
});
config.commands.Indent.addMode({
 name:'Indent2x',
 tooltip:'indents text 2x',
 operation:function(){
config.commands.Indent.putInPlace("{{engindent{{{engindent{"+TWkd.context.selection.content+"}}}}}}",TWkd.context.selection);
 }
});
config.commands.Indent.addMode({
 name:'Indent3x',
 tooltip:'indents text 3x',
 operation:function(){
config.commands.Indent.putInPlace("{{engindent{{{engindent{{{engindent{"+TWkd.context.selection.content+"}}}}}}}}}",TWkd.context.selection);
 }
});
config.commands.Indent.addMode({
 name:'Indent4x',
 tooltip:'indents text 4x',
 operation:function(){
config.commands.Indent.putInPlace("{{engindent{{{engindent{{{engindent{{{engindent{"+TWkd.context.selection.content+"}}}}}}}}}}}}",TWkd.context.selection);
 }
});
config.commands.Indent.addMode({
 name:'Indent5x',
 tooltip:'indents text 5x',
 operation:function(){
config.commands.Indent.putInPlace("{{engindent{{{engindent{{{engindent{{{engindent{{{engindent{"+TWkd.context.selection.content+"}}}}}}}}}}}}}}}",TWkd.context.selection);
 }
});
//}}}
/***An adaptation of [[easyFormat]]***/
//{{{
config.commands.Notes = new TWkd.Ease('Notes','add notes and popups');

config.commands.Notes.addMode({
 name:'Syntax',
 tooltip:'adds syntax note',
 operation:function(){
config.commands.Notes.putInPlace("((syntax(add note here)))",TWkd.context.selection);
 }
});
config.commands.Notes.addMode({
 name:'Translation',
 tooltip:'adds syntax note',
 operation:function(){
config.commands.Notes.putInPlace("&#149; ((translation(add note here)))",TWkd.context.selection);
 }
});
config.commands.Notes.addMode({
 name:'Text',
 tooltip:'adds textual note',
 operation:function(){
config.commands.Notes.putInPlace("&#149; ((text(add note here)))",TWkd.context.selection);
 }
});
config.commands.Notes.addMode({
 name:'Gramm.',
 tooltip:'adds grammatical note',
 operation:function(){
config.commands.Notes.putInPlace("&#149; ((gram(add note here)))",TWkd.context.selection);
 }
});
config.commands.Notes.addMode({
 name:'Popup',
 tooltip:'adds popup note to selected text',
 operation:function(){
config.commands.Notes.putInPlace("(("+TWkd.context.selection.content+"(add note here)))",TWkd.context.selection);
 }
});
//}}}
/***An adaptation of [[easyFormat]]***/
//{{{
config.commands.Tableheader = new TWkd.Ease('Tableheader','add the header row for a formatted table');

config.commands.Tableheader.addMode({
 name:'Invisible',
 tooltip:'adds the header row for a 3-column invisible table',
 operation:function(){
config.commands.Tableheader.putInPlace("XXXXX",TWkd.context.selection);
 }
});

config.commands.Tableheader.addMode({
 name:'Sortable',
 tooltip:'adds the header row for a 3-column sortable table',
 operation:function(){
config.commands.Tableheader.putInPlace("|sortable|k||||h",TWkd.context.selection);
 }
});

config.commands.Tableheader.addMode({
 name:'Standard',
 tooltip:'adds the header row for a 3-column standard table',
 operation:function(){
config.commands.Tableheader.putInPlace("|!|!|!|",TWkd.context.selection);
 }
});

//}}}
/***An adaptation of [[easyFormat]]***/
//{{{
config.commands.Tables = new TWkd.Ease('Tables','add preformatted empty tables');

config.commands.Tables.addMode({
 name:'Invisible',
 tooltip:'adds borderless table',
 operation:function(){
config.commands.Tables.putInPlace("{{invisiblecomm{\n|!|!|!|\n||||\n||||\n||||\n}}}",TWkd.context.selection);
 }
});
config.commands.Tables.addMode({
 name:'Sortable',
 tooltip:'adds a sortable table',
 operation:function(){
config.commands.Tables.putInPlace("|sortable|k\n||||h\n||||\n||||\n||||",TWkd.context.selection);
 }
});
config.commands.Tables.addMode({
 name:'Standard',
 tooltip:'adds a standard table',
 operation:function(){
config.commands.Tables.putInPlace("|!|!|!|\n||||\n||||\n||||",TWkd.context.selection);
 }
});
config.commands.Tables.addMode({
 name:'light gray cell',
 tooltip:'inserts a light gray color code into a table cell',
 operation:function(){
config.commands.Tables.putInPlace("bgcolor(#eeeeee):",TWkd.context.selection);
 }
});
config.commands.Tables.addMode({
 name:'dark gray cell',
 tooltip:'inserts a dark gray color code into a table cell',
 operation:function(){
config.commands.Tables.putInPlace("bgcolor(#cccccc):",TWkd.context.selection);
 }
});
//}}}
Background: #fff
Foreground: #000
PrimaryPale: #eeeeee
PrimaryLight: #eeeeee
PrimaryMid: #666666
PrimaryDark: #014
SecondaryPale: #cccccc
SecondaryLight: #fe8
SecondaryMid: #db4
SecondaryDark: #666666
TertiaryPale: #eee
TertiaryLight: #ccc
TertiaryMid: #999
TertiaryDark: #bbbbbb
Error: #f88
Background: #fff
Foreground: #000
PrimaryPale: #ddeeaa
PrimaryLight: #ddeeaa
PrimaryMid: #666633
PrimaryDark: #014
SecondaryPale: #bbdd88
SecondaryLight: #fe8
SecondaryMid: #db4
SecondaryDark: #666633
TertiaryPale: #eee
TertiaryLight: #ccc
TertiaryMid: #999
TertiaryDark: #aacc88
Error: #f88
[[BACK to Resources|Resource Index]]
!!!
!Getting ~MatLab
Unfortunately, the University of Delaware no longer supports free licenses for students, only faculty. Student versions are available for purchase at a large discount, but you should ask your advisor to send this email to Anita Schwartz (anita@udel.edu):
{{{
Dear Ms. Schwartz,
I need to install MatLab on a research computer in my lab for the 
(choose one: Windows, OS X, or Linux) operating system. 
Could you please send me the install diskettes or the download instructions? 
Thank you.
Sincerely, .......
}}}
''MatLab Tutorial: Lots of online resources available. Best HELP index of any program I have ever used.''
[[MATLAB HOME|http://www.mathworks.com/]]
<html><img src="00/matlab.png" style="height:300px"></html>

!!!
Background: #fff
Foreground: #000
PrimaryPale: #ddccff
PrimaryLight: #ddccff
PrimaryMid: #5500aa
PrimaryDark: #014
SecondaryPale: #ddbbff
SecondaryLight: #fe8
SecondaryMid: #db4
SecondaryDark: #5500aa
TertiaryPale: #eee
TertiaryLight: #ccc
TertiaryMid: #999
TertiaryDark: #ccaaff
Error: #f88
[[BACK to Resources|Resource Index]]
!!!
!DOWNLOAD PYTHON
[[HOMEPAGE|http://www.python.org]]
<html><img src="00/python.png" style="height:400px"></html>
!!!
[[BACK to Resources|Resource Index]]
!!!
!R Statistical Package
Download the R package from: http://www.r-project.org/index.html
[img[00/r1.png]]
<html><img src="00/r2.png" style="height:300px"></html>
!SIMPLE TUTORIAL:
[[Download a simple R tutorial|Tutorial-Verzani-SimpleR.pdf]]
!SIMPLE GUIDE:
[[QUICK-R Guide|http://www.statmethods.net/index.html]]
<html><img src="00/quickR.png" style="height:300px"></html>
!!!
<?php
/***
! User settings
Edit these lines according to your need
***/
//{{{
$AUTHENTICATE_USER = true;	// true | false
$USERS = array(
	'UserName1'=>'Password1', 
	'UserName2'=>'Password2', 
	'UserName3'=>'Password3'); // set usernames and strong passwords
$DEBUG = false;				// true | false
$CLEAN_BACKUP = true; 		// during backuping a file, remove overmuch backups
$FOLD_JS = true; 			// if javascript files have been expanded during download the fold them
error_reporting(E_ERROR | E_WARNING | E_PARSE);
//}}}
/***
!Code
No change needed under
***/
//{{{

/***
 * store.php - upload a file in this directory
 * version :1.6.1 - 2007/08/01 - BidiX@BidiX.info
 * 
 * see : 
 *	http://tiddlywiki.bidi.info/#UploadPlugin for usage
 *	http://www.php.net/manual/en/features.file-upload.php 
 *		for details on uploading files
 * usage : 
 *	POST  
 *		UploadPlugin[backupDir=<backupdir>;user=<user>;password=<password>;uploadir=<uploaddir>;[debug=1];;]
 *		userfile <file>
 *	GET
 *
 * each external javascript file included by download.php is change by a reference (src=...)
 *
 * Revision history
 * V1.6.1 - 2007/08/01
 * Enhancement: Add javascript folding
 * V1.6.0 - 2007/05/17
 * Enhancement: Add backup management
 * V1.5.2 - 2007/02/13
 * Enhancement: Add optional debug option in client parameters
 * V1.5.1 - 2007/02/01
 * Enhancement: Check value of file_uploads in php.ini. Thanks to Didier Corbière
 * V1.5.0 - 2007/01/15
 * Correct: a bug in moving uploadFile in uploadDir thanks to DaniGutiérrez for reporting
 * Refactoring
 * V 1.4.3 - 2006/10/17 
 * Test if $filename.lock exists for GroupAuthoring compatibility
 * return mtime, destfile and backupfile after the message line
 * V 1.4.2 - 2006/10/12
 *  add error_reporting(E_PARSE);
 * v 1.4.1 - 2006/03/15
 *	add chmo 0664 on the uploadedFile
 * v 1.4 - 2006/02/23
 * 	add uploaddir option :  a path for the uploaded file relative to the current directory
 *	backupdir is a relative path
 *	make recusively directories if necessary for backupDir and uploadDir
 * v 1.3 - 2006/02/17
 *	presence and value of user are checked with $USERS Array (thanks to PauloSoares)
 * v 1.2 - 2006/02/12 
  *	POST  
 *		UploadPlugin[backupDir=<backupdir>;user=<user>;password=<password>;]
 *		userfile <file>
*	if $AUTHENTICATE_USER
 *		presence and value of user and password are checked with 
 *		$USER and $PASSWORD
 * v 1.1 - 2005/12/23 
 *	POST  UploadPlugin[backupDir=<backupdir>]  userfile <file>
 * v 1.0 - 2005/12/12 
 *	POST userfile <file>
 *
 * Copyright (c) BidiX@BidiX.info 2005-2007
 ***/
//}}}

//{{{

if ($_SERVER['REQUEST_METHOD'] == 'GET') {
	/*
	 * GET Request
	 */
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
	<head>
		<meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
		<title>BidiX.info - TiddlyWiki UploadPlugin - Store script</title>
	</head>
	<body>
		<p>
		<p>store.php V 1.6.1
		<p>BidiX@BidiX.info
		<p>&nbsp;</p>
		<p>&nbsp;</p>
		<p>&nbsp;</p>
		<p align="center">This page is designed to upload a <a href="http://www.tiddlywiki.com/">TiddlyWiki<a>.</p>
		<p align="center">for details see : <a href="http://TiddlyWiki.bidix.info/#HowToUpload">TiddlyWiki.bidix.info/#HowToUpload<a>.</p>	
	</body>
</html>
<?php
exit;
}

/*
 * POST Request
 */
	 
// Recursive mkdir
function mkdirs($dir) {
	if( is_null($dir) || $dir === "" ){
		return false;
	}
	if( is_dir($dir) || $dir === "/" ){
		return true;
	}
	if( mkdirs(dirname($dir)) ){
		return mkdir($dir);
	}
	return false;
}

function toExit() {
	global $DEBUG, $filename, $backupFilename, $options;
	if ($DEBUG) {
		echo ("\nHere is some debugging info : \n");
		echo("\$filename : $filename \n");
		echo("\$backupFilename : $backupFilename \n");
		print ("\$_FILES : \n");
		print_r($_FILES);
		print ("\$options : \n");
		print_r($options);
}
exit;
}

function ParseTWFileDate($s) {
	// parse date element
	preg_match ( '/^(\d\d\d\d)(\d\d)(\d\d)\.(\d\d)(\d\d)(\d\d)/', $s , $m );
	// make a date object
	$d = mktime($m[4], $m[5], $m[6], $m[2], $m[3], $m[1]);
	// get the week number
	$w = date("W",$d);

	return array(
		'year' => $m[1], 
		'mon' => $m[2], 
		'mday' => $m[3], 
		'hours' => $m[4], 
		'minutes' => $m[5], 
		'seconds' => $m[6], 
		'week' => $w);
}

function cleanFiles($dirname, $prefix) {
	$now = getdate();
	$now['week'] = date("W");

	$hours = Array();
	$mday = Array();
	$year = Array();
	
	$toDelete = Array();

	// need files recent first
	$files = Array();
	($dir = opendir($dirname)) || die ("can't open dir '$dirname'");
	while (false !== ($file = readdir($dir))) {
		if (preg_match("/^$prefix/", $file))
        array_push($files, $file);
    }
	$files = array_reverse($files);
	
	// decides for each file
	foreach ($files as $file) {
		$fileTime = ParseTWFileDate(substr($file,strpos($file, '.')+1,strrpos($file,'.') - strpos($file, '.') -1));
		if (($now['year'] == $fileTime['year']) &&
			($now['mon'] == $fileTime['mon']) &&
			($now['mday'] == $fileTime['mday']) &&
			($now['hours'] == $fileTime['hours']))
				continue;
		elseif (($now['year'] == $fileTime['year']) &&
			($now['mon'] == $fileTime['mon']) &&
			($now['mday'] == $fileTime['mday'])) {
				if (isset($hours[$fileTime['hours']]))
					array_push($toDelete, $file);
				else 
					$hours[$fileTime['hours']] = true;
			}
		elseif 	(($now['year'] == $fileTime['year']) &&
			($now['mon'] == $fileTime['mon'])) {
				if (isset($mday[$fileTime['mday']]))
					array_push($toDelete, $file);
				else
					$mday[$fileTime['mday']] = true;
			}
		else {
			if (isset($year[$fileTime['year']][$fileTime['mon']]))
				array_push($toDelete, $file);
			else
				$year[$fileTime['year']][$fileTime['mon']] = true;
		}
	}
	return $toDelete;
}

function replaceJSContentIn($content) {
	if (preg_match ("/(.*?)<!--DOWNLOAD-INSERT-FILE:\"(.*?)\"--><script\s+type=\"text\/javascript\">(.*)/ms", $content,$matches)) {
		$front = $matches[1];
		$js = $matches[2];
		$tail = $matches[3];
		if (preg_match ("/<\/script>(.*)/ms", $tail,$matches2)) {		
			$tail = $matches2[1];
		}
		$jsContent = "<script type=\"text/javascript\" src=\"$js\"></script>";
		$tail = replaceJSContentIn($tail);
		return($front.$jsContent.$tail);
	}
	else
		return $content;
}

// Check if file_uploads is active in php config
if (ini_get('file_uploads') != '1') {
   echo "Error : File upload is not active in php.ini\n";
   toExit();
}

// var definitions
$uploadDir = './';
$uploadDirError = false;
$backupError = false;
$optionStr = $_POST['UploadPlugin'];
$optionArr=explode(';',$optionStr);
$options = array();
$backupFilename = '';
$filename = $_FILES['userfile']['name'];
$destfile = $filename;

// get options
foreach($optionArr as $o) {
	list($key, $value) = split('=', $o);
	$options[$key] = $value;
}

// debug activated by client
if ($options['debug'] == 1) {
	$DEBUG = true;
}

// authenticate User
if (($AUTHENTICATE_USER)
	&& ((!$options['user']) || (!$options['password']) || ($USERS[$options['user']] != $options['password']))) {
	echo "Error : UserName or Password do not match \n";
	echo "UserName : [".$options['user']. "] Password : [". $options['password'] . "]\n";
	toExit();
}



// make uploadDir
if ($options['uploaddir']) {
	$uploadDir = $options['uploaddir'];
	// path control for uploadDir   
    if (!(strpos($uploadDir, "../") === false)) {
        echo "Error: directory to upload specifies a parent folder";
        toExit();
	}
	if (! is_dir($uploadDir)) {
		mkdirs($uploadDir);
	}
	if (! is_dir($uploadDir)) {
		echo "UploadDirError : $uploadDirError - File NOT uploaded !\n";
		toExit();
	}
	if ($uploadDir{strlen($uploadDir)-1} != '/') {
		$uploadDir = $uploadDir . '/';
	}
}
$destfile = $uploadDir . $filename;

// backup existing file
if (file_exists($destfile) && ($options['backupDir'])) {
	if (! is_dir($options['backupDir'])) {
		mkdirs($options['backupDir']);
		if (! is_dir($options['backupDir'])) {
			$backupError = "backup mkdir error";
		}
	}
	$backupFilename = $options['backupDir'].'/'.substr($filename, 0, strrpos($filename, '.'))
				.date('.Ymd.His').substr($filename,strrpos($filename,'.'));
	rename($destfile, $backupFilename) or ($backupError = "rename error");
	// remove overmuch backup
	if ($CLEAN_BACKUP) {
		$toDelete = cleanFiles($options['backupDir'], substr($filename, 0, strrpos($filename, '.')));
		foreach ($toDelete as $file) {
			$f = $options['backupDir'].'/'.$file;
			if($DEBUG) {
				echo "delete : ".$options['backupDir'].'/'.$file."\n";
			}
			unlink($options['backupDir'].'/'.$file);
		}
	}
}

// move uploaded file to uploadDir
if (move_uploaded_file($_FILES['userfile']['tmp_name'], $destfile)) {
	if ($FOLD_JS) {
		// rewrite the file to replace JS content
		$fileContent = file_get_contents ($destfile);
		$fileContent = replaceJSContentIn($fileContent);
		if (!$handle = fopen($destfile, 'w')) {
	         echo "Cannot open file ($destfile)";
	         exit;
	    }
	    if (fwrite($handle, $fileContent) === FALSE) {
	        echo "Cannot write to file ($destfile)";
	        exit;
	    }
	    fclose($handle);
	}
    
	chmod($destfile, 0644);
	if($DEBUG) {
		echo "Debug mode \n\n";
	}
	if (!$backupError) {
		echo "0 - File successfully loaded in " .$destfile. "\n";
	} else {
		echo "BackupError : $backupError - File successfully loaded in " .$destfile. "\n";
	}
	echo("destfile:$destfile \n");
	if (($backupFilename) && (!$backupError)) {
		echo "backupfile:$backupFilename\n";
	}
	$mtime = filemtime($destfile);
	echo("mtime:$mtime");
} 
else {
	echo "Error : " . $_FILES['error']." - File NOT uploaded !\n";

}
toExit();
//}}}
?>
<html>
<div style="color: rgb(100, 100, 150); font-family: Monaco;"><big><b>
TITLE OR HEADER OR DESCRIPTOR . . . .. 
</html>
1. [[x |1.0.1]]
2. [[y |1.0.2]]
3. [[z |1.0.3]]
!!
<html>
<div style="color: rgb(100, 100, 150); font-family: Monaco;"><big><b>
TITLE OR HEADER OR DESCRIPTOR . . . .. 
</html>
1. [[x |1.1.1]]
2. [[y |1.1.2]]
3. [[z |1.1.3]]
!!
<html>
<div style="color: rgb(100, 100, 150); font-family: Monaco;"><big><b>
TITLE OR HEADER OR DESCRIPTOR . . . .. 
</html>
1. [[x |1.2.1]]
2. [[y |1.2.2]]
3. [[z |1.2.3]]
!!
<html>
<div style="color: rgb(100, 100, 150); font-family: Monaco;"><big><b>
TITLE OR HEADER OR DESCRIPTOR . . . .. 
</html>
1. [[x |1.3.1]]
2. [[y |1.3.2]]
3. [[z |1.3.3]]
!
{{tableindex{
|[[topic-01-00]]|[[topic-01-01]]|[[topic-01-02]]| [[topic-01-03]]|
}}}
<!--{{{-->
<div class='toolbar' macro='toolbar closeTiddler closeOthers +editTiddler > fields syncing permalink references jump'></div>
<div class='topic-01' macro='tiddler topic-01SubtopicMenu'></div><div class='title' macro='view title'></div>
<div class='viewer' macro='view text wikified'></div><div class='tagClear'></div>
<!--}}}-->
{{tableindex{
|[[Subject01]]|[[Subject02]]|[[subtopic3]]|
}}}
<!--{{{-->
<div class='toolbar' macro='toolbar closeTiddler closeOthers +editTiddler > fields syncing permalink references jump'></div>
<div class='topic1' macro='tiddler topic1SubtopicMenu'></div>
<div class='title' macro='view title'></div>
<div class='viewer' macro='view text wikified'></div>
<div class='tagClear'></div>
<!--}}}-->
<!--{{{-->
<div class='toolbar' macro='toolbar closeTiddler closeOthers +editTiddler > fields syncing permalink references jump'></div>
<div class='webview' macro='tiddler webviewindex'></div>
<div class='title' macro='view title'></div>
<div class='viewer' macro='view text wikified'></div>
<div class='tagClear'></div>
<!--}}}-->
{{tableindex{
|[[Welcome|Welcome to the Webview TiddlyWiki]]|[[Instructions]]|[[Subtopic menu instructions]]|
}}}
config.options.chkSaveBackups = false;
config.options.chkEnableAnimations = false;
config.options.chkShowRightSidebar= false;
config.options.chkSinglePageMode= true;
config.options.chkSinglePagePermalink= false;