Die partielle Sonnenfinsternis vom 20.03.2015

Reparatur eines Linux-Systems mit chroot

Kann man nicht mehr auf normalem Wege auf sein System zugreifen, z.B. weil es Probleme mit dem Bootloader gibt und das System nicht mehr startet, so hilft u.U. ein Rettungssystem vom USB-Stick oder von CDROM weiter. Dabei muss es sich nicht unbedingt um die Recovery-Funktion der installierten Linux-Distribution handeln, auch ein fremdes Reparatursystem wie KNOPPIX kann von Nutzen sein. Allerdings sollte Reparatursystem und installiertes System die gleiche Architektur besitzen, mit einem 32-bit KNOPPIX ein 64-bit Zielsystem zu reparieren wird also in der Regel scheitern.

Hat das Reparatursystem erfolgreich gebootet, so verschafft man sich in einem Terminalfenster erstmal einen Überblick über die Festplattenstruktur:

~> lsblk
NAME        MAJ:MIN RM   SIZE RO TYPE  MOUNTPOINT
sda           8:0    0 465,8G  0 disk  
├─sda1        8:1    0     8G  0 part  [SWAP]
├─sda2        8:2    0    20G  0 part  /
└─sda3        8:3    0 437,8G  0 part  
  └─cr_home 253:0    0 437,8G  0 crypt /home
sr0          11:0    1 352,6M  0 rom

Nun mountet man die Partition die das Wurzelvezeichnis des Zielsystems enthält, in unserem Beispiel also /dev/sda2:

sudo mount /dev/sda2 /mnt

Wechselt man anschließend mit chroot das Wurzelverzeichnis zum Zielsystem, so taucht folgendes Problem auf: Die im Wurzelverzeichnis des Zielsystems liegenden Verzeichnisse wie proc, dev und sys sind tot, denn durch chroot wird ja kein neuer Kernel gestartet, durch dessen Gerätetreiber die Verzeichnisse dev usw. ein vitales Abbild des laufenden Systems liefern. Man muss also die entsprechenden Verzeichnisse des Recovery-Systems in das Zielsystem mounten:

for i in /dev /dev/pts /proc /sys /run;\
do sudo  mount -B $i /mnt$i; done

Erst jetzt wird in das neue Wurzelverzeichnis gewechselt:

sudo chroot /mnt /bin/bash

Jetzt stehen einem die Programme des Zielsystems zur Verfügung (man muss aber immer im Hinterkopf behalten, dass der laufende Kernel nach wie vor, der des Recovery-Systems ist). Man kann also bspw. den Bootloader konfigurieren, ist das Zielsystem OpenSuSE ruft man also yast auf:

yast bootloader

Hat man die Arbeit auf dem Zielsystem beendet, so kann man die chroot-Umgebung durch exit wieder verlassen.

Nachbearbeiten digitaler Quellen von Archive.org

Das Internet Archive Archive.org ist um die Langzeitarchivierung digitaler Daten bemüht und bietet seine Archivalien der Öffentlichkeit frei an. So findet man im Internet Archive die digitalen Kopien vieler gescannter Bücher deren Urheberschutz abgelaufen ist. Darunter sind viele Perlen der deutschen Klassiker, aber auch viele naturwissenschaftliche Klassiker wie bspw. Humboldt etc. Die Qualität der angeboten Scans schwankt dabei erheblich, teilweise fehlen ganze Seiten oder sind unleserlich, Gesamtwerke sind nicht immer vollständig. Eine andere Schwäche besteht darin, dass die bereitgestellten PDF- bzw. DJVU-Dateien oftmals durch starke Komprimierung aus den originalen Scandaten erzeugt wurden, weshalb ihre Anzeigequalität gegenüber den Originaldaten teilweise erheblich zurücksteht, was wiederum ihren Gebrauchswert als Ebook schmälert. Zumindest der letztgenannte Mangel kann behoben werden, sofern die originalen Daten zur Verfügung stehen. Was in diesem Fall zu tun ist, um bessere Resultate bei der Erzeugung von DJVU-Dateien zu erhalten, soll im folgenden erläutert werden:

