2 months Surface RT – some thoughts from scientists perspective

There are countless reviews on the Surface RT already, but I consider myself some kind of non-average user, so I’d like to share my experience too.

To understand my argument on the device, you should know:

Who I am

I am a undergraduate Biology student from Germany with some experience in WPF/Multitouch/Kinect/Windows Phone/Windows 8 development using C#. Most software I write is just for personal use, but I published some of my work (WP7, Win8) as well. Since the launch of the first public beta, I‘ve been using and developing for the Windows 8 platform, so I have a reasonable understanding of what’s going on.

The Surface RT is my very first tablet computer. I’ve considered to get other devices (HP ElitePad, Samsung – ARM as well as x86), but decided that the Surface RT was the best fit.

Everyday tasks

Just like my HTC Mozart, I use the Surface a lot. It accompanies me to lectures, in the lab, or when travelling by train. Except for watching my favorite TV series, I don’t use it for entertainment (gaming, music), but for creating, or studying.

Lecture

In a lecture I  take notes and or follow the slides and maybe sometimes even browse Reddit or Facebook. Before the Surface, I used to do this with my phone, usually causing the battery to be dead until 4 PM..

+ taking notes, following slides

+ less smartphone-battery drain

+ charge the phone in the lecture =D

- PDF editing (Reader, PDF Touch) apps need to be improved

Traveling

I travel about 5 hours a week by train and use the Surface to watch my favorite TV series, or to go through lecture slides (aka study). To connect to the internet, I need to use my phones Internet Sharing, but I usually don’t do that, because A there’s almost no connectivity on the train and B due to my 50 MB data contract, it’s painfully slow. (Actually not significant for Twitter/FB/Mail on the phone.)

Sometimes I use the time on the train to write protocols, which involves a lot of Word and Excel. Equipped with a type cover, I can be productive without carrying something big and heavy.

In the Lab

As I mentioned, I‘m studying Biology, so we have a lot of internships/lab work where we do experiments and stuff. We need to write protocols on the experiments – that’s where Surface comes in. Taking measurements and pictures can be a lot of work (and chaotic) if you don’t have the right setup. For that purpose I wrote an app that can be used to manage the data, pictures, videos and files of many experiments while maintaining their context.

The data is not synced to the cloud or something (I’m just not that good..), but stored in either the app, or a folder you can select. In my case it’s a BitLocker-encrypted 16 GB USB key (you can see it in Figure 2 below) drive (8.50 €).

Figure 2: You can make a tree-like structure for your experiments and add fields of data, as well as files.

Figure 2: You can make a tree-like structure for your experiments and add fields of data, as well as files.

Figure 2: You can make a tree-like structure for your experiments and add fields of data, as well as files.

Figure 2: You can make a tree-like structure for your experiments and add fields of data, as well as files.

There are still many things I’d like to improve about the app, but I already use it heavily in the lab.

This is exactly the kind of use case where the Surface RT scores best, because of its long lasting battery, robustness, performance, weight and of course the USB port.

When taking a lot of measurements wich would usually be stored on paper, I can immediately type them into the Excel sheet instead.

The only disadvantage of Windows RT at this point may be that you can’t run the specialized software you usually work with as a scientist (device-specific control software, ImageJ, or other software you probably never even heard of). Technically Windows RT apps are perfectly capable of these things, but most of the time you’re using software which hasn’t been updated for many years, or even decades (no kidding, take a look at Figure 3!) and therefore won’t be ported anytime soon..

Figure 3: I have no idea how old this thing is, but it's frequently used!

Figure 3: I have no idea how old this thing is, but it’s frequently used!

With a Windows 8 Pro tablet one could analyze the data, but for capturing stuff the Surface RT is great and you can still use it as a real tablet as it does “connected standby”, the battery lasts longer etc.!

I love my Surface RT, use it a lot and can absolutely recommend it to anybody else. There are tons of things I didn’t mention and lots of RT apps to come =)

I’d also love to hear your thoughts on non-mainstream use cases^

Localizing Enums (in a ComboBox)

Enums have many useful applications and are often used in CoboBoxes to let the user select things. In the code behind the enum values are often defined using more or less cryptic text, because neither spaces, special characters, or leading numbers can be used in enum values (for good reasons!). Therefor it is necessary to change the text to something more understandable (language-localized in some cases).

