Codierung / Serialisierung von Binärfeldern in einer proprietären XML-Datei (Roche LC480 .ixo-Datei)

9

Ich habe kürzlich eine Exportdatei erhalten, die vom Roche LightCycler 480 Instrument erzeugt wurde. Es verwendet ein proprietäres XML-Format, für das ich noch keine Spezifikation gefunden habe.

Aus solchen Dateitypen möchte ich einige für meine Zwecke relevante Informationen extrahieren. Obwohl das meiste davon leicht geparst und interpretiert werden kann, enthält es eine Anzahl von (ungepolten) 64-kodierten Basisfeldern von binären / serialisierten Daten, die Arrays von Ganzzahl- und / oder Gleitkommazahlen darstellen. Ein Link zu der Beispieldatei finden Sie in diesem Kern .

Ich habe ein Fragment davon am Ende dieses Posts eingefügt. Das AcquisitionTable enthält insgesamt 19 solche codierten item Einträge. Dies stellt wahrscheinlich Arrays von Ganzzahl- ( SampleNo ) und Gleitkommawerten ( Fluor1 ) dar.

Wie die dekodierten Bytes in Integer- oder Gleitkommawerte übersetzt werden sollen, ist mir noch unklar. Bei der Decodierung der Basis 64 beginnt jedes Element mit der folgenden (hexadezimalen) 6-Byte-Sequenz:

%Vor%

Beachten Sie, dass, obwohl ich davon ausgehe, dass jedes Element die gleiche Anzahl an Zahlen (oder Zeilen) in dieser Tabelle enthält, ich eine andere Anzahl von decodierten Bytes für ähnliche Elemente beobachte: 5654 für Fluor1 und 5530 für Fluor2 .

Zusätzlich zu den Arrays, von denen ich vermute, dass sie (sequentielle) Ganzzahlen enthalten, kann ein Muster beobachtet werden:

%Vor%

Es sieht aus wie Paare von Bytes, wobei das zweite Byte um 0x12 (18) und gelegentlich eine Gruppe von 3 Bytes mit 0x00 als zweites Byte ansteigt, wenn das Nibble des letzten Bytes 3 ,% ist co_de% oder D für die drei Beispiele.

Ich habe mich gefragt, ob der Typ des Kodierungs- / Serialisierungsformats für irgendjemanden offensichtlich ist (oder, noch besser, wenn jemand eine Spezifikation dieses Dateiformats hat).

Ich glaube, dass die zum Erstellen dieser Dateien verwendete Software derzeit Java-basiert ist, aber eine Historie als Windows / MFC / C ++ - Produkt hat.

%Vor%

... abgeschnitten

%Vor%

... abgeschnitten

%Vor%     
Alex 20.10.2016, 17:17
quelle

1 Antwort

2

Das habe ich bisher.
Das Dokument, das Sie verwenden, stammt nicht von einem tatsächlichen PCR-Lauf, wie aus den lesbaren Daten hervorgeht. Es ist ein Farbkompensationslauf ( kurze Übersicht, die der Datei zu entsprechen scheint ) (< a href="http://icob.sinica.edu.tw/pubweb/bio-chem/Core%20Facilities/Data/R401-core/LightCycler480%20II_Manual_V1.5.pdf"> vollständige aktualisierte Handbuch, Seite 250, nicht als passend ). Genauer gesagt scheint es sich um einen Farbkompensationslauf für den Farbstoff "FAM / Pulsar 650" zu handeln.
Der Ausgabetyp, wie Sie darauf hinweisen, ist diese "AcquisitionTable" mit 2400 "counts", die, wie ich meine, von der Ausgabe abweichen muss, die Sie normalerweise von einem PCR-Lauf erhalten würden. Ich bin mir sicher, dass Sie diese bereits gefunden haben, aber einige öffentliche Beispiele für PCR-Vorlagen (nicht abgeschlossene Läufe) sind hier , hier , hier und hier .

Laut dem LCRunProgram in Ihrer Datei war das Protokoll hier:
Halten Sie 95 ° C für 0 "bei einer Geschwindigkeit von 20 ° C / s halte 40 ° C für 30 ", 20 ° C / s
Halten Sie 95 ° C für 0 "bei 0,1 ° C / s, Erfassungsmodus" 2 ".

Also erwarten wir, dass der Erfassungszeitraum ungefähr (95 ° C-40 ° C) / 0,1 ° C / s = 550 Sekunden gedauert hat; während dieser Zeit sollte eine feste Anzahl von Akquisitionsereignissen pro Sekunde gegeben sein.

EDIT 0 - das habe ich am Anfang gemacht, also lösche ich es nicht, aber später habe ich weitere interessante Informationen erhalten (siehe unten).

Ich habe mir die Daten mit einem einfachen Python-Skript angesehen (ich bin ein Python-Typ), um nach Mustern zu suchen. Das Skript enthält die Anfangszeichenfolgen Ihrer Daten in einem Dictionary namens values , das hier zu lange wäre; so hier ist es in einem Kern , genau wie Sie es tun mussten.

%Vor%

Lassen Sie uns das Offensichtliche aus dem Weg räumen und sagen, dass ProgramNo und CycleNo dieselben Daten enthalten; und alle Gain sind identisch. Ich poste also nur jeweils eins.