Als Beispiel dient hier der Scan (unter Archive.org) einiger Postkarten mit Kupferstichen von Albrecht Dürer die der Verlag F.A. Ackermann in München herausbrachte. Der eingebettet Betrachter auf Archive.org zeigt die Stiche noch in einer ansprechenden Qualität an, die Überraschung erlebt man erst, wenn man sich eine Kopie als PDF- oder DJVU-File herunterlädt. Die feinen Details der Stiche sind durch die starke Kompression der angebotenen Dateien nicht mehr sichtbar. Glücklicherweise sind auf Archive.org in der Regel auch die Originaldaten der Scans vorhanden, gebündelt in einem TAR-Archiv tragen sie die Endung ..._orig_jp2.tar. Bei diesen Daten handelt es sich jedoch um die unbeschnittenen Daten, auch sind die Bilder in ihrer Lage noch nicht korrigiert. Die beschnittenen und ordentlich orientierten Bilder liegen oft in einem ZIP-Archiv mit der Endung ..._jp2.zip vor – falls nicht, muss man sich selbst an die Arbeit machen.

In unserem Beispiel mit Dürers Kupferstichen liegt jedoch das entsprechende ZIP-Archiv vor. Die JPEG-2000-Dateien des ZIP-Archivs müssen nun zuerst in ein etwas konventionelleres Format überführt werden, prinzipiell sollte man natürlich ein verlustfreies Format wählen, um keine weiteren Details zu verlieren. Ich benutze hier j2k_to_image aus der openjpeg-Suite. Anschließend sollte man die Bilder noch etwas nachschärfen, dazu benutze ich das Kommandozeilentool ImageMagick. Zum schärfen wird die Methode der unscharfen Maskierung (unsharp mask) eingesetzt, um Farbartefakte zu vermeiden wird das Bild vorher in den HSI-Farbraum zerlegt, von den Komponenten Hue, Saturation und Value (oder Intensität) wird nur die letztere, also das Bild mit der Intensität geschärft. Anschließend führt man die drei Komponenten wieder in ein einziges Bild im sRGB-Farbraum zusammen. Nun können die Bilder einzeln in ein DJVU-File überführt werden. Dabei sollte man auf eine Vorgabe der Qualität durch die Optionen -percent oder -decibel verzichten. Natürlich sind die DJVU-Dateien in der Regel deutlich größer als die auf Archive.org liegenden, sie haben aber auch eine deutlich höhere Qualität und letztlich zählt ja vor allem diese (Speicher wird ohnehin immer billiger).

Im folgenden Bild (Ausschnitt aus Dürers St. Christophorus) wurde zum Vergleich einmal ein Bildausschnitt aus dem ursprünglich heruntergeladenen PDF-File (links), dem nachgeschärften Bild aus dem ZIP-Archiv (rechts) gegenübergestellt. Die fein aufgelösten Strukturen des Stichs im rechten Bild rechtfertigen den Aufwand:

Vergleich

Das folgende Shell-Skript erledigt nun die vorher besprochenen Schritte:

# Konvertiere JPEG2000 nach PPM (kompl. Verzeichnis):
j2k_to_image -ImgDir . -OutFor ppm
# 
for i in `ls -1 *.ppm`;
do
# Separiere jedes Bild in H-, S- und I-Bestandteile 
convert $i -colorspace HSI -separate separate_HSI_%d.ppm
# Schärfe die I-Komponente
mogrify -unsharp 1.2x1.2+5+0 separate_HSI_2.ppm
# Führe die HSI-Bestandteile wieder in einem sRGB-File zusammen
convert separate_HSI_?.ppm  -set colorspace HSI -combine -colorspace sRGB $i
# Räume auf
rm separate_HSI_?.ppm
# Erzeuge ein DJVU-File
c44 $i $i.djvu
done
# Erzeuge einen DJVU-Container für alle Seiten
djvm -c dürer.djvu *.ppm.djvu

IPython-Notebooks in einem WordPress-Blog veröffentlichen