One way to achieve this is to create the ComboBox items manually, but it’s much more comfortable to fill the ComboBox items directly with the enum values, because you can get/set the SelectedItem without converting it back and forth from/to the enum value.

You can’t override the .ToString() method of the Enum type, so we have to come up with another solution.

Just like any other control, the ComboBox uses a Template to create its items. We will replace the default template with one that uses a Comverter to populate the items.

The converter will be called “EnumNameConverter” and that’s its code:

EnumNameConverter

As you can see the converter checks if the passed value is of type Enum, so if it’s ‘misused’ it will not throw an Exception. Then it calls an extension method ‘GetValueName’ that will care for converting the Enum to a string. (We could do this in the Converter as well, but if we do it in an extension method, you can use it independently of the Converter.)

That’s the code of the GetValueName extension method:

GetValueName

We have three options to convert the Enum value to a string:

  1. If the GetValueNameMethod was set to something (I’ll come back to that later)
  2. The System.ComponentModel.DataAnnotiations.Display Attribute (its Name property) can be used to describe an Enum’s value directly in the definition – the downside: it only allows for static values, thus no localization logic is available
  3. The inherited .ToString() method that would be used by the default template

If either of the methods returns a null/whitespace/empty string, we will fall back to the next one.

Now let’s talk about the GetValueNameMethod property. It’s a static property of the EnumExtensions class. You can set it to any method of type void(string) of your liking. And it just happens that if you implement resource localization like explained in the samples (keyword: x:Uid) you will have a GetString(string) method that returns the localized string from your resource file. To localize an Enum you need to add a new entry to your Resources.resw file:

Key: EnumName_EnumValueValue: LocalizedEnumValue

Key: EnumName_EnumValue
Value: LocalizedEnumValue

Now we can localize any Enum value to a string using the Enum.Value.GetValueName() method.

For the ComboBox to use the Converter, we need to define the new ItemTemplate. That’s the code:

EnumItemTemplate

To use the template from an extension method, a few tricks have to be used. I won’t go into the details, but you can contact me if you want to know^

For the TCD.Controls package, I wrote another extension method (to the ComboBox type) that applies this template for you. Just call .UseEnumItemTemplate() on the ComboBox you want to use with Enums.

Bottom line:

  • EnumExtensions.GetValueNameMethod
    • set this to your LocalizedStrings.GetString(string) method
  • Enum.Value.GetValueName
    • returns localized string, DisplayAttribute.Name, or .ToString
  • ComboBox.SetUpItems
    • fill the ComboBox with enum values (take a look at the overrides/parameters!)
  • ComboBox.UseEnumItemTemplate
    • prepare the ComboBox for the Enum items

I’ve uploaded a code sample to the MSDN sample gallery as well: http://code.msdn.microsoft.com/Localizing-Enums-in-a-27932222

Keyboard Dismissing ComboBox

In the last few days I came across a design issue with the touch keyboard on Windows 8. The keyboard dismissal logic (documented here) defines a list of controls which do not cause the keyboard to dismiss when they get focused. The purpose is to prevent the keyboard from opening and closing all the time when the user fills out a form and is likely to switch between keyboard-editable controls such as TextBox and other controls like AppBar, Checkbox, RadioButtons the ComboBox and some more.

While that works fine with the other controls, ComboBox expands when interacted with and might get covered by the touch keyboard. And unfortunately you can’t change that behavior, or manually dismiss a deployed touch keyboard. (The user is in complete control over the keyboard.)

While on the MSDN forums it was suggested to alter the layout such that the ComboBox is less likely to collide with the touch keyboard, this was unacceptable in my case. (Screenshot below…)

Screenshot of my app, where I first met the problem

Screenshot of my app, where I first met the problem

I decided to go for a user control that encapsulates a real ComboBox, but intercepts the pointer, causing the keyboard to dismiss. This is done by setting IsHitTestVisible=false on the ComboBox and set it to true after the container (a Button control) was tapped (and caused the keyboard to dismiss). Because the ComboBox did not handle the tap, it need to be opened manually. You can of course control a ComboBox with the keyboard as well (arrow keys, space, enter, tab) and I had a few issues with that, but finally I got it right and now you can’t distinguish the KeyboardDismissingComboBox from a real one 😊