Wenn Sie nun das Skript mit dem Trennzeichen b'\r' versuchen (nur um eines zu versuchen), werden einige davon in Blöcken von 272 (271 + Trennzeichen) Bytes abgeschnitten. Die anderen sind nicht sauber.

%Vor%

Die Trennung nach b'\t' ergibt ähnliche Ergebnisse:

%Vor%

Und das Trennen um b'\n' teilt die Gewinne diesmal auf ähnliche Weise auf:

%Vor%

Ich behaupte also nicht, dass diese "Separatoren" von Bedeutung sind; Ich denke, dass es sich um seltene Zeichen handelt, die die Daten in 272-Byte-Blöcken zu schneiden scheinen, und dieser Wert, 272 Byte, könnte wichtig sein, um zu verstehen, wie diese Daten gespeichert werden.

Der Anfang jeder Zeichenfolge "BARZ" erscheint wie eine "foo-bar" -Ding; wahrscheinlich als Check am Anfang der Kopfzeile gesetzt.

Interessant ist auch, dass die gains -Daten in 8 gleich große Blöcke (plus zwei kleinere Blöcke) aufgeteilt werden. Wenn diese Daten von einer 96-Well-Platte stammen, würde ich untersuchen, ob dies möglicherweise ein Header ist und dann 8 Chunks (Zeilen), die in 12 Elemente (Spalten) aufgeteilt werden könnten, so dass 8 * 12 = 96 die Einstellung repliziert einer 96-Well-Platte.

Wenn diese "272 Bytes pro Zeile" Hypothese wahr ist, dann könnten die Daten in ProgramNo , SampleNo etc, die sich in 272-Byte-Stücke teilen, erklärt werden, wenn die Platte nicht voll war, und einige Brunnen hatten Proben (mit ein paar vollständigen Linien), während andere leer waren. Ich bin mir nicht sicher, ob dies für eine Farbkompensationsplatte sinnvoll wäre.

Time , Temperature , Error und Fluor s trennen sich nicht in Stücke und Sie haben recht, wenn Sie denken, dass es sich um eine Reihe von kontinuierlichen Werten handelt; nicht unbedingt schwebt aber. Die Fluoreszenz kann als "Einheiten" erfasst werden, die positiv sein können (ich habe keinen LightCycler, daher weiß ich nicht, ob das der Fall ist oder nicht).

Und das ist, wo ich so weit bin. Ich bin mir nicht sicher, ob ich Zeit haben werde, weiter zu gehen. Falls ich nicht antworten sollte, viel Glück mit Ihrem Vorhaben.

EDIT 1 :

Was also die SampleNo -Daten angeht, scheint es so strukturiert zu sein:
1) eine Kopfzeile, die durch 0x00 getrennt sein kann oder auch nicht:
 * Der Header BARZ , dann 2 mal 0x00 (insgesamt 6 Bytes)
 * drei Bytes, dann 0x00 (insgesamt 4 Bytes)
 * 17 Bytes, dann 0x00 (insgesamt 18 Bytes)
2) eine Reihe von Daten, die jeweils aus 16 Bytes bestehen und mit 0x00 enden (also jeweils 17 Bytes).
Das bedeutet, dass Samples einen Header und 66 Sätze mit 17 Bytes enthält.

EDIT 2:

Alles mit 0x00 teilen mit diesem schrecklichen Code:

%Vor%

Erträge:

%Vor%

So SampleNo , ProgramNo , SegmentNo , Error und% Gain s sind alle in Blöcke von 17 Bytes aufgeteilt (16 Bytes + 0x00).

EDIT 3 :
Die ersten fünfzehn 17-Bit-Blöcke von ProgramNo (und die Kopie CycleNo ) und Error sind identisch.
Nur zur Verdeutlichung, die "Chunks", die ich beschreibe, beschreiben Sie als eine Reihe von Zahlenpaaren, von denen eines um 0x12 zunimmt. Die von Ihnen erwähnte 0x00 ist der Separator zwischen den Chunks.

EDIT 4 :
Über Gain data, die Verbindung zwischen meinen ursprünglichen "272 Bytes" -Blöcken und den (16 + 0x00) -Byte-Blöcken ist, dass es ein sich wiederholendes Muster von 16 Blöcken gibt, 15 von ihnen sind "16 + 0x00" Blöcke und ein letzter Block hat eine 0x00 in der Mitte. Also 17 Bytes (= 16 + 0x00) * 16 Blöcke = 272 Bytes insgesamt für diese Wiederholung.
Der ganze String ist wie folgt aufgebaut: der "Header" -Teil, dann 8 solcher Wiederholungen von 17 Bytes * 16 Blöcken und dann vier 17 Bytes Blöcke am Ende. Also auf der einen Seite hatte ich Recht mit den 8 Blöcken, aber anscheinend lag ich falsch, als ich die Parallele mit einer PCR-Platte mit 8x12 Wells machte. Hier ist es eher wie 8 * 16 (+4).
Über Fluor etc. Daten, ich habe keine Antwort, aber ich würde versuchen, den Header zu strippen und sehen, ob irgendein (Integer oder Float) Komprimierungsalgorithmus kann daran arbeiten ... Komprimierte Daten würden erklären, warum Sie anders haben Längen für diese Felder.

    
Roberto 29.10.2016 20:04
quelle