Wie in einem vorangegangen Artikel erwähnt, bieten IPython-Notebooks hervorragende Möglichkeiten Arbeiten zu publizieren. Einfügungen können als $\LaTeX$-Code oder durch MathJax vorgenommen werden, Bild- und Videomaterial kann ebenso wie Audiosequenzen in die Notebooks aufgenommen werden. Ein Thema lässt sich so auf sehr ansprechende, multimediale Weise darstellen.
Um eine Notebook-Datei für eine Veröffentlichung in ein gängiges Format zu konvertieren, ruft man auf der Kommandozeile folgendes auf:

> ipython nbconvert --to html input.ipynb

Man erhält ein statisches HTML-Dokument aus dem Notebook input.ipynb, durch Angabe von pdf, latex etc. können selbstverständlich auch andere Formate erzeugt werden.
Ein auf diese Weise erstelltes HTML-Dokument lässt sich nun ohne großen Aufwand in einem WordPress-Blog einfügen. Dazu wird lediglich ein Plugin benötigt, welches HTML-Code direkt im Editor einfügen kann. Hier wird die Vorgehensweise anhand des Plugins EmbedIt Pro beschrieben:

EmbedIt Pro:
Embed any HTML code (Youtube, UStream or whatever HTML) in a post, page or widget, deciding precisely where to embed it, either on-the-fly from custom fields OR from your saved HTML Code Snippets. Super easy for newbies but powerful for developers, since it supports not only shortcodes but PHP functions too to return or display the snippets in your templates.

Nach der Installation des Plugins findet man im Dashboard den Punkt HTML Snippets. Wählt man dort Add New kann man nun den HTML-Code auf der vorgesehenen Fläche einfügen (zum bsp. durch vorherige Selektion mit der Maus). Bestätigt man den Code durch klicken auf Veröffentlichen, erhält man einen Shortcode, der direkt im zu erstellenden Artikel eingefügt werden kann.

Ohne weitere Nachbearbeitung kann man mit dem beschriebenen Workflow seine IPython-Notebooks in einem WordPress-Blog veröffentlichen, dies spart Zeit und erhöht die gestalterische Qualität der Publikation.

IP-Adresse eines Android-Geräts ermitteln

Mit Android-Bordmitteln kann man lediglich die IP-Adresse der Wlan-Schnittstelle feststellen (unter Einstellungen->Wlan->Erweitert). Benötigt man die IP-Adresse einer anderen Netzwerkschnittstelle bietet sich folgender Weg an: Herstellung eines Zugang zum Phone über ssh (bspw. mit der App ConnectBot), anschließend kann auf der Kommandozeile mit dem ip-Befehl die IP-Adressen vorhandener Schnittstellen abgefragt werden:

> ip addr show

Bzw. wenn nur ip4-Adressen interessieren und man evtl. noch mit grep die gewünschten Schnittstelle aussortieren will:

> ip -o -4 addr show

Es werden keine root-Rechte benötigt!

PDFs komprimieren

Vor dem Versenden einer großen PDF-Datei als Email-Anhang, sollte man versuchen sie mit Hilfe eines Postscript-Interpreters zu verkleinern. Dies schont nicht nur upload-Volumen, es verringert auch die Gefahr, dass die Email wegen evtl. Restriktion von Mailservern nicht zugestellt wird. Das auf praktisch allen Systemen verfügbare Programm Ghostscript meistert diese Aufgabe zuverlässig.
Über die Option -dPDFSETTINGS kann man dabei die Darstellungsqualität und damit die Größe der erzeugten Dateien bestimmen:

  • /screen wählt die schlechteste Auflösung,
  • /ebook wählt eine mittlere Auflösung,
  • /printer wählt eine hohe Auflösung,
  • /prepress wählt eine sehr hohe Auflösung aus.

Mit den beiden zuletzt genannten Auflösungsstufen wird man in der Regel keine erheblich Kompression gegenüber der Ausgangsdatei erreichen, mit den erstgenannten Angaben jedoch schon – teils signifikant, jedoch um den Preis stark verlustbehafteter Kompression von enthaltenen Bildern. Man muss gegebenenfalls etwas herumspielen, um bei noch akzeptabler Qualität die gewünschte Verringerung der Dateigröße zu erzielen. Mit folgender Kommandozeile