The KeyboardDismissingComboBox exposes the underlying ComboBox as a property so you can manually edit the items, subscribe to SelectionChanged or edit the template. However, you should not touch the IsHitTestVisible property, as this is vital to the dismissal behavior.

I for my part use ComboBoxes often to let the user select an enum value. For that reason I created an extension method (SetUpItems) to the ComboBox type which can be used to fill it with the values of an enum (first override) and optionally select the default item upon initialization (second override). The only limitation is that you can’t do that from XAML, but from Runtime only.

The control is now part of the TCD.Controls package on NuGet.

Please feel free to report bugs, or suggest changes 😉

03 Der Needleman-Wunsch-Algorithmus

  1. Einführung in die Bioinformatik
  2. Scoring von Alignments
  3. Der Needleman-Wunsch-Algorithmus

Die F-Matrix (abstrakt)

Der Needleman-Wunsch-Algorithmus geht bei der Berechnung des idealen Alignements in zwei Schritten vor, um exponentiell skalierende Rechenzeit zu vermeiden. Zunächst wird die sogenannte F-Matrix berechnet, aus welcher anschließend das ideale Alignment zusammengesetzt wird.

Zur Veranschaulichung alignen wir die Sequenzen GACFC und GCFHC.

Jedes Feld in der Matrix (jede Zelle der Tabelle) beinhaltet einen Score. Diese Punktzahl ist jene, die auf dem Weg zur Berechnung des Feldes gesammelt wurde. Zur Berechnung einer Zelle sind immer die Felder links oben, oben und links notwendig:

Unter den drei Feldern wird jenes gewählt, durch das sich die Höchste Punktzahl erreichen lässt:

  • Oben, wenn eine Lücke in der zweiten Sequenz (Spalten der Tabelle) die meisten Punkte bringt. Punktzahl = oberes Feld + gap penalty = -8 + -8 = -16
  • Oben-links, wenn das entsprechende Aminosäure-Paar die meisten Punkte bringt. Punktzahl = oben-links + Score(G-G) = 0 + 8 = 8
  • Links, wenn eine Lücke in der ersten Sequenz (Zeilen der Tabelle) die meisten Punkte bringt. Punktzahl = linkes Feld + gap Penalty = -8 + -8 = -16

Die höchste Punktzahl ist 8, also wird das Feld oben-links gewählt.

Wir gehen nun ein Feld nach rechts und berechnen wieder die möglichen Punktzahlen:

Die blauen Striche zeigen den Rechenweg, der gegangen wurde, um die Punktzahl eines Feldes zu berechnen. Horizontale und Vertikale Striche verwenden die gap Penalty. Beim diagonalen Rechenweg wird dagegen die Punktzahl des Pärchens verwendet.

Das Paar GC hat einen Score von -3. (siehe BLOSUM50)

  • -16 + -8 = -24
  • -8 + -3 = -11
  • 8 + -8 = 0

Die höchste Punktzahl lässt sich also durch eine Lücke in der ersten Sequenz erreichen.

Auf diese Weise wird die Tabelle Zeile für Zeile gefüllt:

Nur ein Rechenweg hat zur höchstmöglichen Punktzahl geführt. Er beinhaltet sowohl Lücken in der ersten, als auch Lücken in der zweiten Sequenz.

Auswählen des Alignments (abstrakt)

Der zum letzten Feld führende Rechenweg muss nun aufgespürt werden. Dazu wird immer das Nachbarfeld ausgewählt, welches für die Berechnung verwendet wurde. (Die blaue Linie kennt der Algorithmus natürlich nicht.)

Ähnlich wie bei der Berechnung der Tabelle, wird das Nachbarfeld gewählt, durch das die (höchste) Punktzahl errechnet wurde. In diesem Fall das links-oben-Feld. Das entsprechende Aminosäuren-Paar wird dem fertigen Alignment (im Bild unten rechts) hinzugefügt. (Merke: diagonal: Match, links: Lücke im Ersten, links: Lücke im Zweiten)

Das gewählte Feld ist als nächstes dran:

