Diese Dokumentation beschreibt die Implementierung einer flachen (Flatt-)Tabellendarstellung im DCC-Format, die Reshaping-Methodik sowie die Validierung dieser Darstellung und ihrer Parser mittels Primfaktorzerlegung.
Diese Dokumentation beschreibt die Implementierung einer flachen (Flat-)Tabellendarstellung im DCC-Format, die Reshaping-Methodik sowie die Validierung dieser Darstellung und ihrer Parser mittels Primfaktorzerlegung.
## 1. Flatt-Format vs. Long-Darstellung
## 1. Flat-Format vs. Long-Format
### Flatt-Format
### Flat-Format
In vielen Anwendungsfällen, wie etwa bei der Erfassung von Mikroskopbildern, werden höherdimensionale Daten in einem rasterartigen Format erfasst. Hierbei wird die Lichtintensität auf einem Gitter aus X- und Y-Positionen gemessen.
-**Long-Darstellung:**
-**Long-Format:**
Alle möglichen Kombinationen der Indexwerte (z. B. X und Y) werden explizit in der Tabelle gespeichert. Dies führt zu einer sehr großen Datenmenge, da redundante Indexwerte mehrfach vorkommen.
-**Flatt-Format:**
Die Indexwerte werden jeweils nur einmal als separate dcc:Quantities abgelegt, während die eigentlichen Messdaten in einer einzigen, flachen Liste gespeichert werden.
-**Flat-Format:**
Die Indexwerte werden jeweils nur einmal als separate `dcc:Quantities` abgelegt, während die eigentlichen Messdaten in einer einzigen, flachen Liste gespeichert werden.
Beispiel:
Bei einer Messung mit 1920 × 1080 Positionen würden im Long-Format ca. 2 × 2.073.600 Indexwerte gespeichert werden. Im Flatt-Format sind lediglich 1920 Werte für die X-Position und 1080 Werte für die Y-Position notwendig – eine Einsparung von **99,8 %** der Indexwerte.
Bei einer Messung mit 1920 × 1080 Positionen würden im Long-Format ca. 2 × 2.073.600 Indexwerte gespeichert werden. Im Flat-Format sind lediglich 1920 Werte für die X-Position und 1080 Werte für die Y-Position notwendig – eine Einsparung von **99,8 %** der Indexwerte.
Die Umrechnung von einem n-dimensionalen Index in einen eindimensionalen Flatt-Index erfolgt mittels der folgenden Formel:
Die Umrechnung von einem n-dimensionalen Index in einen eindimensionalen Flat-Index erfolgt mittels der folgenden Formel:
@@ -30,15 +30,15 @@ Diese Methode entspricht der **Row-Major-Order** (C-Style-Order), wie sie in Pro
### Long-Darstellungen müssen nicht speziell getestet werden
In der Long-Darstellung werden alle Indexkombinationen vollständig gespeichert, sodass keine Umrechnung von mehrdimensionalen in eindimensionale Werte erfolgt.
Dadurch ist das Risiko eines Mapping-Fehlers nicht vorhanden. Dennoch ist es sinnvoll und empfolen, zu prüfen, ob alle dcc:qunatites anch dem Parsen die selbe Länge haben um auszuschießen, dass das inkorrekte Parsen von Whitspaces wie z.B. beim Zeilenumbruch '\n\r' zu leeren Elementen geführt haben.
Im Flatt-Format hingegen findet eine Kompression der Indexinformationen statt – hier muss für jede Parser Implementierung einmal überprüft werden, ob die Umrechnung (Reshaping) korrekt vorgenommen wurde.
Dadurch ist das Risiko eines Mapping-Fehlers nicht vorhanden. Dennoch ist es sinnvoll und empfohlen, zu prüfen, ob alle `dcc:quantities` nach dem Parsen die selbe Länge haben, um auszuschließen, dass das inkorrekte Parsen von Whitespaces wie z.B. beim Zeilenumbruch '\n\r' zu leeren Elementen geführt hat.
Im Flat-Format hingegen findet eine Kompression der Indexinformationen statt – hier muss für jede Parserimplementierung einmal überprüft werden, ob die Umrechnung (Reshaping) korrekt vorgenommen wurde.
Genau diese Validierung erfolgt im Folgenden mittels Primfaktorzerlegung.
## 2. Validierung mittels Primfaktorzerlegung
### Mathematischer Hintergrund
Jeder Indexvektor in der Flatt-Tabelle besteht aus einer Folge von Primzahlen. Ein Eintrag $T(i_0, i_1, \dots, i_{N-1})$ der flachen Datenliste wird als Produkt definiert:
Jeder Indexvektor in der Flat-Tabelle besteht aus einer Folge von Primzahlen. Ein Eintrag $T(i_0, i_1, \dots, i_{N-1})$ der flachen Datenliste wird als Produkt definiert:
@@ -61,14 +61,14 @@ Stimmt die durch die Primfaktorzerlegung erhaltene Faktorliste mit der erwartete
### 1 oder 0 Indizierung
In diesem Beispil und im Python-Code wird wie in C und Python üblich mit 0 startend indiziert, die Methdoik lässt sich analog auch auf 1 Indizierung wie in Fortran, R oder Matlab anwenden.
In diesem Beispiel und im Python-Code wird wie in C und Python üblich mit 0 startend indiziert, doch die Methodik lässt sich analog auch auf 1 Indizierung wie in Fortran, R oder Matlab anwenden.
## 3. Beispiel-XML und Implementierung des Reshapings
Die folgende XML-Struktur demonstriert ein Beispiel für eine 3D-Flatt-Tabelle, in der die Indexvektoren und die flachen Daten als dcc:Quantities abgelegt sind. Die XML-Struktur enthält außerdem detaillierte Beschreibungen in Englisch und Deutsch, die erläutern, wie die Reshaping-Umrechnung und die Validierung mittels Primfaktorzerlegung erfolgen.
Die folgende XML-Struktur demonstriert ein Beispiel für eine 3D-Flat-Tabelle, in der die Indexvektoren und die flachen Daten als `dcc:Quantity`s abgelegt sind. Die XML-Struktur enthält außerdem detaillierte Beschreibungen in Englisch und Deutsch, die erläutern, wie die Reshaping-Umrechnung und die Validierung mittels Primfaktorzerlegung erfolgen.
```xml
<dcc:listrefType="basic_3IndexFlattTable">
<dcc:listrefType="basic_3IndexFlatTable">
<dcc:name>
<dcc:contentlang="en">3D Table with Index Vectors</dcc:content>
<dcc:contentlang="de">3D Tabelle mit Indexvektoren</dcc:content>
...
...
@@ -87,11 +87,11 @@ Die folgende XML-Struktur demonstriert ein Beispiel für eine 3D-Flatt-Tabelle,
und wird verwendet, um die korrekte Neuordnung der Daten zu überprüfen.
@@ -155,7 +155,7 @@ Die folgende XML-Struktur demonstriert ein Beispiel für eine 3D-Flatt-Tabelle,
to test the correct reshaping of the data.
</dcc:content>
<dcc:contentlang="de">
Diese flachgelegte Datenanordnung wird durch Multiplikation der Indexvektoren erzeugt.
Diese flache Datenanordnung wird durch Multiplikation der Indexvektoren erzeugt.
Die Primfaktorzerlegung jedes Wertes entspricht seinem Multi-Index und wird verwendet, um
die korrekte Neuordnung der Daten zu überprüfen.
</dcc:content>
...
...
@@ -167,7 +167,7 @@ Die folgende XML-Struktur demonstriert ein Beispiel für eine 3D-Flatt-Tabelle,
</dcc:name>
<si:realListXMLList>
<si:valueXMLList>
<!-- The additional whitespaces and linefeed are only for visualisation! The Last index dimension is written in consecutive blocks. -->
<!-- The additional whitespaces and linefeed are only for visualization! The last index dimension is written in consecutive blocks. -->
130 170 190 230 290
182 238 266 322 406
286 374 418 506 638
...
...
@@ -190,22 +190,23 @@ Die folgende XML-Struktur demonstriert ein Beispiel für eine 3D-Flatt-Tabelle,
Die Generierung der flachen Tabelle erfolgt durch die folgende Methode:
1.**Generierung der Indexvektoren:**
Für jede Dimension wird eine Folge aufteigend sortierte Liste von disjunkten Primzahlen erzeugt.
Für jede Dimension wird eine Folge aufsteigend sortierte Liste von disjunkten Primzahlen erzeugt.
2.**Reshaping mittels Broadcasting:**
Die einzelnen Primzahlvektoren werden so umgeformt, dass sie über alle Dimensionen hinweg miteinander multipliziert werden können. Das Ergebnis ist eine n-dimensionale Tabelle, deren Werte das Produkt der jeweiligen Indexwerte sind.
3.**Flattening:**
Die n-dimensionale Tabelle wird in eine flache, eindimensionale Liste (C-Style, row-major) umgewandelt.
Der folgende Python-Codeausschnitt zeigt die wesentlichen Schritte:
Der pytest in der Datei [test_flatt_table.py](../../tests/test_flatt_table.py) überprüft die korrekte Umrechnung der n-dimensionalen Indexwerte in die flache Liste.
Dabei werden immer der erste un der letzte Wert in der hochdimensionellen-Tabelle so wie 1000 zufällige Index-Kombinationen überprüft.
Der pytest in der Datei [test_flat_table.py](../../tests/test_flat_table.py) überprüft die korrekte Umrechnung der n-dimensionalen Indexwerte in die flache Liste.
Dabei werden immer der erste und der letzte Wert in der hochdimensionalen Tabelle so wie 1000 zufällige Index-Kombinationen überprüft.
```python
importos# Importiere das OS-Modul zur Arbeit mit Dateisystemen
importnumpyasnp# Importiere NumPy als np zur Arbeit mit Arrays und numerischen Operationen
importuuid# Importiere das UUID-Modul zur Generierung von eindeutigen Identifikatoren
defis_prime(n):# Definiert Funktion is_prime zur Überprüfung, ob eine Zahl n eine Primzahl ist
# this algorithmus is neither fast nor efficient,
# This algorithm is neither fast nor efficient,
# but it is simple and works for our purpose and can be implemented in any programming language
ifn<2:# Falls n kleiner als 2 ist, ist es keine Primzahl
returnFalse# Gib False zurück, da n keine Primzahl ist
...
...
@@ -215,7 +216,7 @@ def is_prime(n): # Definiert Funktion is_prime zur Überprüfung, ob eine Zahl
returnTrue# Wenn keine Teilbarkeit gefunden wurde, ist n eine Primzahl, also gib True zurück
defnext_n_primes(n,start=2):# Definiert Funktion next_n_primes zur Generierung der nächsten n Primzahlen ab einem Startwert
#This function generates the next n primes starting from the given start value
#This function generates the next n primes starting from the given start value
primes=[]# Initialisiere eine leere Liste zur Speicherung der gefundenen Primzahlen
num=start# Setze die Zählvariable num auf den Startwert
whilelen(primes)<n:# Solange die Anzahl der gefundenen Primzahlen kleiner als n ist
<dcc:content lang="en">This index vector contains the prime numbers used for dimension {i} (zero indexd) of the flat table.</dcc:content>
<dcc:content lang="de">Dieser Indexvektor enthält die Primzahlen, die für die Dimension {i} (nullindiziert) der flachen Tabelle verwendet werden.</dcc:content>
<dcc:content lang="en">This index vector contains the prime numbers used for dimension {i} (zero indexed) of the flat table.</dcc:content>
<dcc:content lang="de">Dieser Indexvektor enthält die Primzahlen, die für die Dimension {i} (null-indiziert) der flachen Tabelle verwendet werden.</dcc:content>