> gs -sDEVICE=pdfwrite -dCompatibilityLevel=1.5 -dPDFSETTINGS=/printer -dNOPAUSE -dQUIET -dBATCH -sOutputFile=output.pdf input.pdf

wird Ghostscript mit vernünftigen Optionen gestartet. Weitere Optionen und Erläuterungen findet man auf der Website von Ghostscript.

Overlays für PDF-Formulare erstellen

Das PDF-Format bietet komfortable Funktionen für die Erstellung interaktiver Formulare an. Leider nutzen nicht alle Autoren diese Möglichkeit und so bekommt man hin und wieder PDF-Dokumente, denen zwar individuelle Angaben hinzugefügt werden sollen, die andererseits aber keine interaktive Eingabemöglichkeit anbieten. In solchen Fällen hilft nur ausdrucken und handschriftliches hinzufügen der Angaben. Diese Vorgehensweise entstammt dem IT-Mittelalter und vergeudet Papier, welches durch einen guten PDF-Workflow eigentlich hervorragend eingespart werden kann. Hier soll ein Lösungsweg auf Basis des Schweizer Messers unter den PDF-Werkzeugen pdftk und LibreOffice (die Vorgehensweise ist für OpenOffice äquivalent).
Ich treffe hier die Festlegung, dass das Ausgangsdokument unter dem Namen input.pdf vorliegt. Da LibreOffice PDF nicht direkt als Format für Hintergrundbilder unterstützt, muss man erst ein Encapsulated Postscript (EPS) Dokument erzeugen:

> pdf2ps input.pdf
> ps2eps input.ps

In LibreOffice öffnet man nun das Menü Format->Seite… und wählt im Reiter Hintergrund als Quelle Grafik. Jetzt kann man das EPS-Dokument (input.eps) als Hintergrundbild auswählen und muss noch bei Art den Punkt Position anklicken. Als Bezugspunkt den Zentrumspunkt wählen und Anwenden klicken.
Nun auf den Reiter Seite gehen und die Seitenränder so verändern, dass das gewählte Hintergrundbild exakt die gleiche Größe und Lage wie im Original hat. Man wählt bspw. Links 0cm, Rechts 0cm, Oben 1.4cm und Unten 0cm.
Um nun Text über die gewünschten Bereiche des Hintergrundbildes zu legen, öffnet man das Menü Einfügen->Rahmen und wählt dort den Reiter Typ. Als Verankerung den Punkt An der Seite einstellen, auf den Reiter Umrandung wechseln und dort bei Stil -kein- klicken. Nach dem Klick auf ok erscheint das Rahmenelement und kann positioniert und dann mit Text gefüllt werden. Sind mehrere Einfügungen an unterschiedlichen Stellen zu machen, legt man auf die beschriebene Weise weitere Rahmen an. Ebenso kann man ein Bild mit einer gescannten Unterschrift oder eines Stempels einfügen. Dabei ist natürlich darauf zu achten, dass das Bild einen transparenten Hintergrund hat (in Gimp bspw. eine Farbe in Transparenz umwandeln).
Zum Schluss setzt man den Hintergrund wieder auf Farbe und Keine Füllung und exportiert das Dokument als PDF (ich wähle hier overlay.pdf als Dateinamen).
An dieser Stelle tritt das Tool pdftk in Aktion:

> pdftk input.pdf background overlay.pdf output output.pdf

Das zusammengesetzte Dokument steht nun unter dem Dateinamen output.pdf bereit. Sollte es Probleme mit der Sichtbarkeit einzelner Boxen geben, so kann statt der Option background auch die Option stamp verwendet werden. In diesem Fall sollte man den Hintergrund der Boxen transparent gestalten.

Links: Ursprüngl. PDF, Mitte: Overlay PDF, Rechts: Zusammengesetztes PDF

Sollte das ursprüngliche Dokument mehrseitig sein, muss das PDF erst in einzelne Seiten zerlegt werden (das folgende Kommando erzeugt Dateinamen im Format pg_%04d.pdf):