Hier ergibt sich die höchste Punktzahl durch eine Lücke in der ersten Sequenz, also geht’s mit dem linken Feld weiter.

Schließlich gelangt man wieder beim ersten Feld an und hat das korrekte Alignment zusammengesetzt:

Du kannst das Programm auch herunterladen und die Berechnung schrittweise nachverfolgen:

http://dl.dropbox.com/u/7813771/Blog/Bioinformatik/Needleman-Wunsch%20Visualisierung.zip (falls es nicht starten sollte, musst du wahrscheinlich das .NET Framework 4 Client Profile nachinstallieren – der Installer ist auch dabei)

Wenn du im Programm bist, kannst du auswählen, dass die Berechnung nur schrittweise durchgeführt wird (None, FMatrix, Alignment, Both). Mit dem “calculate”-Knopf wird gestartet und mit “next” geht’s einen Rechenschritt weiter. Wenn du mit der Maus über eine der Zahlen fährst, erscheint die Berechnung des Feldes.

Die F-Matrix (Code)

Der Code für den Needleman-Wunsch Algorithmus ist etwas ausführlicher, als die vorherigen Beispiele, daher habe ich ihn hier auf drei Methoden aufgeteilt:

  • AlignSequenccesAsync -> wird aufgerufen um die Sequenzen zu berechnen
  • CalculateFMatrix -> berechnet aus zwei Sequenzen die F-Matrix
  • SelectAlignment -> wählt aus einer F-Matrix das Alignment aus

Beginnen wir zunächst mit dem Berechnen der F-Matrix:

Oben haben wir gesehen, wie die F-Matrix manuell berechnet werden kann. Bei Sequenzen mit mehreren Tausend Aminosäuren ist das natürlich nicht mehr machbar.

In C# verwenden wir für die F-Matrix ein zweidimensionales int-Array, welches in Zeile 35 initialisiert wird.

Zunächst werden in Zeile 37-41 die jeweils erste Zeile bzw. Spalte der Tabelle gefüllt. Die erste Zelle (gap vs. gap) bekommt hier ausnahmsweise keine gap-penalty – gap-gap (am Anfang des Alignments) macht schließlich auch keinen Sinn. Für die restlichen Zellen der Spalte bzw. Zeile, wird für die Punktzahl zur Berechnung nur die gap-penalty verwendet, schließlich treten auf dem Weg zur Zelle keine echten Paare auf.
Für die übrigen Zellen wird der im vorherigen Kapitel beschriebene Rechenweg durchgeführt: In den Zeilen 47-49 werden die möglichen Punktzahlen aus den umliegenden Feldern berechnet. Die höchste wird anschließend ausgewählt und in der Tabelle (f) gespeichert (Zeile 55).

Auswählen des Alignments (Code)

Die F-Matrix enthält nun alle Informationen, die zur Auswahl des idealen Alignments benötigt werden. Beginnend mit der letzten Zelle, wird nun jeweils die Differenz zu den drei anderen Zellen berechnet (scoreDiag, scoreUp, scoreLeft in Zeile 65-68). Anschließend wird geprüft, ob die jeweilige Nachbarzelle für die Berechnung verwendet wurde. Für die oben, bzw. links liegende Zelle muss die Differenz zur aktuellen Zelle der gap-penalty entsprechen, während die Differenz zur oben-links-Zelle dem Score für das aktuelle Paar entspricht.

Das fertige Alignment (alignmentA, alignmentB) wird mit dem entsprechenden Paar verlängert. Die Zählvariablen i und j werden nun verringert, sodass das gewählte Nachbarfeld als nächstes dran ist. (Für diagonal beide verringern; nach oben j verringern; nach links i verringern) (Zeile 69-87)

Sobald eine der beiden Variablen i, oder j bei 0 angekommen ist (man ist am Ende einer Sequenz angelangt), muss der Rest der verbleibenden Sequenz mit gaps alignt werden. (Zeile 89-100)

alignmentA und alignmentB enthalten nun die berechneten Sequenzen, sind allerdings noch in umgekehrter Reihenfolge. Das Umkehren der Reihenfolge wird in der AlignSequencesAsync-methode durchgeführt. Dazu wird die Methode Reverse-String verwendet, auf die ich jetzt nicht weiter eingehe.

AlignSequencesAsync verknüpft CalculateFMatrix und SelectAlignment:

Anfangs (Zeile 15+16) sind die berechneten Sequenzen leer (“”). Die eigentliche Berechnung wird auf einem neuen Thread durchgeführt. Das wird so gemacht, damit das Programm auch bei längeren Berechnung noch ‘responsive’ bleibt und es nicht so aussieht, als sei es abgestürzt.

In den Zeilen 24 und 25 wird das berechnete Alignment umgekehrt – SelectAlignment geht schließlich rückwärts durch die Tabelle.

Nachdem alignmentTask fertig ist (Zeile 28) wird das fertige Alignment als string[] zurückgegeben (Zeile 29).

So viel zur Theorie. Das Beispielprojekt zum Selbermachen folgt in Kürze.

02 Scoring von Alignments

  1. Einführung in die Bioinformatik
  2. Scoring von Alignments
  3. Der Needleman-Wunsch-Algorithmus

Prüfen auf Identität

Die einfachste Art, zwei Sequenzen miteinander zu vergleichen ist, zu prüfen, ob sie identisch sind. Dazu müssen jeweils die 0. Position der ersten Sequenz mit der 0. Position der zweiten, die 1. der ersten mit der 1. der zweiten und so weiter vergleichen werden:

Der folgende Code macht genau das gleiche, verwendet dabei jedoch statt einer for-Schleife eine while-Schleife:

while-Schleifen brauchen nicht nur mehr Zeilen, sondern sind auch gefährlicher, da man gerne mal das ‘i++;’ vergisst.

Das Ergebnis einer solchen Prüfung kann offensichtlich nur zwei Werte annehmen: true oder false.

Sowohl Mutationen, als auch Rasterverschiebungen führen bei dieser Methode zu einem ‘false‘:

APFELSAFT
APPELSAFT
oder
APFELSAFT
PFELSAFT

Im folgenden Kapitel betrachten wir zunächst der ersten Fall und bewerten ein Alignment unter Berücksichtigung von Mutationen.

Bewerten von Mutationen

Welches der folgenden zwei Alignments ist das wahrscheinlichere?

KIRSCHSAFT
PIRSCHSAFT
oder
KIRSCHSAFT
KIRSCHSAAT

Beide Alignments unterscheiden sich in genau einer Aminosäure. Um eine qualifizierte Aussage zu treffen, bei welchem es sich um das ‘bessere’ bzw. wahrscheinliche Alignment handelt, müssen wir den Austausch K<>P mit dem Austausch F<>A vergleichen.

Hierzu wird eine sogenannte ‘Substitution Matrix‘ verwendet. Dabei handelt es sich um eine Tabelle, in der Aminosäure-Paare (z.B. P-P, G-C, W-A..) eine Punktzahl (Score) zugewiesen wird. Paare gleicher Aminosäuren bekommen dabei eine positive Punktzahl, während eine Mutation in der Regel einen negativen Score bekommt. Es gibt verschiedene solcher Tabellen, die sich in ihrer Berechnung unterscheiden. Wir verwenden hier die BLOSUM50 Matrix. Berechnet wird der Score bei BLOSUM50 durch die Formel

Wobei p(ab) die Wahrscheinlichkeit für das Auftreten des Paares A-B in natürlichen Proteinsequenz-Alignments ist, während q(a) bzw. q(b) die Frequenz in zufälligen ist. Das Ergebnis wird zur nächsten Ganzzahl gerundet.

Der Score einer Sequenz berechnet sich aus der Summe der Scores aller Paare. Die Paarung einer Aminosäure mit einer Lücke (gap) ist ebenfalls zulässig und wird immer mit dem selben Score, der sogenannten gap-penalty bewertet. In der abgebildeten Tabelle hat diese den Wert -5.

In unserem Beispiel oben unterschieden sich die ersten beiden Sequenzen im Paar K‑P, welches den Wert ‑1 hat, während sich die folgenden zwei Sequenzen im Paar A‑F mit dem Wert ‑3 unterschieden. Der Score für das erste Alignment summiert sich damit auf 62, während der des zweiten 58 beträgt. (Man beachte, dass die korrekte Paarung von K‑K 6 Punkte, während die von F‑F 8 Punkte bringt.)