> pdftk input.pdf burst

Nach der Bearbeitung der entsprechenden Seiten können sie wieder zusammengefügt werden:

> pdftk pg_0001.pdf pg_0002.pdf pg_0003.pdf cat output output.pdf

Erstellen von Wachstumskurven mit Gnuplot

Hinweise auf den Gesundheits- und Ernährungszustand von Kindern- und Jugendlichen können sich durch die Messung anthropometrischer Merkmale und deren Einordnung in Perzentilkurven, die die Verteilung der Körpermaße in einer Referenzpopulation wiederspiegeln, ergeben. Eine aktuelle Studie zur Gesundheit von Kindern und Jugendlichen[ 1] liefert solche Perzentilkurven ausgewählter Körpermaße von Kindern und Jugendlichen im Alter von 3 Monaten bis 17 Jahren.
Als individuelle Datenquelle können die Ergebnisse der kinderärztlichen Untersuchungen, die im Mutterpass dokumentiert sind, herangezogen werden. Es gibt insgesamt 9 Vorsorgeuntersuchungen, angefangen von der U1 direkt am Tag der Geburt, bis hin zur U9 im 5 Lebensjahr, bzw. bis zu 4 Monaten später. Bei allen Vorsorgeuntersuchungen wird in der Regel auch das Gewicht und die Körpergröße erfasst. Darüber hinaus sollte man diese Körpermaße in regelmäßigen Abständen auch selbst erfassen. Oft erinnern die Kinder selbst an die Messungen, da sie ab einem gewissen Lebensalter an ihrem eigenen Wachstum Interesse zeigen. Für die Darstellung der gemessenen Daten soll die skriptgesteuerte Plottersoftware Gnuplot, die unter freier Lizenz für alle gängigen Betriebssysteme verfügbar ist, verwendet werden. Die Aufbereitung der Daten für Gnuplot ist denkbar einfach: In einer Textdatei werden spaltenweise Messzeitpunkt, Körpergröße in cm und Körpergewicht in Gramm, jeweils durch Leerzeichen oder Tabulator getrennt erfasst. In Zeile 4 des folgenden kleinen Gnuplot-Skripts wird dem Programm mitgeteilt, dass es sich bei den Daten für die x-Achse um Datumsangaben handelt, die folgende Zeile beschreibt das Format, in dem das Datum vorliegt. Das Höchstalter des zu untersuchenden Kindes muß gegebenfalls in Zeile 15 als oberer Grenzwert des Darstellungsbereichs angepasst werden. Dabei zählt nur die Dekade des Jahrtausends als Kindesalter (Gnuplot repräsentiert Zeitangaben intern als Sekunden seit dem 01.01.2000). Mein Skript geht von den Daten zweier Kinder aus, die in den Dateien "bruno.dat" und "felix.dat" gespeichert sind. In diesen Dateien ist der Zeitpunkt der Messung natürlich durch das reale Datum vermerkt. Da die Daten aber über das Alter des Kindes abgetragen werden sollen, muss in Zeile 45 und 46 das Datum der Messung entsprechend verschoben werden, so dass die Geburt mit dem Datum 01.01.2000 zusammenfällt.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
#!/usr/bin/gnuplot 
#
set encoding utf8
set xdata time
set timefmt "%d.%m.%Y"
set xtics rotate by -45
set format x "%b/%y"
 
set termoption dash
set size ratio 0.7 1.0, 1.0; set origin 0.0, 0.0
set ylabel "Körpergröße [cm]"
set xlabel "Alter [Jahre]" offset screen 0,-0.02
#####################################
# Als Endpunkt das Höchstalter eintragen:
set xrange ['01.01.2000':'01.01.2009']
set ytics mirror
unset y2label
unset y2range
unset y2tics
set format x "%y"
set mxtics 12
set key left
set key screen 0.1,0.9
 
set style line 1 lt 1 lc rgb "red" lw 3
set style line 2 lt 1 lc rgb "grey" lw 1
set style line 3 lt 1 lc rgb "black" lw 1
set style line 4 lt 1 lc rgb "green" lw 1
 