Die Sequenzen KIRSCHSAFT und PIRSCHSAFT haben damit eine größere Ähnlichkeit, als KIRSCHSAFT und KIRSCHSAAT.

Bewerten von Alignments

Das vorherige Kapitel hat schon einiges vorausgegriffen, doch soll nun auch gezeigt werden, wie die Berechnung des Scores ‘in großem Stil’ durchgeführt wird.

Ähnlich wie beim direkten Vergleich zweier Sequenzen, werden die Sequenzen in einer for-Schleife gelesen. Die int-Variable ‘score’ wird verwendet, um den Punktestand zu messen. In jedem Schritt wird der Punktestand um den entsprechenden Wert erhöht. Dazu muss auf die SubstitutionMatrix zugegriffen werden.

Um mit der SubstitutionMatrix arbeiten zu können, benötigen wir den Objekttyp Dictionary<Key, Value>.

Ein Dictionary<Key, Value> ähnelt einem Nachschlagewerk, bei dem jedes Element (Value) mit einem anderen Objekt (Key) identifiziert wird. Nehmen wir an, dass das Dictionary<char, int> mit der Bezeichnung ‘buchstaben’ das folgende Key-Value-Pair enthält: ‘C’, 3

buchstaben['C'] liefert damit den int-Wert 3 zurück.

Bei der SubstitutionMatrix handelt es sich um ein Objekt des Typs Dictionary<char, Dictionary<char, int>>, also ein Dictionary<char, …>, welches als Value ein Dictionary<char, int> beinhaltet. Das äußere beinhaltet damit die Zeilen der SubstitutionMatrix (z.B. substimatrix['C'] ist die Zeile ‘C’), während das Innere die Einträge in der Zeile beinhaltet (z.B. substimatrix['C']['P'] ist der Score für ein C‑P-Paar – also ‑4).

Sowohl im folgenden Codebeispiel, als auch im herunterladbaren Beispielprojekt, wird die BLOSUM50-Substitutions Matrix mit ‘blosum50matrix’ bezeichnet. Wie dieses Objekt zustande kommt, kannst du dir im Code anschauen, ist hier aber nicht weiter von Bedeutung.

Wichtig ist, dass wir in Zeile 207 überprüfen, ob wir bereits am Ende einer der beiden Sequenzen angelangt sind, bzw. ob das Zeichen an der Position ‘-’, also eine gap ist. In diesem Fall müssen wir die gap penalty verwenden. Andernfalls wird der score in Zeile 210 um den Wert des Paares erhöht, der in der BLOSUM50 nachgesehen wird.

Mit der oben beschriebenen Methode kann nun Berechnet werden, wie gut ein Alignment ist.

Weiter geht es mit dem Needleman-Wunsch Algorithmus.

01 Einführung in die Bioinformatik

Gerade Biologen/Biotechnologen ohne Vorkenntnisse aus der Informatik, haben oft Probleme beim Verständnis grundlegender Verfahren der Bioinformatik. In einer kleinen Serie von Tutorials, werde ich versuchen, dieser Zielgruppe den Einstieg zu erleichtern. Die Codebeispiele folgen der Syntax der Programmiersprache C#, die abstrakten Verfahren können aber auf andere objektorientierte Programmiersprachen übertragen werden. (z.B. Java, C++, VisualBasic…)

Die Theorie zu lesen ist zwar schön und gut, doch am Besten verstehen, was vor sich geht kann man, indem man es selbst macht. Ich empfehle jedem, die Codebeispiele nachzubauen, bzw. in echt nachzuvollziehen! Keine Sorge, du musst nicht alles selbst machen. Im folgenden findest du zunächst eine Anleitung, wie du dir die notwendige Software installierst. Anschließend kannst du ein bereits vorbereitetes Projekt herunterladen.

  1. Einführung in die Bioinformatik
  2. Scoring von Alignments
  3. Der Needleman-Wunsch-Algorithmus

Vorbereiten der Software

Um die Codebeispiele testen zu können, benötigst du eine sogenannte ‘Entwicklungsumgebung’. Bei “Microsoft Visual Studio Express 2012 for Windows Desktop” handelt es sich um eine kostenfreie Version von Visual Studio 2012. Als Student bekommt man über MSDNAA übrigens auch eine kostenfreie Lizenz für die Vollversion, welche sonst über 600€ kostet!

Herunterladen kannst du die Software hier: http://www.microsoft.com/visualstudio/eng/downloads#d-express-windows-desktop

Wer noch mit Windows XP/Vista ‘arbeitet’ sollte 1. Visual C# 2010 Express als Übergangslösung verwenden und 2. Upgraden!

Ich empfehle die englische Version, da die deutschen Übersetzungen der Begriffe ziemlich nichtssagend sind und bei der Suche nach Problemlösungen im Internet nur im Weg sind.

Mit einem Doppelklick öffnest du den Installer. Der macht den Rest dann von alleine.

Nach dem klick auf ‘Install’ geht der Rest von selbst.

Die Installation dauert eine Weile – Visual Studio ist schließlich eine ziemlich mächtige Software und mit der Version die du gerade installierst, kann man jede Art von Desktop-Anwendungen erstellen.

Nachdem die Installation fertig ist, kann du das bereits vorbereitete Beispielprojekt herunterladen: http://dl.dropbox.com/u/7813771/Blog/Bioinformatik/Bioinfo01.zip

Entpacke das Archiv an einen Ort deiner Wahl. Im Ordner ‘Bioinfo01′ befindet sich die Datei ‘Bioinfo01.sln’. Öffne sie mit einem Doppelklick. (Die Aufforderung dich zu registrieren kannst du erstmal wegdrücken.)

Als nächstes sollte es etwa so aussehen:

Mit einem Klick auf “Start” kannst du das Programm starten:

Wie das Programm funktioniert erkläre ich gleich, doch zunächst brauchen wir ein paar…

Grundlagen der objektorientierten Programmierung

Zum vereinfachten Verständnis unterscheiden wir zunächst drei Dinge:

  • Klasse – definiert die ‘Art’ eines Objekts, zum Beispiel string, int, oder double
  • Instanz – das Objekt selbst (repräsentiert eine Information)
  • Funktion – führt eine Operation durch (zum Beispiel text.Replace(‘A’, ‘B’) macht aus jedem ‘A’ in der string-Instanz ‘text’ ein ‘B’)

Daneben gibt es noch die sogenannte ‘Syntax’, welche festlegt, wie Code zu interpretieren ist. (Vergleichbar mit Grammatik in der Sprache.)

Ein einfaches Codebeispiel – manipulieren eines strings

(Dieses Codebeispiel findest du auch im Bioinfo01-Beispielprojekt…)

In Zeile 1 wird zunächst ein string mit der Bezeichnung ‘beispielText’ initialisiert. Ihm wird die Zeichenkette “Wo ein Wille ist, ist auch ein Weg.” zugewiesen.

Anschließend wird die Methode ‘Replace’ auf das Objekt ‘beispielText’ angewandt und der zurückgegebene Wert der dem Objekt ’beispielText’ zugewiesen.

Referenzieren einzelner Zeichen in einem string

Um eine Zeichenkette (Aminosäuresequenz) zu analysieren, reicht es nicht, sie als Ganzes anzuschauen. Man muss auch auf einzelne Zeichen in der Zeichenkette zugreifen können.

Hierfür wird die Zeichenkette als sogenanntes Array interpretiert. Ein Array hat eine definierte Länge und mit einer Ganzzahl (int) kann auf seine Elemente zugegriffen werden.

Nachdem ‘Alphabet’ und ‘zusammengesetzt’ initialisiert wurden, wird in Zeile 3 zusammengesetzt’ ein neuer Wert zugewiesen. Der neue Wert setzt sich zusammen aus dem vorherigen Wert von ‘zusammengesetzt’ und dem 1. Element aus ‘Alphabet’.

In der nächsten Zeile wird ‘zusammengesetzt’, welches jetzt den Wert “B” hat, der Wert “B” + ‘L’ zugewiesen.

Die dritte Zeile macht genau das selbe, nur wird hier die Kurzschreibweise benutzt. Dies ist in vielen Fällen übersichtlicher!

Generieren einer zufälligen Aminosäuresequenz

Jede Aminosäure wird durch ihren Ein-Buchstaben-Code repräsentiert. Dadurch kann eine Aminosäuresequenz als string behandelt werden.