#####################################################
# Darstellung der Körperlänge über dem Kindesalter
#
# Sekunden/Tag = 86400
# Differenz der Geburtsdatumsangaben in Tagen = 962
# Differenz zwischen Brunos Geburtstag und 1.1.2000 in Tagen = 1660
# Verschiebe die Zeitangaben, so dass sie am 1.1.2000 starten.
 
plot "KiGGS-Referenzperzentile-Länge.dat" using 1:5 title "Perzentile P50 (KiGGS 2003-06)" ls 1 smooth csplines, \
     "" using 1:6 title "Perzentile P75" ls 2 smooth csplines, \
     "" using 1:4 t "Perzentile P25" ls 2 smooth csplines, \
     "" using 1:7 title "Perzentile P90" ls 3 smooth csplines, \
     "" using 1:3 t "Perzentile P10" ls 3 smooth csplines, \
     "" using 1:8 title "Perzentile P97" ls 4 smooth csplines, \
     "" using 1:2 t "Perzentile P3" ls 4 smooth csplines, \
     "bruno.dat" using (timecolumn(1)-1660*86400):2 title "Bruno Körpergröße" with linespoints  4, \
     "felix.dat" using (timecolumn(1)-(963+1660)*86400):2 title "Felix Körpergröße" with linespoints 5
 
set term svg fsize 8
set output "kurven-l.svg"
replot
 
pause -1

45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
set ylabel "BMI [kg/m²]"
 
plot "KiGGS-Referenzperzentile-BMI.dat" using 1:5 title "Perzentile P50 (KiGGS 2003-06)" ls 1 smooth csplines, \
     "" using 1:6 title "Perzentile P75" ls 2 smooth csplines, \
     "" using 1:4 t "Perzentile P25" ls 2 smooth csplines, \
     "" using 1:7 title "Perzentile P90" ls 3 smooth csplines, \
     "" using 1:3 t "Perzentile P10" ls 3 smooth csplines, \
     "" using 1:8 title "Perzentile P97" ls 4 smooth csplines, \
     "" using 1:2 t "Perzentile P3" ls 4 smooth csplines, \
     "bruno.dat" using (timecolumn(1)-1660*86400):($3/1000.0)/($2/100.0)**2 title "Bruno BMI" with linespoints  4, \
     "felix.dat" using (timecolumn(1)-(963+1660)*86400):($3/1000.0)/($2/100.0)**2 title "Felix BMI" with linespoints 5
 
set term svg fsize 8
set output "kurven-bmi.svg"
replot
 
pause -1

54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
set ylabel "Gewicht [kg]"
 
plot "KiGGS-Referenzperzentile-Gewicht.dat" using 1:5 title "Perzentile P50 (KiGGS 2003-06)" ls 1 smooth csplines, \
     "" using 1:6 title "Perzentile P75" ls 2 smooth csplines, \
     "" using 1:4 t "Perzentile P25" ls 2 smooth csplines, \
     "" using 1:7 title "Perzentile P90" ls 3 smooth csplines, \
     "" using 1:3 t "Perzentile P10" ls 3 smooth csplines, \
     "" using 1:8 title "Perzentile P97" ls 4 smooth csplines, \
     "" using 1:2 t "Perzentile P3" ls 4 smooth csplines, \
     "bruno.dat" using (timecolumn(1)-1660*86400):($3/1000.0) title "Bruno Gewicht" with linespoints  4, \
     "felix.dat" using (timecolumn(1)-(963+1660)*86400):($3/1000.0) title "Felix Gewicht" with linespoints 5
 
set term svg fsize 8
set output "kurven.svg"
replot
 
pause -1

Die Dateien KiGGS-Referenzperzentile-Länge.dat, KiGGS-Referenzperzentile-Gewicht.dat und KiGGS-Referenzperzentile-BMI.dat mit der Angabe der Referenzperzentilen zu Größe, Gewicht und BMI, auf Grundlage der oben erwähnten Studie, stehen zum Download bereit.