Zunächst definieren wir einen string, welcher alle Ein-Buchstaben-Codes enthält:

string AminoAcidLetters = “ARNDCQEGHILKMFPSTWYV”;

Die Bedeutung der Zeichen kann dieser Tabelle entnommen werden.

Damit wir uns auch an anderer Stelle einfach zufällige Sequenzen erzeugen können, schreiben wir den Code als neue Methode. Die Methode bekommt einen Parameter vom Typ ‘int‘ mit der Bezeichnung ‘length’. Dadurch kann beim Aufruf der Methode die Länge der zu generierenden Sequenz festgelegt werden. Die Methode heißt ‘RandomAASequence’ und gibt einen string zurück.

Bitte auf das Bild klicken, um es in voller Größe zu sehen.

Um effizientes Arbeiten auch bei sehr langen Sequenzen sicherzustellen, verwenden wir die StringBuilder Klasse an Stelle der string Klasse. Mehr Informationen zum Unterschied zwischen string und StringBuilder findest du hier.

Besonders wichtig ist, dass du verstanden hast, was in Zeile 35 vor sich geht: Bei “r<lenght” handelt es sich um ein sogenanntes Statement. Es kann entweder wahr (true) oder falsch (false) sein. Alles was in den Klammern (Zeile 36-41) steht wird immer wieder ausgeführt, bis das statement ‘r<length’ nicht mehr wahr, also false ist. Dieser Fall tritt ein, wenn die Variable ‘r’ den Wert von ‘length’ oder größer annimmt. Damit wir uns nicht in einer endlosen Schleife verfangen, müssen wir mit jeder Iteration ‘r’ um 1 erhöhen!

Nachdem die for-Schleife ausgeführt wurde, enthält ‘sequence’ unsere zufallsgenerierte Aminosäurensequenz. In Zeile 43 wird diese an den Aufrufer (caller) der Methode zurückgegeben.

Der oben Dargestellte Code ist durch die vielen Kommentare leider etwas unübersichtlich geworden. Gekürzt und optimiert sieht er so aus:

Bitte auf das Bild klicken, um es in voller Größe zu sehen.

Das Aufrufen von RandomSequence(40) gibt nun eine zufällige Sequenz von 40 Aminosäuren zurück. Zum Beispiel: GHHFWSPMFGLKMNKMWHYNDGYFGHEHPAYHFPRRWCPF

Anders als das ausführliche Codebeispiel, ist dieses noch nicht im Bioinfo01-Beispielprojekt. Um ein Gefühl dafür zu bekommen, kannst du es ja mal nachprogrammieren ;)

Wie wichtig die Verwendung des StringBuilders anstatt eines normalen strings ist, zeigt der direkte Vergleich: die Generierung einer 100 000 Zeichen langen Sequenz dauert bei Verwendung des string Typs etwa 300 mal so lang!

Als Nächstes geht es weiter mit dem Scoring von Alignments.

TCD.Web.NotiConn – communicate between handsets without a server

Two days ago, when I was cycling, suddenly I had the answer:

Imagine you have two Windows Phone 7 devices and want to establish a two-way connection between them. For example to play a game of Tic-Tac-Toe. You can do this either with a server on the internet, that connects the clients with each other, or the multicast protocol on WiFi-networks. The same WiFi network may not always be available to both users, but you don’t want to set up a server either (maybe, because you’re only doing this for fun, or you don’t have the resources).

The only way to send messages to a WP7 app via the internet is to use push notifications. But how do you exchange the channel addresses between the devices? One way is to use a QR code:

  1. Establish a push notification channel on both devices
  2. Encode the channel URI into a QR code
  3. Scan the QR code of the other device
  4. Send a message with your own channel URI to the other device
  5. Connection established =)

Other methods of exchange can be used as well, for example NFC. You could as well require the user to mail, copy and paste the channel URI, but this is not very convenient.

To my knowledge, push notifications on Android ad iOS work pretty much the same, so you can do this cross-platform as well.

Here are a few screenshots of the sample application (link below), which features a simple chat between the two devices.

Oh and by the way: this works with multiple clients as well!

Here you can download the sample application, or the NuGet package

cheers