• SPARQL 4: Be Extra Careful on your Birthday

    A Yak staring at the photographer

    Enough Yak Shaving already.

    I am now three parts into my yak-shaving investigation of Wikidata and SPARQL (one, two, three) with the goal of figuring out whether birthdays are more or less dangerous – measured by whether or not people survive them – than ordinary days.

    At the end of the last instalment I was stumped by timeouts on Wikidata, and so much of this post is about massaging my query so that I get some answers in the CPU minute that one gets on Wikidata's triplestore. While plain optimisation certainly is necessary, working on six million people within a minute is probably highly ambitious whatever I do[1]. I will hence have to work on a subset. Given what I have worked out in part 3,

    # This will time out and just waste CPU.
    SELECT (count(?person) AS ?n)
    WHERE {
      ?person rdfs:label ?personName.
      ?person wdt:P569 ?bdate.
      hint:Prior hint:rangeSafe true.
      ?person wdt:P570 ?ddate.
      hint:Prior hint:rangeSafe true.
    
      FILTER (MONTH(?bdate)>1 || DAY(?bdate)>1)
      FILTER (MONTH(?bdate) = MONTH(?ddate)
        && DAY(?bdate) = DAY(?ddate)
        && YEAR(?bdate) != YEAR(?ddate))
      FILTER (YEAR(?bdate)>1850)
    
      FILTER (lang(?personName)="en")
    }
    

    – how do I do a subset? Proper sampling takes almost as much time as working with the whole thing. But for now, I'd be content with just evaluating my query on whatever subset Wikidata likes to work on. Drawing such a (statiscally badly sampled) subset is what the LIMIT clause you have already seen in part one does. But where do I put it, since, if things work out, my query would only return a single row anyway?

    Subqueries in SPARQL, and 50 Labels per Entity

    The answer, as in SQL, is: A subquery. In SPARQL, you can have subqueries like this:

    SELECT (count(?person) as ?n)
    WHERE {
      { SELECT ?person ?personName ?bdate ?ddate
        WHERE {
          ?person rdfs:label ?personName;
            wdt:P569 ?bdate;
            wdt:P570 ?ddate.
        }
        LIMIT 50
      }
      FILTER (lang(?personName)="en")
    }
    

    – so, within a pair of curly braces, you write another SELECT clause, and its is then the input for another WHERE, FILTER, or other SPARQL construct. In this case, by the way, I'm getting 50 records with all kinds of labels in the subquery and then filter out everything that's not English. Amazingly, only one record out of these 50 remains: there are clearly at least 50 statements on labels for the first entity Wikidata has picked here.

    Raising the innner limit to 500, I get 10 records. For the particular sample that Wikidata chose for me, a person indeed has 50 labels on average. Wow. Raising the limit to 5000, which probably lowers the the pharaohs to non-pharaohs in the sample, gives 130 records, which translates into 38 labels per person.

    Clearly, adding the labels is an expensive operation, and since I do not need them for counting, I will drop them henceforth. Also, I am doing my filtering for off-January 1st birthdays in the subquery. In this way, I probably have a good chance that everything coming out of the subquery actually counts in the outer filter, which means I can compute the rate of people dying on their birthday by dividing my count by the limit.

    Let's see where this gets us:

    SELECT (count(?person) AS ?n)
    WHERE {
      { SELECT ?person ?bdate ?ddate
        WHERE {
          ?person wdt:P569 ?bdate.
          hint:Prior hint:rangeSafe true.
          ?person wdt:P570 ?ddate.
           FILTER (MONTH(?bdate)>1 || DAY(?bdate)>1)
          FILTER (YEAR(?bdate)>1850)
          hint:Prior hint:rangeSafe true.
        }
        LIMIT 500
      }
    
      FILTER (MONTH(?bdate) = MONTH(?ddate)
        && DAY(?bdate) = DAY(?ddate)
        && YEAR(?bdate) != YEAR(?ddate))
      hint:Prior hint:rangeSafe true.
    }
    

    Named Subqueries and Planner Barriers

    That's returning a two for me, which is not implausible, but for just 500 records it ran for about 20 seconds, which does not feel right. Neither pulling the 500 records nor filtering them should take that long.

    When a database engine takes a lot longer than one thinks it should, what one should do is take look at the query plan, in which the database engine states in which sequence it will compute the result, which indexes it intends to use, etc.

    Working out a good query plan is hard, because in general you need to know the various partial results to find one; in my example, for instance, the system could first filter out everyone born after 1850 and then find the death dates for them, or it could first match the death dates to the birthdays (discarding everything that does not have a death day in the process) and then filter for 1850. Ff there were may people with birthdays but no death days (for instance, because your database talks mostly about living people), the second approach might be a lot faster. But you, that is, the database engine, have to have good statistics to figure that out.

    Since that is such a hard problem, it is not uncommon that the query planner gets confused and re-orders operations such that things are a lot slower than they would be if it hadn't done the ordering, and that's when one should use some sort of explain feature (cf. Wikidata's optimisation hints). On Wikidata, you can add an explain=detail parameter to the query and then somehow display the bunch of HTML you get back.

    I did that and, as I usually do when I try this kind of thing, found that query plans are notoriously hard to understand, in particular when one is unfamiliar with the database engine. But in the process of figuring out the explain thing, I had discovered that SPARQL has the equivalent of SQL's common table expressions (CTEs), which gave me an excuse to tinker rather than think about plans. Who could resist that?

    In SPARQL, CTEs are called named subqueries and used like this:

    SELECT (count(?person) AS ?n)
    WITH { SELECT ?person ?bdate ?ddate
        WHERE {
          ?person wdt:P569 ?bdate;
          hint:Prior hint:rangeSafe true.
          ?person wdt:P570 ?ddate.
          hint:Prior hint:rangeSafe true.
           FILTER (MONTH(?bdate)>1 || DAY(?bdate)>1)
          FILTER (YEAR(?bdate)>1850)
        }
        LIMIT 30000
      } AS %selection
    WHERE {
      INCLUDE %selection
    
      FILTER (MONTH(?bdate) = MONTH(?ddate)
        && DAY(?bdate) = DAY(?ddate)
        && YEAR(?bdate) != YEAR(?ddate))
      hint:Prior hint:rangeSafe true.
    

    – you write your subquery in a WITH-block and give it a name that you then INCLUDE in your WHERE clause. In several SQL database systems, such a construct provides a planner barrier, that is, the planner will not rearrange expressions across a WITH.

    So does, according to the optimisation hints, Wikidata's current SPARQL engine. But disappointingly, things don't speed up. Hmpf. Even so, I consider named subexpresisons more readable than nested ones[2], so for this post, I will stay with them. In case you come up with a brilliant all-Wikidata query, you probably want to go back to inline subqueries, though, because then you probably do not want to constrain the planner too much.

    Finally: Numbers. But what do they Mean?

    With my barrier-protected subqueries, I have definitely given up on working with all 6 million persons with birthdays within Wikidata. Interestingly, I could go from a limit of 500 to one of 30'000 and stay within the time limit. I never went back to try and figure out what causes this odd scaling law, though I'd probably learn a lot if I did. I'd almost certainly learn even more if I tried to understand why with a limit of 50'000, the queries tended to time out. But then 30'000 persons are plenty for my purpose provided they are drawn reasonably randomly, and hence I skipped all the tempting opportunities to learn.

    And, ta-da: With the above query, I get 139 matches (i.e., people who died on their birthdays).

    What does that say on the danger of birthdays? Well, let's see: If birthdays were just like other days, one would expect 30'000/365 deaths on birthdays in this sample, which works out to a bit more than 80. Is the 140 I am finding different from that 80 taking into account statistical noise? A good rule of thumb (that in the end is related to the grand central limit theorem) is that when you count n samples, your random error is something like (n) if everything is benevolent. For 140, that square root is about 12, which we physicist-hackers like to write as σ = 12, and then we quickly divide the offset (i.e., 140 − 80 = 60) by that σ and triumphantly proclaim that “we've got a 5-σ effect”, at which point everyone is convinced that birthdays are life-threatening.

    This is related to the normal distribution (“Gauss curve”) that has about 2/3s of its area within “one σ” (which is its width as half maximum and would be the standard deviation of something you draw from such a distribution), 95% of …

  • SPAQRL 3: Who Died on their Birthdays?

    Many Yaks grazing on a mountain meadow

    A lot of Yak Shaving left to do here.

    Now that I have learned how to figure out dates of birth and death in Wikidata and have made myself sensible tools to submit queries, I can finally start to figure out how I can let Wikidata pick out people dying on the same day of the year they were born on, just like Mary Lea Heger.

    I first fetched people with their birthdays and dates of death:

    SELECT ?person ?bday ?dday
    WHERE {
      ?person wdt:P569 ?bday.
      ?person wdt:P570 ?dday.
    }
    LIMIT 2
    

    Consider that query for a while and appreciate that by giving two triple patterns using the same variable, ?person, I am performing what in SQL databases would be a join. That that's such a natural thing in SPARQL is, I'd say, a clear strong point for the language.

    Here is what I got back when I ran this this through my wpd shell function from part two:

    person=http://www.wikidata.org/entity/Q18722
    dday=-1871-06-29T00:00:00Z
    bday=-2000-01-01T00:00:00Z
    
    person=http://www.wikidata.org/entity/Q18734
    dday=-1884-01-01T00:00:00Z
    bday=-2000-01-01T00:00:00Z
    

    This seems to work, except the dates look a bit odd. Did these people really die more than a hundred years before they were born? Ah, wait: these are negative dates. Opening the person URIs as per part one in a browser, I one learns that Q18722 is pharaoh Senusret II, and at least his birthday clearly is… not very certain. If these kinds of estimates are common, I probably should exclude January 1st from my considerations.

    Getting Labels

    But the first thing I wanted at that point was to not have to click on the URIs to see names. I knew enough about RDF to simply try and get labels according to RDF schema:

    SELECT ?personName ?bday ?dday
    WHERE {
      ?person rdfs:label ?personName.
      ?person wdt:P569 ?bday.
      ?person wdt:P570 ?dday.
    }
    LIMIT 10
    

    That's another SQL join, by the way. Nice. Except what comes back is this:

    dday=-2596-01-01T00:00:00Z
    bday=-2710-01-01T00:00:00Z
    personName=Хуан-ди
    
    dday=-2596-01-01T00:00:00Z
    bday=-2710-01-01T00:00:00Z
    personName=Huang Di
    
    dday=-2596-01-01T00:00:00Z
    bday=-2710-01-01T00:00:00Z
    personName=ኋንግ ዲ
    
    dday=-2596-01-01T00:00:00Z
    bday=-2710-01-01T00:00:00Z
    personName=هوان جي دي
    
    dday=-2596-01-01T00:00:00Z
    bday=-2710-01-01T00:00:00Z
    personName=Emperador mariellu
    

    If you select the URI in ?person in addition to just the name, you'll see that we now got many records per person. Actually, one per label, as is to be expected in a proper join, and since there are so many languages and scripts out there, many persons in Wikidata have many labels.

    At this point I consulted Bob DuCharme's Learning SPARQL and figured a filter on the language of the label is what I wanted. This does not call for a further join (i.e., triple pattern), as the language is something like a property of the object literal (i.e., the string) itself. To retrieve it, there is a function determining the language, used with a FILTER clause like this:

    SELECT ?personName ?bday ?dday
    WHERE {
      ?person rdfs:label ?personName.
      ?person wdt:P569 ?bday.
      ?person wdt:P570 ?dday.
    
      FILTER (lang(?personName)="en")
    }
    LIMIT 10
    

    FILTER is a generic SPARQL thing that is more like a SQL WHERE clause than SPARQL's WHERE clause itself. We will be using it a lot more below.

    There is a nice alternative to this kind of joining and filtering I would have found in the wikidata user manual had I read it in time. You see, SPARQL also defines a service interface, and that then allows queriers to mix and match SPARQL-speaking services within a query. Wikidata has many uses for that, and one is a service that can automatically add labels with minimal effort. You just declare that you want that service to filter your query, and then you write ?varLabel to get labels instead of URIs for ?var, as in:

    # don't run this.  It'll put load on Wikidata and then time out
    SELECT ?personLabel ?bday ?dday
    WHERE {
      ?person wdt:P569 ?bday.
      ?person wdt:P570 ?dday.
    
      SERVICE wikibase:label {
        bd:serviceParam wikibase:language "en" .
      }
    }
    LIMIT 10
    

    The trouble with that: This would first pull out all result triples (a couple of million) out of wikidata and then hand over these triples to the wikibase:label service, which would then add the labels and hand back all the labelled records. Only then will the engine discard the all result rows but the first 10. That obviously is terribly inefficient, and Wikidata will kill this query after a minute.

    So: Be careful with SERVICE when intermediate result sets could be large. I later had to use subqueries anyway; I could have used them here, too, to work around the millions-of-triples problem, but at that point I hadn't progressed to these subqueries, let alone means to defeat the planner (that's part four material).

    Determining Day and Month

    Turtle (about my preference for which you could already read in part two) has a nifty abbreviation where you can put a semicolon after a triple and then leave out the subject in the next triple. SPARQL will put the previous subject into this next triple. That works in SPARQL, too, so I can write my query above with fewer keystrokes:

    SELECT ?personName ?bday ?dday
    WHERE {
      ?person rdfs:label ?personName;
        wdt:P569 ?bday;
        wdt:P570 ?dday.
    
      FILTER (lang(?personName)="en")
    }
    LIMIT 10
    

    Now I need to figure out the birthday, as in: date within a year. In Bob DuCharme's book I found a SUBSTR function, and BIND clauses that let you compute values and bind them to variables. Treating the dates as ISO strings (“YYYY-MM-DD“) should let me pull out month and date starting at index 6 (gna: SPARQL starts with index 1 rather than with 0 as all deities in known history wanted), and then five characters, no? Let's see:

    SELECT ?personName ?bdate ?ddate
     WHERE {
       ?person rdfs:label ?personName;
         wdt:P569 ?bday;
         wdt:P570 ?dday.
    
       BIND (SUBSTR(?bday, 6, 5) as ?bdate)
       BIND (SUBSTR(?dday, 6, 5) as ?ddate)
    
       FILTER (lang(?personName)="en")
     }
     LIMIT 3
    

    This gives:

    personName=Sobekhotep I
    bdate=-01-0
    ddate=-01-0
    
    personName=Amenemhat I
    ddate=-02-1
    
    personName=Senusret II
    bdate=-01-0
    ddate=-06-2
    

    Well, that is a failure. And that's because my assumptions on string indices are wrong in general, that is: for people born before the Christian era, and then again for people born after 9999-12-31. Which makes we wonder: Does Wikidata have people born in the future? Well, see below.

    I'll cheat a bit and spare you a few of the dead alleys I actually followed trying to fix this, because they are not very educational. Also, when I strugged with the timeouts I will discuss in a moment I learned about the right way to do this on Wikidata's optimisation page: When something is a date, you can apply the functions DAY, MONTH, and YEAR on it, and that will plausibly even use indexes and thus be a lot faster.

    Thinking about YEAR and having seen the fantasy dates for the ancient Egyptian pharaohs, I also decided to exclude everyone before 1850; that ought to suffice for letting me forget about Gregorian vs. Julian dates, and the likelihood that the dates are more or less right ought to be a lot higher in those days than in the 14th century, say.

    With that, I can write the “birth day equals death day“ in a filter without further qualms. The resulting query is starting to look imposing:

    SELECT ?person ?personName ?bdate ?ddate
    WHERE {
      ?person rdfs:label ?personName.
      ?person rdfs:label  wdt:P569 ?bdate.
      hint:Prior hint:rangeSafe true.
      ?person rdfs:label wdt:P570 ?ddate.
      hint:Prior hint:rangeSafe true.
    
      FILTER (MONTH(?bdate) = MONTH(?ddate)
        && DAY(?bdate) = DAY(?ddate))
      FILTER (YEAR(?bdate)>1850)
    
      FILTER (lang(?personName)="en")
    }
    LIMIT 10
    

    The odd triples with hint:Prior are hints for Wikidata's triple store that, or so I understand Wikidata's documentation, encourages it to use indexes on the properties mentioned in the previous lines; the query certainly works without those, and I frankly have not bothered to see if they actually do anything at all for the present queries. There. Accuse me of practising Cargo Cult if you want.

    Anyway, the result is looking as awful as I had expected given my first impressions with January 1st, and clearly, ensuring birthdays after 1850 is not enough to filter out junk:

    person=http://www.wikidata.org/entity/Q112689783
    ddate=0080-01-01T00:00:00Z
    bdate=1920-01-01T00:00:00Z
    personName=Enrico Mezzasalma
    
    person=http://www.wikidata.org/entity/Q19976926
    ddate=1342-01-01T00:00:00Z
    bdate=2000-01-01T00:00:00Z
    personName=Peter Jonsson
    
    person=http://www.wikidata.org/entity/Q19291026
    ddate=1400-01-01T00:00:00Z
    bdate=2000-01-01T00:00:00Z
    personName=Galceran Marquet
    ...
    

    It seems Wikidata even uses 2000-01-01 as some sort of NULL value. Dang. Let's filter out January 1st, then:

    SELECT ?person ?personName ?bdate ?ddate
    WHERE {
      ?person rdfs:label …
  • Falsche Dichotomien

    Über den Köpfen von Demonstrierenden: Schneegestöber

    So sieht Engagement für Freiheit und Emanzipation aus: Im Schneegestöber demonstrierten die Menschen im Februar 2018 gegen die Militärs und Kriegsherren, die sich in der Münchner Edelunterkunft Bayrischer Hof zu ihrer „Sicherheitskonferenz“ getroffen haben.

    Seit dem Überfall auf die Ukraine grassiert das Aufziehen falscher Dichotomien (weniger elegant gesagt: sich angeblich ausschließender Alternativen) auch bei Menschen, die das vermutlich nicht im Rhetorikkurs gelernt haben und oft sogar guten Willens sind. Wer in den letzten Monaten normale Zeitungen oder Twitter gelesen hat, wird zumindest die folgenden Figuren gesehen haben (es gibt eine ganze Ecke mehr):

    • Entweder wir liefern Waffen oder wir unterstützen Angriffskriege (Quatsch: einfach mal selbst keine Angriffskriege und Drohnenballereien mehr machen und dann auf eine effektive Ächtung solcher Aktionen hinarbeiten wäre viel effektiver)
    • Entweder du bist für „uns“ oder du bist für Putin (Quatsch: Ich habe schon des Öfteren gegen Putin-Besuche demonstriert und bin dafür auch einmal im Auftrag von Olaf Scholz verprügelt worden; mensch kann prima gegen alle Sorten blutiger Hähne[1] sein)
    • Entweder lassen wir auf Russen schießen oder die Leute in der Ukraine werden alle getötet (Quatsch: Das russlandgefällige Janukowitsch-Regime war jetzt nicht klasse, aber ausweislich diverser Wahlen oder Leaks nicht qualitativ verschieden von den uns gefälligen Regimes von, sagen wir, Kutschma und Tymoschenko oder auch Poroschenko; es ist nach aller realistischen historischen Erfahrung völlig sicher, dass im Krieg viel mehr Menschen sterben und leiden werden als bei einem schnellen Regime Change, zumal wenn die regimechangenden Truppen dann nicht so ewig bleiben wie die unseren in Afghanistan und im Irak und/oder die Bevölkerung schnell aus dem Kriegsmodus herauskommt)
    • Entweder willst du Volk und Nation der Ukraine retten oder du willst die Leute in der Ukraine in Knechtschaft sehen (Quatsch: spätestens seit Brecht haben nette Menschen aufgehört, von „Volk“ zu reden, denn „Bevölkerung“ verhindert Fehlschlüsse, und spätestens seit dem 20. Jahrhundert sollte eigentlich Konsens bestehen, dass das mit den „Nationen“ eine eher bescheidene Idee war; mit der Verteidigung bzw. Erringung von Menschen- und Bürgerrechten haben Volk und Nation jedenfalls längst nichts mehr zu tun)
    • Entweder du schießt oder du tust gar nichts (Quatsch: Im Gegenteil ist eine geschichtliche Konstante, dass sozialer Fortschritt, der aus den Gewehrläufen kommt, nicht viel taugt und jedenfalls nicht lange anhält)

    Es lohnt sich grundsätzlich, aber ganz besonders bei all den kriegseuphorischen Äußerungen, auf solche falschen Dichotomien zu achten. Wie gesagt: Nicht alle, die sowas verwenden, sind im Bereich finsterer Rhetorik unterwegs. Aber wer in diesem Bereich unterwegs ist, verwendet sie fast immer. Mal sehen, ob ich den Fleiß habe, mehr unter dem Tag Dichotomien zu schreiben, den ich anlässlich dieses Posts angelegt habe

    Nachtrag (2023-04-01)

    Nee, habe ich wieder weggemacht, weil ich den Fleiß noch nicht hatte.

    Dennoch kann ich mich in der Kriegsfrage eigentlich nicht mehr groß über solche Tricks echauffieren, denn Kriegsbegeisterung hält erfahrungsgemäß selten lange an; ich bin eigentlich recht zuversichtlich, dass jedenfalls diejenigen neuen Fans der Panzerhaubitze, die noch etwas Herz und/oder Verstand haben, in recht absehbarer Zeit zu wieder etwas gewaltskeptischeren Positionen zurückkehren werden, ohne dass sich erst richtig viele Leute totschießen müssen.

    Was allerdings taz-Chefreporter (was immer das sein mag) Peter Unfried in der taz vom Samstag gebracht hat, hat mich dann doch schlucken lassen:

    Die Gewaltoption [konkreter weiter oben fomuliert: militärischer Massenmord] ist Voraussetzung einer freien und emanzipatorischen Zukunft.

    Ob es nun sinnvoll ist oder nicht, ich musste dem widersprechen, und die taz hat meinen Leserbrief heute auch abgedruckt:

    Peter Unfried will durch Militär eine freie und emanzipatorische Zukunft sichern. Das ist nicht nur absurd, ist doch der autoritäre Gewaltapparat Militär die Antithese zu Freiheit und Emanzipation. Es ist auch schlicht unhistorisch. Versammlungsfreiheit und Datenschutz, Wahlrecht und Atomausstieg, Streikrecht und straffreie Abtreibung, ganz besonders das Recht, nicht morden zu müssen, auch bekannt als Kriegsdienstverweigerung: Alles in der weiteren Umgebung von Freiheit haben Menschen ohne Militär – in Gewerkschaft, Blaustrümpfen oder Fridays for Future – gegen Menschen mit Militär – ihre Regierungen nämlich – erkämpft und tun es auch gerade jetzt überall Tag für Tag. Wenn Unfried hingegen seine Freiheit auf das Militär baut, hat er sie schon verloren.
    [1]

    Wer es nicht erkennt: Das bezieht sich auf ein sehr zeitgemäßes Lied der Brecht/Weill-Combo. Seit dem 24.8.2021 sind nun Brechts Werke endlich gemeinfrei, und so kann ich den mich immer wieder beeindruckenden Text bedenkenlos zitieren:

    Am Grunde der Moldau wandern die Steine
    Es liegen drei Kaiser begraben in Prag
    Das Große bleibt groß nicht und klein nicht das Kleine
    Die Nacht hat zwölf Stunden, dann kommt schon der Tag.

    Es wechseln die Zeiten. Die riesigen Pläne
    Der Mächtigen kommen am Ende zum Halt.
    Und gehn sie einher auch wie blutige Hähne
    Es wechseln die Zeiten, da hilft kein Gewalt.

    Am Grunde der Moldau wandern die Steine
    Es liegen drei Kaiser begraben in Prag
    Das Große bleibt groß nicht und klein nicht das Kleine
    Die Nacht hat zwölf Stunden, dann kommt schon der Tag.
  • SPARQL 2: Improvising a client

    A Yak on a mountain path, watching the observer

    There is still a lot of hair on the Yak I am shaving in this little series of posts on SPARQL. All the Yaks shown in the series lived on the Valüla Mountain in Vorarlberg, Austria.

    This picks up my story on figuring out whether birthdays are dangerous using SPRAQL on Wikidata. You can probably skip this part if you're only interested in writing SPARQL queries to Wikidata and are happy with the browser form they give you. But you shouldn't. On both accounts.

    At the end of part one, I, for one, was unhappy about the Javascript-based UI at Wikidata and had decided I wanted a user interface that would let me edit my queries in a proper editor (in particular, locally on my machine, giving me the freedom to choose my tooling).

    My browser's web inspector quickly showed me that the non-Javascript web UI simply sent a query argument to https://query.wikidata.org/sparql. That's easy to do using curl, except I want to read the argument from a file (that is, the one I am editing in my vi). Helpfully, curl's man page informs on the --form option:

    This enables uploading of binary files etc. To force the 'content' part to be a file, prefix the file name with an @ sign. To just get the content part from a file, prefix the file name with the symbol <. The difference between @ and < is then that @ makes a file get attached in the post as a file upload, while the < makes a text field and just get the contents for that text field from a file.

    Uploads, Multipart, Urlencoded, Oh My!

    In this case, Wikidata probably does not expect actual uploads in the query argument (and the form does not submit it in this way), so < it ought to be.

    To try it, I put:

    SELECT ?p ?o
    WHERE {
      wd:Q937 ?p ?o.
    }
    LIMIT 5
    

    (the query for everything Wikidata says about Albert Einstein, plus a LIMIT clause so I only pull five triples, both to reduce load on Wikidata and to reduce clutter in my terminal while experimenting) into a file einstein.rq. And then I typed:

    curl --form query=<einstein.rq https://query.wikidata.org/sparql
    

    into my shell. Soberingly, this gives:

    Not writable.
    

    Huh? I was not trying to write anything, was I? Well, who knows: Curl, in its man page, says that using --form does a POST with a media type of multipart/form-data, which many web components (mistakenly, I would argue) take as a file upload. Perhaps the remote machinery shares this misconception?

    Going back to the source of https://query.wikidata.org/, it turns out the form there does a GET, and the query parameter hence does not get uploaded in a POST but rather appended to the URL. Appending to the URL isn't trivial with curl (I think), but curl's --data option at least POSTs the parameters in application/x-www-form-urlencoded, which is what browsers do when you don't have uploads. It can read from files, too, using @<filename>. Let's try that:

    curl --data query=@einstein.rq https://query.wikidata.org/sparql
    

    Oh bother. That returns a lenghty message with about a ton of Java traceback and an error message in its core:

    org.openrdf.query.MalformedQueryException: Encountered " <LANGTAG> "@einstein "" at line 1, column 1.
    Was expecting one of:
        "base" ...
        "prefix" ...
        "select" ...
        "construct" ...
        "describe" ...
        "ask" ...
    

    Hu? Apparently, my query was malformed? Helpfully, Wikidata says what query it saw: queryStr=@einstein.rq. So, curl did not make good on its promise of putting in the contents of einstein.rq. Reading the man page again, this time properly, I have to admit I should have expected that: “if you start the data with the letter @“, it says there (emphasis mine). But haven't I regularly put in query parameters in this way in the past?

    Sure I did, but I was using the --data-urlencode option, which is what actually simulates a browser and has a slightly different syntax again:

    curl --data-urlencode query@einstein.rq https://query.wikidata.org/sparql
    

    Ha! That does the trick. What comes back is a bunch of XML, starting with:

    <sparql xmlns='http://www.w3.org/2005/sparql-results#'>
      <head>
        <variable name='p'/>
        <variable name='o'/>
      </head>
      <results>
        <result>
          <binding name='p'>
            <uri>http://schema.org/version</uri>
          </binding>
          <binding name='o'>
            <literal datatype='http://www.w3.org/2001/XMLSchema#integer'>1692345626</literal>
          </binding>
        </result>
    

    Making the Output Friendlier: Turtle?

    Hm. That's not nice to read. I thought: Well, there's Turtle, a nice way to write RDF triples in plain text. In RDF land, people rather regularly support the HTTP accept header, a wildly underused and cool feature of HTTP that lets a client say what kind of data it would like to get (see Content negotiation in the Wikipedia). So, I thought, perhaps I can tell Wikidata to produce Turtle using accept?

    This plan looks like this when translated to curl:

    curl --header "accept: text/turtle" \
      --data-urlencode query@einstein.rq https://query.wikidata.org/sparql
    

    Only, the output does not change, Wikidata ignores my request.

    Thinking again, it is well advised to do so (except it could have produced a 406 Not Acceptable response, but that would probably be even less useful). The most important thing to remember from part one is that RDF talks about triples of subject, predicate, and object. In SPARQL, you have a SELECT clause, which means a result row in general will not consist of subject, predicate, and object. Hence, the service couldn't possibly return results in Turtle: What does not consist of RDF triples canot be serialised as RDF triples.

    Making the Output Friendlier: XSLT!

    But then what do I do instead to improve result readability? For quick and (relatively) easy XML manipulation on the command line, I almost always recommend xmlstarlet. While I give you its man page has ample room for improvement, and compared to writing XSL stylesheets, the command line options of xmlstarlet sel (use its -h option for explanations) are somewhat obscure, but it just works and is compact.

    If you inspect the response from Wikidata, you will notice that the results come in result elements, which for every variable in your SELECT clause have one binding element, which in turn has a name attribute and then some sort of value in its content; for now, I'll settle for fetching either uri or literal (again, part one has a bit more on what that might mean). What I need to tell xmlstarlet thus is: “Look for all result elements and produce one output record per such element. Within each, make a name/value pair from a binding's name attribute and any uri or literal element you find.” In code, I furthermore need to add an XML prefix definition (that's totally orthogonal to RDF prefixes). With the original curl and a pipe, this results in:

    curl --data-urlencode query@einstein.rq https://query.wikidata.org/sparql \
    | xmlstarlet sel -T -N s="http://www.w3.org/2005/sparql-results#" -t \
      -m //s:result --nl -m s:binding -v @name -o = -v s:uri -v s:literal --nl
    

    Phewy. I told you xmlstarlet sel had a bit of an obscure command line. I certainy don't want to type that every time I run a query. Saving keystrokes that are largely constant across multiple command invocations is what shell aliases are for, or, because this one would be a bit long and fiddly, shell functions. Hence, I put the following into my ~/.aliases (which is being read by the shell in most distributions, I think; in case of doubt, ~/.bashrc would work whenever you use bash):

    function wdq() {
      curl -s --data-urlencode "query@$1" https://query.wikidata.org/sparql
      | xmlstarlet sel -T -N s="http://www.w3.org/2005/sparql-results#" -t \
        -m //s:result --nl -m s:binding -v @name -o = -v s:uri -v s:literal --nl
    }
    

    (notice the $1 instead of the constant file name here). With an exec bash – my preferred way to get a shell to reflecting the current startup scripts –, I can now type:

    wdq einstein.rq | less
    

    and get a nicely paged output like:

    p=http://schema.org/version
    o=1692345626
    
    p=http://schema.org/dateModified
    o=2022-07-31T01:52:04Z
    
    p=http://schema.org/description
    o=ލިޔުންތެރިއެއް
    
    p=http://schema.org/description
    o=ಗಣಿತಜ್ಞ
    
    p=http://schema.org/description
    o=भौतिकशास्त्रातील नोबेल पारितोषिकविजेता शास्त्रज्ञ.
    

    We will look at how to filter out descriptions in languagues one can't read, let alone speak, in the next instalment.

    For now, I'm reasonably happy with this, except of course I'll get many queries wrong initially, and then Wikidata does not return XML at all. In that case, xmlstarlet produces nothing but an unhelpful error message of its own, because it …

  • SPARQL and Wikidata 1: Setting out

    Yaks todding along a mountain path

    If you continue, you will read about a first-rate example of Yak Shaving

    While listening to a short biography of the astrophysicist Mary Lea Heger (my story; sorry, in German), I learned that she died on her birthday. That made me wonder: How common is that? Are people prone to die on their birthdays, perhaps because the parties are so strenuous, perhaps because they consider them a landmark that they are so determined to reach that they hold on to dear life until they have reached it? Or are they perhaps less likely to die because all that attention strengthens their spirits?

    I figured that could be a nice question for Wikidata, a semantic database that feeds Wikipedia with all kinds of semi-linguistic or numeric information. Even if you are not Wikipedia, you can run fairly complex queries against it using a language called SPARQL. I've always wanted to play with that, in particular because SPARQL seems an interesting piece of tech. Answering the question of the letality of birthdays turned out to be a mildly exciting (in a somewhat nerdy sense) journey, and I thought my story of how I did my first steps with SPARQL might be suitably entertaining.

    Since it is a relatively long story, I will split it up into a few instalments. This first part relates a few preliminaries and then does the first few (and very simple) queries. The preliminaries are mainly introducing the design of (parts of) RDF with my take on why people built it like that.

    Basics: RDF in a few paragraphs

    For motivating the Resource Description Format RDF and why people bother with it, I couldn't possibly do better than Norman Gray in his witty piece on Jordan, Jordan and Jordan. For immediate applicability, Wikidata's User Manual is hard to beat.

    But if you're in a hurry, you can get by with remembering that within RDF, information is represented in triples of (subject, predicate, object). This is somewhat reminiscent of a natural-language sentence, although the “predicate“ typically would be a full verb phrase, possibly with a few prepositions sprinkled in for good measure. Things typically serving as predicates are called “property“ in RDF land, and the first example for those defined in wikidata, P10[1], would be something like has-a-video-about-it-at or so, as in:

    "Christer Fuglesang", P10, http://commons.wikimedia.org/wiki/Special:FilePath/Christer%20Fuglesang%20en.webm
    "Christer Fuglesang", P10, http://commons.wikimedia.org/wiki/Special:FilePath/Christer%20Fuglesang%20ru.webm
    

    If you know about first order logic: It's that kind of predicate. And please don't ask who Christer Fuglesang is, the triples just came up first in a query you will learn about a bit further down.

    This was a bit of a simplification, because RDF will not usually refer to a thing (an “entity“ in RDF jargon) with a string (“literal”), if only because there could be multiple Christer Fuglesangs and a computer would be at a loss as to which one I mean in the two triples above. RDF instead talks about “resources“, which is anything that has a URI and encompasses both entities and properties. So, a statement as above would actually combine three URIs:

    http://www.wikidata.org/entity/Q317382, http://www.wikidata.org/prop/direct/P10, http://commons.wikimedia.org/wiki/Special:FilePath/Christer%20Fuglesang%20en.webm

    CURIEs

    That is a lot of stuff to type, and thus almost everything in the RDF world supports URL abbreviation using prefixes. Basically, in some way you say that whenever there's wpt: in a token, some magic replaces it by http://www.wikidata.org/prop/direct/. Ff you know about XML namespaces (and if you're doing any sort of non-trivial XML, you should): same thing, except that the exact syntax for writing down the mapping from prefixes to URIs depends on how you represent the RDF triples.

    These “words with a colon that expand to long URIs by some find-and-replace rules“ were called CURIEs, compact URIs, for a while, but I think that term has become unpopular again. I consider this a bit of a pity, because it was nice to have a name for them, and such a physics-related one on top. But it seems nobody cared enough to push the W3C draft for that ahead.

    As with XML namespaces, each RDF document could use its own prefix mapping; if you want, you could instruct an RDF processor to let you write wikidata-direct-property: for http://www.wikidata.org/prop/direct/ rather than wpt: as usual. But that would be an unfriendly act. At least for the more popular collections of RDF resources, there are canonical prefixes: you don't have to use them, but everyone will hate you if you don't. In particular, don't bind well-known prefixes like foaf: (see below) to URIs other than the canonical ones except when seeing whether a piece of software does it right or setting traps for unsuspecting people you don't like.

    Then again, for what we are doing here, you do not need to bother about prefix mappings at all, because the wikidata engine has all prefixes we will use prefined and built in. So, as long as you are aware that you can replace the funny prefixes with URI parts and that there is some place where those URIs parts are defined, you are fine.

    Long URIs in RDF?

    You could certainly ask why we're bothering with the URIs in the first place if people in practice use the canonical prefixes almost exclusively. I think the main reason RDF was built on URIs was because its parents on the one hand wanted to let everyone “build” resources with minimal effort. On the other hand, they wanted to ensure as best they could that two people would not accidentally use the same resource identifier while meaning different things.

    To ensure the uniqueness of identifiers, piggybacking on the domain name system, which already makes sure that there are never two machines called, say, blog.tfiu.de in the world, is a rather obvious move. In HTTP URIs, domain names show up as the authority (the host part, the thing between the first colon and the double slash), and so with URIs of that sort you can start creating (if you will) your resources and would never conflict with anyone else as long as hold on to your domain.

    In addition, nobody can predict which of these namespace URIs will become popular enough to warrant a globally reserved prefix of their own; you see, family-safe prefixes with four (or fewer) letters are a rather scarce resource, and you don't want to run a registry of those. If you did, you would become really unpopular with all the people you had to tell things like “no, your stuff is too unimportant for a nice abbreviation, but you can have aegh7Eba-veeHeql1:“

    The admittedly unwieldy URIs in practice also have a big advantage, and one that would require some complex scheme like the Handle system if you wanted to replicate it with prefixes: most of the time, you can resolve them.

    Non-speaking URIs

    While RDF itself does not care, most URIs in this business actually resolve to something that is readable in a common web browser; you can always try it with the resources I will be mentioning later. This easy resolution is particularly important in the case of Wikidata's URIs, which are essentially just numbers. Except for a few cases (wd:Q42 is Douglas Adams, and wd:Q1 is the Universe), these numbers don't tell you anything.

    There is no fixed rule that RDF URIs must have a lexical form that does not suggest their meaning. As a counterexample, http://xmlns.com/foaf/0.1/birthday is a property linking a person with its, well, birthday in a popular collection of RDF resources[2] called foaf (as in friend of a friend – basically, you can write RDF-complicant address books with that).

    There are three arguments I have heard against URIs with such a speaking form:

    • Don't favour English (a goal that the very multilingual Wikipedia projects might plausibly have).
    • It's hard to automatically generate such URIs (which certainly is an important point when someone generates resources as quickly and with minimal supervision as Wikidata).
    • People endlessly quarrel about what should be in the URI when they should really be quarrelling about the label, i.e., what is actually shown to readers in the various natural languages, and still more about the actual concepts and definitions. Also, you can't repair the URI if you later find you got the lexical form slightly wrong, whereas it's easy to fix labels.

    I'm not sure which of these made Wikidata choose their schema of Q<number> (for entities) and P<number> (for properties) – but all of them would apply, so that's what we have: without looking …

  • Strafgericht ist für die anderen

    Als vor ein paar Wochen der der Olivindex tief im braunen Bereich war, war allenthalben der Wunsch zu hören, Wladimir Putin möge sich möglichst schnell vor dem Internationalen Strafgerichtshof verantworten. Daraus wird wohl schon deshalb nichts, weil Russland das Gericht nicht anerkennt.

    Das aber fanden die RuferInnen nach Gerechtigkeit damals in der Regel ebenso wenig erwähnenswert wie die Tatsache, dass auch die USA die Jurisdiktion des Haager Gerichtshofs ebensowenig anerkennen wie unsere Regierung beispielsweise das Verbot von Atombomben. „It wouldn't do to mention,“ sagt mensch da im englischen Sprachraum, zumal es bei der US-Abstinenz genau um Straffreiheit bei Handlungen in Angriffskriegen („Kriegsverbrechen“ halte ich ja für einen Pleonasmus) geht.

    Wer aber glaubt, die EU verhalte sich nennenswert anders, täuscht sich. Gerade jetzt gibt es dazu höchst aufschlussreiches Anschauungsmaterial. Die EU rüstet nämlich den Apparat im Senegal nicht nur mit fieser Biometrie auf, sie will dort mit Frontex auch selbst aktiv werden. Die Bedingungen dazu werden gerade verhandelt. Zum Glück ist der EU-Apparat voll undichter Stellen, und so konnte Statewatch jüngst die Verhandlungsposition der Kommission befreien.

    Und darin wird blank gezogen:

    [Frontex-Leute] sollten berechtigt sein, alle Aufgaben der Grenzkontrolle zu erfüllen und die dazu nötige Exekutivgewalt ausüben [...]; sie sollten berechtigt sein, Dienstwaffen, Munition und Ausrüstung mitzuführen und diese gemäß der Gesetze der Republik Senegal zu nutzen.

    (Übersetzung von mir; die offizielle EU-Übersetzung ist nicht befreit).

    Mit anderen Worten: Die EU wird den Senegal zur Übergabe seiner staatlichen Gewalt zwingen. Wer sich fragt, was passiert, wenn sich der Senegal nicht darauf einlässt, mag sich die Geschichte der jüngsten Erpressung von Kenia durch die EU ansehen, als sich das Land gegen EU-Dumpingimporte (von der EU euphemistisch als „European Partnership Agreement“ bezeichnet) wehren wollte.

    Und wer meint, der Senegal dürfte vielleicht nicht die Exekutive, aber doch die Legislative behalten, wird im nächsten Absatz eines Besseren belehrt:

    Insbesondere sollten [die Frontex-Leute] unter allen Umständen volle Immunität gegenüber der Strafjustiz der Republik Senegal genießen. Sie sollten ebenfalls zivilrechtliche Immunität für Handlungen genießen, die sie in Wahrnehmung ihrer offiziellen Funktionen vornehmen.

    Sind wir mal besser froh, dass niemand irgendwem im Senegal Panzerhaubitzen liefert. Slava Senegal!

  • Mary Lea Heger: Interstellares Natrium und Geburtstage

    Fotonegativ eines hellen Sterns und des umgebenden Sternfelds.

    Der Stern δ Orionis in einer Aufnahme von 1927 (B5232a aus HDAP) – das war eines der zwei Objekte, in deren Spektrum Mary Lea Heger das interstellare Natrium entdeckt hat.[1]

    In der DLF-Sternzeit vom 13. Juli ging es um Mary Lea Heger, die vor rund 100 Jahren entdeckte, dass es Natrium im Raum zwischen den Sternen gibt (auch wenn sie sich im verlinkten Artikel von 1919 noch nicht ganz sicher war, wo genau). Wer mal Himmelsaufnahmen aus der Zeit gesehen hat, wird ahnen, wie haarig das gewesen sein muss.

    Heger hat nämlich Spektren aufgenommen, was damals überhaupt nur für sehr helle Sterne wie den oben abgebildeten δ Orionis alias Mintaka (der am weitesten rechts stehende Gürtelstern des Orion) sinnvoll ging. Aus diesen Spektren hat sie dann Radialgeschwindigkeiten abgeleitet, also im Groben beobachtete Wellenlängen von Spektrallinien bekannter Elemente mit deren auf der Erde messbaren Wellenlängen verglichen, daraus die Blau- bzw. Rotverschiebung abgeleitet und daraus wiederum bestimmt, wie schnell sich die Objekte gerade auf uns zu oder von uns weg bewegen.

    Ehrlich gesagt weiß ich gar nicht, wie das damals gemacht wurde. Heute malt einem der Computer schöne Kurven und kann dann auch beliebige Funktionen dranfitten. Damals hingegen war, denke ich, schon die numerische Erfassung der Schwärzungen der Fotoplatte (bei der ihrerseits doppelte Schwärzung mitnichten doppeltes Licht bedeutet) eine echte Herausforderung. Die Wikipedia schreibt leider unter Densitometer nichts zur Geschichte dieser Geräte, und zu einer richtigen Recherche kann ich mich gerade nicht aufraffen.

    Mintaka und Hegers zweites Objekt, der von uns aus kaum ordentlich zu beobachtende β Scorpii alias Akrab[2], sind beides ziemlich heiße Sterne, im Jargon Spektralklasse B mit Oberflächentemperaturen deutlich über 20000 Kelvin (die Sonne: 6000 K). Weil bei diesen Temperaturen die Atome recht schnell unterwegs sind, wenn sie Photonen absorbieren, sind die Linien solcher Sterne in der Regel breit (vgl. Dopplerverbreiterung); auf den Fotos, aus denen solche Spektren gewonnen wurden, wirken die Linien sozusagen ausgewaschen.

    Tanzende und stehende Linien

    Heger hat nun aber auch ein paar recht scharfe Linien von Kalzium und Natrium in den Spektren dieser Sterne gefunden, und zwar in Absorption, was heißt: Irgendwo zwischen da, wo das Licht herkommt und Hegers Spektrographen muss es Kalizum- und Natriumatome geben, die das Licht der passenden Wellenlängen absorbiert (und dann wieder woandershin emittiert) haben. Und davon nicht zu knapp.

    Plot einer Kurve, beschriftet mit Wellenlängen

    Ein modernes Spektrum von β Ori (vom FEROS-Spektrographen der ESO, HD36485_1069462_2014-08-24T08:30:43.517_S0.5x11_1x1_UVB_NOD). Auf der x-Achse ist die Wellenlänge in Nanometer, auf der y-Achse die Flussdichte in Instrumenteneinheiten. Gezeigt ist die Umgebung der Fraunhofer-Linien H (Labor: 393,368 nm) und K (Labor: 396,847 nm) des einfach ionisierten Kalziums. Links ist eine relativ schmale und unstrukturierte Linie zu sehen, wie sie Heger für die interstellare Absorption gesehen haben wird, rechts dann eine breite Linie mit vielen Komponenten von den Einzelsternen: die Höcker da drauf würden tanzen, wenn mensch einen Film machen würde. Nach etwas Überlegung habe ich beschlossen, mich nicht festzulegen, was welche Linie ist…

    Sowohl Akrab als auch Mintaka sind zudem recht enge Doppelsterne[3]. So enge, dass sie mit damaligen Techniken wie ein Stern erschienen. Dass es sich um Doppelsterne handelt, war bekannt, weil in ihren Spektren (im Groben) jede Linie nicht ein Mal, sondern zwei Mal vorhanden ist, und die Teile eines Paars darüber hinaus regelmäßig umeinander tanzen. Die Erklärung: jeder Stern macht für sich eine Linie, die je nach Stellung in der Bahn anders dopplerverschoben ist als die seines Partners. Nun sind solche Sterne sehr schwer, und sie umkreisen sich auf relativ engen Bahnen (bei Mintaka: das Jahr ist im engen Paar 5.7 Tage lang), so dass die Bahngeschwindigkeiten bis hunderte Kilometer pro Sekunde betragen können[4]. Damit sind auch die Dopplerverschiebungen der Linien recht ernsthaft, und so ist die Natur der ersten dieser spektroskopischen Doppelsterne schon Ende des 19. Jahrhunderts aufgefallen.

    Nur: Hegers scharfe Linien tanzen nicht. Sie bleiben stur stehen, während die Sterne umeinander rasen. Und damit ist klar, dass die absorbierenden Atome zumindest nicht zu den einzelnen Sternen gehören. Sie könnten im Prinzip aus der Erdatmosphäre kommen, denn die Natriumschicht in so um die 100 km Höhe, die heute für Laser-Leitsterne verwendet wird, ist in hinreichend empfindlichen Spektren durchaus zu sehen. Wie das mit damaligen Spektren war, weiß ich nicht, die Schicht als solche wurde aber erst 1929 entdeckt (was sich jedoch nur auf die spezifische Verteilung des Natriums beziehen mag – andererseits ist neutrales Natrium in Gegenwart von Sauerstoff nicht gerade stabil. Also: ich weiß es wirklich nicht).

    Abgeleitete Kopfzahl: mit 30⋅3600 Sachen um die Sonne

    Heger wird aber (auch wenn sie das im verlinkten Artikel nicht schreibt, weil die entsprechende Korrektur Teil der Standard-Datenreduktion war und ist) in ihren scharfen Linien doch eine Bewegung gesehen haben, nämlich um etwas weniger als 30  km ⁄ s. Das ist der Reflex der Bewegung der Erde um die Sonne, und der wäre in atmosphärischen Linien nicht zu sehen, da sich ja die Atmosphäre mit der Erde bewegt.

    Die Geschwindigkeit der Erde bei ihrem Weg um die Sonne ist übrigens mit zwei Kopfzahlen schnell abgeschätzt: erstens dem Dauerbrenner 30 Millionen Sekunden pro Jahr (oder π⋅107  s, was tatsächlich die Art ist, in der ich mir das merke) und dann die 150 Millionen km (was ich mir als 1.5⋅1011  m merke) für den Radius der Erdbahn. Die Geschwindigkeit ist dann einfach Umfang der Erdbahn geteilt durch ein Jahr oder in überschaubareren Einheiten

    (2⋅π⋅1.5⋅108  km)/(π⋅107  s) = 3⋅101  km ⁄ s

    Das “etwas weniger“ als diese 30  km ⁄ s kommt daher, dass die volle Amplitude dieser Bewegung nur bei Sternen in der Ekliptik, also der Abbildung der Erdbahn am Himmel, zu sehen ist. Geht mensch von dieser gedachten Linie weg, wird die Geschwindigkeitskomponente in Richtung des Sterns kleiner (nämlich mit dem Kosinus der ekliptikalen Breite), bis am ekliptikalen Pol gar kein Reflex der Erdbewegung mehr zu sehen ist[5].

    Akrab nun steht in einem Tierkreiszeichen und von daher quasi per definitionem nahe an der Ekliptik. Auch der Orion (gleich südlich vom Stier) ist nicht weit von ihr entfernt – die ekliptikale Breite von Mintaka ist ungefähr 23.5 Grad. Deshalb taugt 30  km ⁄ s schon als Abschätzung für die Amplitude der Radialgeschwindigkeit der beiden Sterne aufgrund der Bewegung der Erde um die Sonne.

    Mit 10⋅3600 Sachen mit der Sonne durch die Strom

    Tatsächlich konnte Mary Lea Heger die Rotverschiebungen ihrer scharfen Linien und unscharfen Linien messen und kam auf folgendes Geschwindigkeiten (alles in km/s):

    Objekt β Sco δ Ori
    Natrium -9.2 17.6
    Kalzium -8.5 18.7
    RG des Systems -11.0 15.2
    Sonnenbewegung -10.7 18.1

    Die „Sonnenbewegung“ ist dabei das, was damals schon gemessen war als Bewegung der Sonne gegenüber der allgemeinen galaktischen Rotation von etwa 200  km ⁄ s – wie die damals darauf gekommen sind, ist eine ganz eigene Geschichte –, projiziert auf den Richtungsvektor zum jeweiligen Stern. Die „Radialgeschwindigkeit (RG) des Systems“ hingegen ist die Geschwindigkeit, mit der der Schwerpunkt der jeweiligen Sternsysteme auf uns zukommt oder sich von uns entfernt.

    Dass die Sonnenbewegung und Radialgeschwindigkeiten hier recht eng beieinander liegen, ist übrigens kein Zufall. Beide Sterne sind wie gesagt heiße B-Sterne, und diese sind[6] nach astronomischen Maßstäben sehr jung, gerade erst (also: vor ein paar oder ein paar zehn Millionen Jahren) aus Gaswolken geboren. Die Gaswolken wiederum laufen sehr brav mit der allgemeinen galaktischen Rotation mit. Sie können gar nicht anders, denn anders als die Sterne kollidieren Gaswolken in Galaxien durchaus miteinander, wenn eine versucht, quer zum Strom zu schwimmen. Wenn sie dann kollidieren, verlieren sie rasch ihre Eigengeschwindigkeiten (und produzieren sehr wahrscheinlich noch eifrig Sterne). Was übrig bleibt, läuft wieder brav mit dem Rest der Galaxis.

    Sterne hingegen können sich frei durch die Galaxis bewegen, weil sie praktisch nie mit anderen Sternen kollidieren – für einen Stern, kompakt wie er ist, ist die Galaxis quasi ein Vakuum, wenn auch eins mit Gavitationsfeld. Gerät ein Stern allerdings in die Nähe schwerer Dinge (wie etwa solchej Wolken), wird er ein wenig aus seiner Bahn gehoben, und das äußert sich am Ende in Eigengeschwindigkeiten wie der Sonnenbewegung von oben. Junge Sterne hatten noch keine Zeit, diese Sorte Schwung zu holen, und so ist die Radialgeschwindigkeit oben eigentlich nichts anderes als die Sonnenbewegung.

    Auch wenn Heger keine Fehlerschätzungen angibt, ist die Übereinstimmung der Geschwindigkeiten der scharfen Linien und der Sonnenbewegung umwerfend gut, jedenfalls, wenn mensch die Schwierigkeiten der in diese Tabelle eingehenden Messungen bedenkt. Tatsächlich gibt die Wikipedia für die Radialgeschwindigkeit des Gesamtsystems Akrab  − 1±2  km ⁄ s gegen Hegers -11; in einem System aus sechs Sternen muss das noch nicht mal auf ein Problem bei Heger hindeuten, aber ganz ehrlich: Ich wäre sehr verwundert, wenn sie besser als auf, sagen wir, 5 km/s hätte messen können.

    Hegers Fazit

    Entsprechend war Heger in ihren Schlussfolgerungen vorsichtig:

    The agreement of the velocity obtained from the D lines …
  • Wird Bolsonaro Schuld sein an der nächsten großen Seuche?

    Diagramm mit Einflussfaktoren wie Wald-Dichte, Artenvielfalt, Stadtnähe und ihren Korrelationen untereinander und mit der Inzidenz von Zoonosen

    Wie verschiedene Metriken die Häufigkeit von Zoonosen beeinflussen: Abbildung zwei aus doi:10.1126/sciadv.abo5774. CC-BY-NC Winck et al.

    Auch wenn (oder gerade weil) in China ein SARS-Erreger schon mal aus enem Labor entkommen ist, glaube ich ja immer noch ziemlich fest daran, dass SARS-2 aus (zu) engem Kontakt von Menschen und Wildtieren entstanden ist. Wo es viele Tiere gibt, sind solche Krankheiten mit tierischer Beteiligung, Zoonosen, Regel eher als Ausnahme, und wo es viele verschiedene Tiere gibt, ist entsprechend mit vielen Überraschungen zu rechnen. So erscheint Brasilien als ideales Land, um quantitative Schätzungen zu bekommen zur Frage, wie insbesondere neuartige Krankheitserreger Artgrenzen überwinden können und was dann passiert.

    Das war das Projekt von Gisele R. Winck und Ciclilia Andreazzi vom Institiuto Oswaldo Cruz in Rio de Janeiro sowie KollegInnen von verschiedenen anderen brasilianischen Instituten, über das sie in „Socioecological vulnerability and the risk of zoonotic disease emergence in Brazil”, Science Advances 8 (2022), doi:10.1126/sciadv.abo5774, berichten – und auch gleich anmerken, dass Brasilien vielleicht doch kein ganz ideales Land ist, ist doch ein Großteil der derzeit in Brasilien grassierenden Zoonosen gar nicht in Amerika entstanden: Malaria, Dengue, Zika oder Gelbfieber kommen alle aus der alten Welt.

    Aber es gibt auch Beispiele für Zoonosen aus Südamerika, so etwa Chagas, ein von Trypanosomen – das sind einzellige Eukaryoten, also in gewissem Sinn einfache Tiere – hervorgerufenes Syndrom, das zu tödlichen Verdauungsstörungen führen kann, sich aber nur gemeinsam mit relativ memmigen Wanzen weiterverbreiten kann.

    Pfadanalyse

    Winck et al versuchen, der Frage nach künftigen Zoonose-Risiken mit einer Pfadanalyse auf den Grund zu gehen, einer statistischen Methode zur Aufklärung von Netzwerken einander beeinflussender Größen, von der der ich, soweit ich mich erinnere, zuvor noch nie gehört habe. Diese Lücke dürfte wohl damit zusammenhängen, dass die Methode in der Biologie entwickelt wurde (ihr Erfinder war Populationsgenetiker) und im Bereich von Physik und Astronomie wenige etwas damit anzufangen wussten.

    Eine entsprechende ADS-Anfrage (und das ADS hat eigentlich alles, was es in der Astronomie gibt) liefert dann auch vor allem Kram aus Randbereichen, darunter eine Studie in den Geophysical Review Letters, die fast in das aktuelle Thema passt: „Urban Vegetation Slows Down the Spread of Coronavirus Disease (COVID-19) in the United States“. Da allerdings wette ich ungelesen, dass von dem Effekt wenig übrigbleibt, wenn mensch die Korrelation zwischen graueren Vierteln und Armut auf der einen und SARS-2 und Armut auf der anderen Seite rausrechnet.

    Wie dem auch sei: Bei einer Pfadanalyse braucht es eine Zielgröße (also das, dessen Verhalten erklärt werden soll) und „Kausalfaktoren“ (also Größen, das Verhalten der Zielgröße erklären sollen). Die Zielgröße im Paper ist die Fallzahl von einigen Zoonosen[1] in den verschiedenen brasilianischen Bundesstaaten.

    Das grobe Modell, das der Arbeit zugrundeliegt, ist nun, dass enge Kontakte zwischen Menschen und Tieren, gerade wenn wie beim Verzehr von Bushmeat Blut im Spiel ist, die Zoonosen nach oben treibt. Es könnte auch indirekte Effekte geben, wenn es etwa Wildtieren schlechter geht, weil die Menschen gerade ihr Habitat zerstören, und daher Pathogene, die vorher selten und harmlos waren, genau dann durch die geschwächte Population rauschen, wenn Menschen und Wildtiere während der Rodungen und vor der Etablierung funktionierender Landwirtschaft besonders wahrscheinlich interagieren. Mit solchen Motivationen betrachtet die Arbeit folgende Kausalfaktoren (vgl. Tabelle 1 im Paper):

    • Exposition gegenüber Zoonosen (Wie viele wilde Tiere gibt es? Wie gut ist die medizinische Versorgung der Nutztiere? Wie viel Boden ist (artenarme und in der Hinsicht wahrscheinlich eher sichere) landwirtschaftliche Fläche? Wie ist der Anteil der im Wesentlichen unberührten Fläche? Wie schnell gehen unberührte Flächen verloren?)
    • Empfindlichkeit gegenüber Zoonosen (Bäume in Städten als Proxy für die Art der Besiedlung; Kontakt mit Hausmüll als Proxy für die Dichte des Kontakts zu Vektoren wie Ratten und Mücken; Zustand der Abwassererfassung; Bruttoinlandsprodukt pro EinwohnerIn als Proxy für die Armutsrate)
    • Resilienz (Wie viel Gesundheitspersonal gibt es? In wie vielen Einrichtungen? Wie weit ist es in die nächste Stadt, in der spezialisierte Kliniken verfügbar sein werden?)

    Ich muss an der Stelle ein wenig die Nase rümpfen, denn an sich kann dieses Modell nicht so richtig das, was die AutorInnen zu versprechen scheinen: Aufklären, was mensch tun könnte, um neue Zoonosen im Zaum zu halten. Die Zielgröße ist ja die Ausbreitung längst an den Menschen gewöhnter Erreger. Zudem wird die Mehrheit der untersuchten Zoonosen von einzelligen Tieren verursacht und nicht von Viren oder Bakterien, deren pandemisches Potenzial ich weit höher einschätze, zumal, wenn sie anders als die meisten Einzeller keine Zwischenwirte brauchen.

    Aber seis drum: Ganz unplausibel ist ja nicht, dass, wo bekannte Erreger besonders intensiv zwischen Menschen und Tieren ausgetauscht werden, sich auch unbekannte Erreger allmählich an Menschen gewöhnen können.

    BIP ist wurst

    Angesichts des betrachteten Reichtums an Faktoren ist schon erstaunlich, dass die Mathematik der Pfadanalyse mit den Daten von Winck et al das Bild am Anfang des Posts ergibt (nicht signifikante Kausalfaktoren sind dort nicht gezeigt), also etwa das Bruttoinlandsprodukt pro EinwohnerIn keinen signifikanten Einfluss auf die Zoonoserate hat (was aus meiner Sicht nur heißen kann, dass es in Brasilien kein nützliches Maß für den Wohlstand mehr ist). In den Worten des Artikels:

    Zoonotic epidemic risks, as inferred from the observed mean number of ZD cases, are positively associated with vegetation loss (path analysis coefficient = 0.30), mammalian richness (0.47), and remoteness (0.72) and negatively related to urban afforestation (−0.33) and vegetation cover (−0.82).

    Also: Bäume in der Stadt (hätte ich erstmal nicht als einen wichtigen Faktor geraten, aber siehe das oben erwähnte GeoRL-Paper) und vor allem intakte Wildnis sind gut gegen Zoonosen. Eine hohe Dichte wilder Säugetiere, mit denen Menschen im Zuge von Entwaldung eifrig interagieren und, noch stärker, die Entfernung von größeren menschlichen Ansiedlungen befördern demgegegenüber solche Krankheiten.

    Besonders stark ist dabei der Effekt der Bewaldung (bzw. Besteppung oder Bemoorung, wenn das die lokal vorherrschenden Ökosysteme sind): Sie fördert zwar sehr stark die Artenvielfalt von Säugetieren, doch hemmt sie dennoch Zoonosen insgesamt. Das passt erstaunlich gut zur Beobachtung von Jared Diamond in seinem lesenswerten Buch „Collapse: How societies choose to fail or succeed“[2], dass Entwaldung wohl der allerwichtigste Faktor für den Zusammenbruch von Zivilisationen ist.

    Und dann die Schurken

    Ich bin auf das Paper wie üblich über einen Beitrag in der DLF-Sendung Forschung aktuell gegekommen, in dem Fall vom 30.6. Darin wurde vor allem abgehoben auf den Schluss der AutorInnen, die aktuelle Herrschaft in Brasilien beeinflusse die Kausalfaktoren mit ihrer marktradikalen, reaktionären und teils auch anderweitig dummen Politik stark in Richtung Zoonose:

    Ein weiterer wichtiger Aspekt, dessen Relevanz sich gerade erst erwiesen hat, ist die Empfindlichkeit gegenüber fehlgeleiteten politischen Maßnahmen, wie sie von den augenblicklichen Regierungen veranlasst wurden.

    Besonders gut hat mir dabei gefallen die Rede von einer „increasing socioecological degradation“, also einem zunehmenden sozio-ökologischen Verfall, zumal ich dabei an meine eigene brasilianische Geschichte denken musste.

    Foto eines Schildes aus Portugiesisch: Vorsicht, Waldtiere auf der Straße

    Im Parco de Tijuca auf dem Stadtgebiet von Rio de Janeiro: Warnung vor den „Waldtieren“, die auf der Straße rumlaufen. Tatsächlich turnen Affen sogar durch die Telefonleitungen, die zum Nationalobservatorium führen.

    Im Jahr 2014 habe ich rund eine Woche am Nationalobservatorium in Rio de Janeiro gearbeitet. Ich denke, es ist nicht verkehrt, so etwa in dieser Zeit den Höhepunkt der Wirkungen der Sozialpolitik von Lula da Silva zu verorten, der speziell mit seiner bolsa familia Dutzenden Millionen Menschen ein halbwegs menschenwürdiges Leben ermöglicht hat.

    Das hatte sehr profunde Konsequenzen auch für Menschen aus der Mittelschicht. Mein Gastgeber etwa erzählte, er sei vor Lulas Sozialpolitik „Opfer ungefähr jedes Verbrechens gewesen, das es gibt“, und das sei eine recht typische Erfahrung der Cariocas gewesen. Demgegenüber sei in den vieleicht fünf Jahren vor meinem Besuch eigentlich nichts mehr in der Richtung passiert. Ein weiterer Kollege ergänzte, er sei in dieser Zeit nur einmal ausgeraubt worden, und zwar mit chirurgischer Präzision (seine Worte), als er in den frühen Morgenstunden schon ziemlich beschickert unterwegs gewesen sei und die Räuber die Nettigkeit hatten, ihm seinen Geldbeutel wieder zurückzugeben, zwar ohne Bargeld, aber mit allem Plastikwahnsinn, dessen Wiederbeschaffung wirklich viel Stress gewesen wäre.

    Diese Zeiten sind lange vorbei. Nach dem (rückblickend ist diese Charakterisierung wohl nicht zu bestreiten) Putsch gegen Dilma ging die Politik zurück zur Umverteilung von unten nach oben, mit den erwartbaren Konsequenzen für das Leben in einer Stadt wie Rio – und den weniger offensichlichen Konsequenzen für das Heranbrüten der nächsten großen zoonotischen Pandemie.

    Ich frage mich ja bei solchen Betrachtungen immer, wie Leute wie Bolsonaro eigentlich ruhig schlafen können. Aber dann: Die Frage stellt sich ja ganz analog für Scholz, Steinmeier, für Fischer und Schröder, die mit Hartz IV oder der versuchten Rentenprivatisierung ganz ähnliche Dinge, wenn auch vielleicht auf kleinerer Flamme, angerichtet haben. Und ich vermute, ich habe den Kern der Antwort schon berechnet: Allein der Umstand, dass diese Menschen Macht haben, macht es sehr wahrscheinlich, dass sie über erhebliche moralische Flexibilität verfügen.

    [1]Im einzelnen Bilharziose, Leishmaniose (innere und Haut-; wird im Rahmen des Klimawandels auch in der BRD häufiger), Leptospirose (letzter großer Ausbruch in der …
  • Vorbildliches Friedrichstadt

    Schwarzweißbild auf Tafel vor realen Häusern.

    In Friedrichstadt zeigen Tafeln gerne Fotos von um die 1900, die oft genug bis in Details wie Fenstersprossen dem aktuellen Zustand entsprechen. Dieser Post ist ein vorsichtiger Lobpreis einer solchen Praxis.

    Ich bin gerade im nordfriesischen Friedrichstadt, einem Städtchen nahe der Nordseeküste, das viele TouristInnen anzieht, vor allem wenn, wie jetzt gerade, das Wetter am Strand längere Aufenthalte dort eher unattraktiv macht. Diesen BesucherInnen wird Friedrichstadt gerne als „Stadt der Toleranz“ präsentiert. Angesichts einer jahrhundertelangen Präsenz pazifistischer und damit relativ sympathischer protestantischer Sekten wie der Mennoniten und Quäker ist das wahrscheinlich auch eine recht brauchbare Zuschreibung – gerade diese hatten mit weniger toleranten Obrigkeiten meist erhebliche Probleme.

    Ich allerdings finde das Nest aus anderen Gründen bemerkenswert, und das nicht nur, weil die Toleranz Grenzen hatte, die zumindest halbwegs aufgeklärten Menschen völlig albern erscheinen: Die Unitarier mussten zum Beispiel wieder gehen, was um so erschütternder ist, als sich diese von der christlichen Rechtgläubigkeit vor allem in der Zurückweisung des wahrscheinlich durchgeknalltesten aller Dogmen unterscheiden, nämlich der Trinität.

    Wir müssen uns Gott als Tafellappen vorstellen

    Ich kann nicht widerstehen: Als ich in der Grundschule war, erzählte uns der Dorfpfarrer original, mensch müsse sich die dreifaltige Gottheit vorstellen wie einen Tafellappen. Er nahm daraufhin so einen und faltete ihn an fünf Stellen so, dass vorne drei Falten rausguckten. Ein Tafellappen, drei Falten. Wer andere aus seiner Stadt wirft, weil sie so einen offensichtlichen Polit-Kompromiss[1] nicht glauben wollen, verdient einen Toleranzpreis vielleicht doch nur eingeschränkt.

    Nein, wirklich vorbildlich an Friedrichstadt ist die, trärä, Na… Na… na ja. Ich muss es ja doch irgendwann mal sagen: Nachhaltigkeit. Das Wort ist zwar inzwischen zu Heizmaterial für Dampfplauderer verkommen, aber an sich liegt es ja schon nahe, so leben zu wollen, dass das auch noch ein paar Jahrhunderte weitergehen kann. Die wichtigste Zutat dabei ist: Nicht (prozentual, also exponentiell) wachsen. Was um x% im Jahr wächst, verdoppelt sich nach ungefähr 75/x Jahren (oder so), und zehn Verdopplungszeiten entsprechen einer Vertausendfachung. Fast nichts auf dieser Welt kann sich vertausendfachen, ohne dass etwas gewaltig vor die Hunde geht.

    Friedrichstadt hat sich dem Wachstum in mancherlei Hinsicht beeindruckend entzogen. Herzog Friedrich III von Gottorf hat den Ort in den 1620er Jahren als künftiges Handelszentrum mit ein paar tausend EinwohnerInnen planen lassen. Derzeit, 401 Jahre Jahre nach der Gründung, leben so um die 2500 Menschen hier. Um die Größenordnungen zu betonen: Wer 400 Jahre Zeit hat, hat auch bei einer Verdoppelungszeit von 40 Jahren noch eine Vertausendfachung, und 40 Jahre Verdoppelungszeit entsprechend weniger als zwei Prozent Jahreswachstum.

    Fortzug in wirtschaftlich prosperierendere Gegenden

    Friedrichstadt aber wuchs zumindest in der Bevölkerung nicht. Die entsprechende Statistik aus der Wikipedia sieht als Spline-geglätteter (was das Loch nach dem ersten Weltkrieg überbetont) Plot so aus:

    Plot: Recht konstant bei 2500 verlaufende Linie mit einem jähen Anstieg in den 1940er Jahren und einem relativ steilen Rückgang danach.

    Der Berg in den 1940er und 1950er Jahren ist Folge des Zuzugs von Geflüchteten vor allem aus den von der Sowjetunion eroberten bzw. später kontrollierten Gebieten. Sein Abschmelzen führen die Wikipedia-AutorInnen auf den „Fortzug der Vertriebenen in wirtschaftlich prosperierendere Gegenden“ zurück.

    Auch wenn Bevölkerungsexport keine, hust, nachhaltige Strategie ist: Der Nettoeffekt ist eine konstante Bevölkerung, und bei recht maßvoller Entwicklung der Wohnfläche pro Mensch ist das auch im Stadtbild sichtbar, denn Friedrichstadt hat kaum Einfamilienhaus-Wüsten aus dem Auto-Zeitalter (auch wenn die Stadt, das Eingangsfoto zeigt es, der Automobilisierung nicht entgehen konnte).

    Doch auch wirtschaftlich hat sich nicht allzu viel getan: Eine Mühle, die Kölln-Flocken hergestellt hat (na gut, vielleicht auch anderen Kram für die Firma), ist 2001 wegen mangelnder Kapazität geschlossen worden – wo sie stand, ist heute ein Komplex von Spiel- und Bolzplätzen. Andere Industrie hat schon vorher aufgegeben.

    Und so lebt Friedrichstadt eben weitgehend von Tourismus. Es ist ja auch hübsch hier. Auch das würde ich jetzt nicht als „nachhaltig“ bezeichnen, zumal es ohne ein gewisses Niveau an industrieller Produktion nichts würde mit den fünf Stunden Lohnarbeit pro Woche. Aber dennoch ist es interessant, wie sich eine Stadt anfühlt, die 400 Jahre lang stagnierte, aus welchen Gründen und mit welchen Mitteln auch immer.

    Ich muss sagen: Mir gefällt es in Friedrichstadt.

    [1]Ich persönlich vermute ja, dass es, als beim Konzil von Nicäa die Trinität beschlossen wurde, ähnlich zuging wie während der marktradikalen Hochschul„reformen“ der 1990er und Nullerjahre („Bologna-Prozess“), als jedeR jedeN aufs Kreuz zu legen versuchte und das Ergebnis völlig dysfunktionaler Quatsch ist.
  • Velorution Aber Hallo

    Demo-Impressionen: Fahrrad mit Pappschild "Velorution jetzt", Fahrraddemo fährt auf eine Autobahnauffahrt

    Weil mir mein Pappschild „Velorution Aber Hallo“ im Fridays-for-Future-Stil so gut gefiel (bis auf die Klettbänder war alles recyclet), muss ich kurz von der Demo für den Fahrradschnellweg zwischen Heidelberg und Mannheim erzählen.

    Diese hat eine lange Tradition von inzwischen fast einem Jahrzehnt. Eine noch längere Tradition hat allerdings das Thema, nämlich (mindestens) eine Verbindung zwischen Heidelberg und Mannheim, auf der RadlerInnen nicht entweder ein einem Fort von rasenden Autos gequält werden oder im Übermaß Schnitzeljagd- und Querfeldein-Qualitäten benötigen. Seit größenordnungsmäßig 20 Jahren wird an dem Thema herumdiskutiert und -geplant, ohne dass etwas passiert wäre.

    Um die Sache etwas in Bewegung zu halten, veranstalten ADFC und Co jedes Jahr im Juli eine Raddemo von Heidelberg nach Mannheim. Ganz ehrlich ist es eigentlich immer darum gegangen, die bestehende A656 zu verwenden – diese Straße ist zwar nicht besonders schön, würde aber die technischen Voraussetzungen an einen Radschnellweg durchaus erfüllen. Soweit es mich betrifft, könnten sie das Ding für Autos sperren und es als Radschnellweg deklarieren: Wäre fürs Erste ok.

    In der Realität sind diese Demos natürlich nie auf einer, schauder, Bundesautobahn gefahren, jedenfalls nicht den ganzen Weg. Dieses Mal aber waren wir immerhin ein kleines Stück auf einer leibhaftigen Autobahn unterwegs, für vielleicht 500 Meter auf der A656 vor Mannheim, mit offiziellem Segen und von der begleitenden Polizei zelebriert wie ein Hochamt.

    Jaja, Velorution, der Übergang von einer Auto- in eine Fahrradgesellschaft, in der der Wahnsinn aus der Dystopie des Herrn Benz durch entspannte Mobilität und selbstbestimmten Umgang mit Verkehrstechnik ersetzt würde: die sieht anders aus. Aber vielleicht hat die Standpauke[1], die eine Vertretrin des Radentscheid Heidelberg den mitfahrenden Offiziellen (ja, der Heidelberger OB und der Mannheimer „Verkehrsbürgermeister“ sind tatsächlich die ganze Strecke mitgefahren) bei der Abschlusskundgebunge gehalten hat, diese ja vielleicht doch so weit beeindruckt, dass wenigstens zwei oder drei Parkplätze im nächsten Jahr verschwinden werden. Und das wäre ja schon mal ein Gewinn.

    Fahrräder auf einer autobahnähnlichen Straße, ein Anhänger mit Blumen

    So sieht Velorution aus: Menschen und Blumen auf der Autobahn.

    [1]Es war großartig: Während die Bürgermeister wieder davon geredet haben, dass es nur noch ein paar „Lückenschlüsse“ brauche, beschrieb die Rednerin die Untätigkeit der Verwaltungen und die düstere Realität, in der nicht ein Parkplatz weichen darf, während die Bürgermeister im Stil gescholtener Schulbuben danebenstanden. Sehr charmant und mit viel Applaus bedacht. Wenn das dem Apparat nicht etwas mehr Realitätssinn vermittelt…
  • Wifi im Metronom: Ui

    Screenshot: Etwas zerrupfte Felder einer einfachen Webseite

    Das Captive Portal im WLAN vom Metronom, gerendert in einem netsurf: Nicht perfekt, aber es funktioniert, ganz ohne Javascript und anderen Zauber.

    Ich sage ja nur ungern etwas Positives über Epiphänomene der Bahnprivatisierung, aber wo ich gerade in einem Metronom sitze und ich wiederholt über absurd komplexe Captive Portals geschimpft habe: Die Metronoms (bzw. ihr Dienstleister Icomera) machen das tatsächlich mal so, dass das halbwegs akzeptabel ist: Es funktioniert ohne Javascript und Local Storage, auch im netsurf (wenn auch interessanterweise nicht mit dillo; ich habe das nicht debuggt) und überträgt in restriktiv konfigurierten Browsern gerade mal 6 kiB für die Seite. Selbst ein webkit kommt, solange Javascript aus ist, mit rund 50 kiB raus.

    Wenn das irgendwer von Icomera liest: Ziemlich großes Lob[1]! Wenn das hier jemand liest, der/die ein kommerzielles WLAN anbieten will, es aber nicht einfach ganz offen lassen will: Geht zu Icomera und sagt: „Ich will das, was die Metronoms bekommen haben“.

    Full Disclosure: Ich bin an sich ein zähnefletschender Feind von „Dienstleistern“ wie Icomera, habe aber ansonsten tatsächlich nichts mit denen zu tun.

    PS: Kein Licht ohne Schatten im Geschäft von IT-„Dienstleistung“: Icomera blockt leider Port 587, der inzwischen Standard fürs Maileinliefern ist. Ach, Icomera: Drängt die Leute doch bitte nicht noch mehr zu webmail (und gmail). Aber immerhin haben sie ssh offen gelassen, so dass halbwegs unproblematische Selbsthilfe möglich ist.

    [1]Für ganz großes Lob müsstet etwas zurückhaltenderes CSS verwenden oder zumindest den z-index eures Dialogs über den Footer heben.
  • PSA: netsurf 3 does not accept cookies from localhost

    As I have already pointed out in April, I consider simple and compact web browsers a matter of freedom (well, Freedom as in speech, actually), and although there's been a bit of talk about ladybird lately, my favourite in this category still is netsurf, which apparently to this date is lean enough to be runnable on vintage 1990 Atari TT machines. I'll freely admit I have not tried it, but the code is there.

    Yesterday, however, netsurf drove me crazy for a while: I was developing a web site, making sure it works with netsurf. This website has a cookie-based persistent login feature, and that didn't work. I sent my Set-Cookie headers all right – ngrep is your friend if you want to be sure, somewhat like this:

    sudo ngrep -i -d lo cookie port 8888
    

    Ngrep also clearly showed that netsurf really did not send any Cookie headers, so the problem wasn't on the cookie header parsing side of my program, either.

    But why did the cookies disappear? Cookie policy? Ha: netsurf does accept a cookie from Google, and crunching this would be the first thing any reasonable policy would do. Did I perhaps fail to properly adhere to the standards (which is another thing netsurf tends to uncover)? Hm: looking up the cookie syntax spec gave me some confidence that I was doing the right thing. Is my Max-Age ok? Sure, it is.

    The answer to this riddle: netsurf does not store cookies if it cannot sort them into a hierarchy of host names, and it never can do that for host names without dots (as in localhost, for instance). Given the ill-thought-out Domain attribute one can set for cookies (see the spec linked above if you want to shudder), I even have a solid amount of sympathy for that behaviour.

    But given that that is something that will probably bite a lot of people caring about freedom enough to bother with netsurf, I am still a bit surprised that my frantic querying of search engines on that matter did not bring up the slightly unconventional cookie handling of netsurf. Let us hope this post's title will change that. Again, netsurf 3 will not store cookies for not only localhost but any host name without dots in it. Which is a bit inconvenient for development, and hence despite my sympathy I am considering a bug report.

    Meanwhile, I've worked around the problem by adding:

    127.0.0.1 victor.local.de
    

    to my /etc/localhost (the name really doesn't matter as long as it will never clash with an actual site you want to talk to and it contains one or more dots) and access the site I'm developing as http://victor.local.de. Presto: my cookie comes back from netsurf all right.

    A Debugging Session

    So, how did I figure this riddle out? The great thing about Debian and halfway compact software like netsurf is that it makes it reasonably simple to figure out such (mis-) features. Since I firmly believe that the use of debuggers is a very basic skill everyone touching a computer should have, let me give a brief introduction here.

    First, you need to get the package's source. Make sure it matches the version of the program that you actually run; to do that, copy the deb line in /etc/apt/sources.list for the repository the package comes from (note that this could be the security repo if you got updates from there). In the copied line, replace deb with deb-src. In my case, that would be:

    deb-src https://deb.debian.org/debian bullseye main
    

    On a freshly installed Debian, it's likely you already have a line like this; consider commenting out the deb-src lines when not working with source code, as that will make your apt operations a bit faster.

    After an apt update, I can now pull the source. To keep your file system tidy, I put all such sources into children of a given directory, perhaps /usr/src if you're old-school, or ~/src if not:

    cd
    mkdir -p src/netsurf
    cd src/netsurf
    apt-get source netsurf-gtk
    

    I'm creating the intermediate netsurf directory because apt-get source creates four items in the directory, and in case you're actually building a package (which you could, based on this), more entries will follow; keeping all that mess outside of src helps a lot. Note that apt-get source does not need any special privileges. You really should run it as yourself.

    By the way, this is the first part where monsters like webkit make this kind of thing really strenuous: libwebkit sources (which still are missing much over a full browser) pull 26 megabytes of archive expanding to a whopping 300 Megabytes of source-ish goo.

    To go on, enter the directory that apt-get source created; in my case, that was netsurf-3.10. You can now look around, and something like:

    find . -name "*.c" | xargs grep "set-cookie"
    

    quickly brought me to a file called netsurf/content/urldb.c (yeah, you can use software like rgrep for „grep an entire tree“; but then the find/xargs combo is useful for many other tasks, too).

    Since I still suspected a problem when netsurf parses my set-cookie header, the function urldb_parse_cookie in there caught my eye. It's not pretty that that function is such an endless beast of hand-crafted C (rather than a few lines of lex[1]), but it's relatively readable C, and they are clearly trying to accomodate some of the horrible practices out there (which is probably the reason they're not using lex), so just looking at the code cast increasing doubts on my hypothesis of some minor standards breach on my end.

    In this way, idly browsing the source code went nowhere, and I decided I needed to see the thing in action. In order to not get lost in compiled machine code while doing that, one needs debug symbols, i.e., information that tells a debugger what compiled stuff resulted from what source code. Modern Debians have packages with these symbols in an extra repository; you can guess the naming scheme from the apt.sources string one has to use for bullseye:

    deb http://debug.mirrors.debian.org/debian-debug bullseye-debug main
    

    After another round of apt update, you can install the package netsurf-gtk-dbgsym (i.e., just append a -dbgsym to the name of the package that contains the program you want to debug). Once that's in, you can run the GNU debugger gdb:

    gdb netsurf
    

    which will drop you into a command line prompt (there's also a cool graphical front-end to gdb in Debian, ddd, but for little things like this I've found plain gdb to be less in my way). Oh, and be sure to do that in the directory with the extracted sources; only then can gdb show you the source lines (ok: you could configure it to find the sources elsewhere, but that's rarely worth the effort).

    Given we want to see what happens in the function urldb_parse_cookie, we tell gdb to come back to us when the program enters that function, and then to start the program:

    (gdb) break urldb_parse_cookie
    Breakpoint 1 at 0x1a1c80: file content/urldb.c, line 1842.
    (gdb) run
    Starting program: /usr/bin/netsurf
    

    With that, netsurf's UI comes up and I can go to my cookie-setting page. When I try to set the cookie, gdb indeed stops netsurf and asks me what to do next:

    Thread 1 "netsurf" hit Breakpoint 1, urldb_parse_cookie (url=0x56bcbcb0,
        cookie=0xffffbf54) at content/urldb.c:1842
    1842  {
    (gdb) n
    1853    assert(url && cookie && *cookie);
    

    n (next) lets me execute the next source line (which I did here). Other basic commands include print (to see values), list (to see code), s (to step into functions, which n will just execute as one instruction), and cont (which resumes execution).

    In this particular debugging session, everything went smoothly, except I needed to skip over a loop that was boring to watch stepping through code. This is exactly what gdb's until command is for: typing it at the end of the loop will fast forward over the loop execution and then come back once the loop is finished (at which point you can see what its net result is).

    But if the URL parsing went just fine: Why doesn't netsurf send back my cookie?

    Well, tracing on after the function returned eventually lead to this:

    3889      suffix = nspsl_getpublicsuffix(dot);
    (gdb)
    3890      if (suffix == NULL) {
    

    and a print(suffifx) confirmed: suffix for localhost is NULL. Looking at the source code (you remember the list command, and I usually keep the source open in an editor window, too) confirms that this makes netsurf return before storing the freshly parsed cookie, and a cookie not stored is a cookie not sent back to the originating site. Ha!

    You do not want to contemplate how such a session would look like with a webkit browser or, worse, firefox or chromium, not to mention stuff you don't have the source …

  • Der Markov-Preis für die ungewöhnlichste Wortfolge

    Ich bin kein besonderer Freund der Triggerwarnung an sich, aber hier warne ich mal: Es geht um Rassismus, schreckliche Gewalt (wenn das für euch einen Unterschied macht: obendrein gegen Kinder) und Religion. Eigentlich ist das alles viel zu ernst für einen Spaßpreis.

    Aber es hilft nichts: Der Markov-Preis für die ungewöhnlichste Wortfolge[1] geht heute an den Deutschlandfunk für den Hintergrund Politik vom 2. Juli, dessen Thema der Sender wie folgt umschreibt:

    Tausende indigene Kinder wurden zwischen 1870 und 1996 in Kanada von ihren Familien getrennt und in Internaten untergebracht. Oft wurden sie dort sexuell missbraucht, viele starben. Die Aufarbeitung dieses Kapitels der kanadischen Geschichte hat erst begonnen – und wird die Gesellschaft noch lange beschäftigen.

    Darin heißt es bei Minute 12:00: „Die Nonnen hatten alle Lederpeitschen.“ Nennt mich naiv im Hinblick auf die Realität des Christentums, aber: jedenfalls außerhalb der engeren BDSM-Szene ist das schon ein Satz, dem eine durchschnittliche künstliche Intelligenz eine eher geringe Wahrscheinlichkeit zuordnen würde. Der Neugier halber habe ich kurz meinen Müllbrowser angeworfen (in dem darf liberal Javascript laufen), um zu sehen, was Google dazu einfällt:

    Google-Suchfeld mit "Die Nonnen hatten alle" und vorgeschlagener Ergänzung "folgen"

    Bei näherer Überlegung muss ich die Preisvergabe allerdings relativieren, denn wenn ich (erneut) an Edgar Allen Poes Kurzgeschichte Die Grube und das Pendel denke, erscheint die prämierte Wortfolge und auch ihre BDSM-Konnotation gar nicht mehr so abwegig.

    Eine weitere Verbindung zu jüngeren Themen aus diesem Blog fand ich bei Minute 10:20. In der Übersetzung des Deutschlandfunks:

    Sie kamen mit diesen Lastwagen, mit denen sonst Vieh transportiert wird. Damit haben sie uns abgeholt…

    …nämlich in die besagten residential schools.

    Ich glaube, es ist kein Zufall, dass da Fahrzeuge eingesetzt wurden, die normalerweise Schlachttiere bewegen. Gegen Ende meiner Überlegungen zu Königinnenkämpfen neulich hatte ich schon darauf hingewiesen, dass die Charakterisierung von Menschen als lästige (oder im vorliegenden Fall zu tötende) Tiere ein „konstantes Feature so gut wie aller Kriege und anderer Massenmorde der Geschichte“ ist.

    Ganz gewiss hat es der Transport der Kinder in Schlachtvieh-Wagen den im Apparat beschäftigten Menschen erheblich leichter gemacht, so unmenschlich zu handeln. Und ja, das ist sowohl ein Argument für die Erhaltung der Empathie mit Schlachtvieh als auch ein Argument gegen den Transport von Menschen in Viehtranportern[2].

    [1]Benannt ist der Preis nach Andrei Andrejewitsch Markow in seiner in Fachkreisen üblicheren englischen Umschreibung (sich selbst wird er wohl vor allem Марков geschrieben haben). Markov-Ketten waren bis zum Durchmarsch der neuronalen Netze das Mittel der Wahl zur statistischen Modellierung sprachlicher Äußerungen, also letztlich zur Beantwortung der Frage, wie wahrscheinlich es ist, kurz nach dem Token „Nonne“ ein Token wie „Hostie“, „Backschaufel“, „Gesangbuch“, „Rohrstock“ oder eben „Lederpeitsche“ zu finden.
    [2]Auch wenn ich irgendwelche Nazigeschichten hier lieber raushalten würde (denn da ist nochmal was ganz anderes passiert), muss ich, wo ich schon grob das Thema habe, noch anmerken: Ich bin überzeugt, dass Adolf Eichmann nicht nur aus Sachzwang Viehwaggons gewählt hat, um all die Menschen in die NS-Vernichtungslager verschleppen zu lassen.
  • Bertrand Russell und die Faulheit

    Als ich angefangen habe, an diesem Blog zu schreiben, wollte ich eigentlich regelmäßig über den Wahnsinn ranten, dass wir Unmengen Plunder und „Dienstleistungen“ herstellen, ohne die die Welt eigentlich besser wäre, und dafür sowohl uns selbst als auch den Planeten furchtbar stressen. Wenn ich jetzt sehe, was ich wirklich unter dem Tag Faulheit geschrieben habe: Am Schluss gab es doch immer andere Themen.

    Unterdessen war am 18. Mai der 150. Geburtstag von Bertrand Russell, von dem hier verschiedentlich schon die Rede war, allerdings eher im Zusammenhang mit seiner Philosophiegeschichte und weniger aufgrund seiner Arbeiten an den Grundlagen der Mathematik, seiner zähen Arbeit gegen religiösen Wahn oder seines pazifistischen Elans[1]; mit all dem hat mich Russell schon sehr lange begeistert.

    Erst im Portrait von Russell in SWR2 Wissen am 13.5. (Audio lohnt sich: Russell spricht selbst, Englisch und Deutsch!) jedoch erfuhr ich, dass er mal wegen Aufruf zu Widerstand gegen die Staatsgewalt im Gefängnis saß (zudem im Alter von 89 Jahren) – und, dass er schon 1932 die zornige Diatribe gegen den Unsinn exzessiver Lohnarbeit geschrieben hat, die ich für diesen Blog vorgesehen hatte.

    Sind wir 90 Jahren später klüger?

    Allerdings schrieb Russell seinen kleinen Aufsatz auf dem Höhepunkt der Großen Depression, also unter fantastischen Arbeitslosenraten, und so unterscheidet sich seine Analyse schon in vielem von meiner; der wichtigste Punkt wäre wohl, dass Russell in erster Linie die vorhandene Arbeit gleichmäßiger verteilen wollte, während ich, 90 Jahre später, überzeugt bin, dass die Gesamtmenge an Arbeit drastisch reduziert werden muss und kann, um den allgemeinen Wohlstand zu heben. Aber wir haben eben auch 90 Jahre Produktivitätssteigerung trotz Übergangs in die „Dienstleistungsgesellschaft“ hinter uns, und Russell konnte nichts von Indexfonds, Fidget Spinnern, SAP, SUVs, Nagelstudios, Bundesligafernsehen, Rechteverwertungsgesellschaften, Flimmerwände, TikTok und all dem anderen bunten Mist wissen, mit dem wir uns heute das Leben gegenseitig schwer machen.

    Russells Essay „In Praise of Idleness“ ist beim Web Archive zu haben (fragt mich nicht, wie das gerade mal 50 Jahre nach Russells Tod trotz Contentmafia zugeht; schlechter auf Deutsch), und wo ich ihn schon gelesen habe, möchte ich ein paar der schöneren Zitate hier versammeln, zumal seine Argumente inzwischen vielleicht unvollständig, sicher aber nicht falsch sind. Die Übersetzungen sind jeweils von mir.

    Russell fängt mit etwas an, das zwar zu lang ist, um ein gutes Gaffito zu machen, und vielleicht klingt „rechtschaffen“ („virtuous“) ein wenig angestaubt. Ich würde damit dennoch jeden Tag auf eine Fridays For Future-Demo gehen:

    Ich glaube, dass viel zu viel Arbeit getan wird in der Welt, und dass der Glaube, Arbeit sei rechtschaffen, unermesslichen Schaden anrichtet [...]

    Ursprüngliche Gewalt

    Im Weiteren leitet Russell die „Arbeitsethik“ in etwa dadurch ab, dass früher mal Krieger die Leute, die die Arbeit gemacht haben, nicht dauernd mit Gewalt zwingen wollten, sie zu füttern. Russell, der ja Kommunist gewesen war, bis er Lenin getroffen hat, waren gewiss die Parallelen zu Marx' ursprünglicher Akkumulation[2] bewusst; ich frage mich ein wenig, warum er darauf nicht wenigstens kurz anspielt.

    Und dann kommt seine scharfe Beobachtung, dass es während des ersten Weltkriegs mit all seiner völlig destruktiven Verschwendung den ArbeiterInnen im UK eigentlich besser ging als in Zeiten ganz normalen Wirtschaftens:

    Trotz all [der Verschwendung aufs Töten] war das generelle Wohlstandsniveau der ungelernten LohnarbeiterInnen auf der Seite der Alliierten höher als davor oder danach. Die tatsächliche Bedeutung dieser Tatsache wurde durch Finanzpolitik versteckt: Die Kriegsanleihen ließen es so aussehen, als würde die Zukunft die Gegenwart ernähren. Aber das ist natürlich unmöglich; ein Mensch kann keinen Brotlaib essen, der noch nicht existiert.

    Diese Argumentation zeigt in der anderen Richtung übrigens den Unsinn (oder die Fiesheit) kapitalgedeckter Rentenversicherungen: Wenn in 50 Jahren niemand mehr Brot backt, wird es für all das angesparte und zwischenzeitlich zerstörerische Kapital kein Brot zu kaufen geben – über diesen spezifischen Wahnsinn hatte ich es schon kurz im letzten April.

    In diesem speziellen Fall würde ich Russell allerdings fragen wollen, ob das ähnlich auch für die britischen Kolonien galt; einige indische Hungersnöte im Megaopferbereich fallen durchaus in die verschiedenen Kriegszeiten, und ich vermute, Russell sieht hier zu guten Stücken lediglich die während Kriegen erheblich größere Kampfkraft nicht allzu patriotischer Gewerkschaften reflektiert.

    Philosophie und Sklavenhaltung

    Wenig später folgt ein weiteres Bonmot, wenn Russell zunächst die immer noch herrschende Ideologie erklärt:

    Warum [sollten Leute ohne Lohnarbeit verhungern und die anderen furchtbar lang arbeiten]? Weil Arbeit Pflicht ist, und Menschen nicht im Verhältnis zu dem bezahlt werden sollen, was sie herstellen, sondern im Verhältnis zu ihrer Tugendhaftigkeit, wie sie durch ihren Fleiß unter Beweis gestellt wird.

    Das ist die Moralität des Sklavenstaates, angewandt auf Umstände, die völlig verschieden sind von denen, unter denen sie entstand.

    Ich merke kurz an, dass Russell als Philosoph dem antiken Sklavenstaat durchaus etwas abgewinnen konnte, denn ohne die Arbeit all der SklavInnen hätten Thales und Demokrit wohl keine Muße gehabt, ihren von Russell sehr geschätzten Gedanken nachzuhängen. Dabei ist er gar nicht so furchtbar darauf fixiert, dass die Leute in ihrer Muße dringend philosophieren[3] müssen:

    Es wird der Einwand kommen, dass, wenn auch ein wenig Muße angenehm ist, die Leute nicht wüssten, mit was sie ihre Tage füllen sollen, wenn sie nur vier Stunden von ihren vierundzwanzig arbeiten müssen. Soweit das in unserer modernen Welt wirklich zutrifft, ist es eine Verdammung unserer Zivilisation; es war jedenfalls in keiner vorherigen Epoche wahr. Es hat vor uns eine Fähigkeit gegeben für Freude und Spiel, die in gewissem Maß von unserem aktuellen Kult der Effizienz gehemmt wird. Der moderne Mensch denkt, dass es für jede Tätigkeit einen Grund außerhalb ihrer selbst geben müsse, dass Dinge nie um ihrer selbst willen getan werden dürfen.

    Die lahmeren Einwände gegen das bedingungslose Grundeinkommen kamen also auch damals schon. Ich stimme Russells Entgegnug aus diesem Absatz herzlich zu, auch wenn er wie ich auch nicht widerstehen kann, kurz darauf von einer generellen Begeisterung für Wissenschaft zu träumen:

    In einer Welt, in der niemand gezwungen ist, mehr als vier Stunden pro Tag zu arbeiten, wird jede Person, die die wissenschaftliche Neugier packt, sich dieser hingeben können, und alle MalerInnen werden malen können, ohne zu verhungern, gleichgültig, wie großartig ihre Bilder sein mögen.

    Nun… Bis zum Beweis des Gegenteils glaube ich fest daran, dass eine Gesellschaft mit minimalem Lohnarbeitszwang eine Gesellschaft von BastlerInnen und Amateurastronominnen sein wird. Schaun wir mal.

    Krieg ist viel Arbeit

    Ich kann dieses Best-of aus Russells Artikel nicht ohne seine Brücken zum Kriegführen beenden. Krieg erwähnt er, wenn er Techniken diskutiert, die die Übersetzung von Produktivitätsfortschritten in weniger Arbeit verhindern:

    Wenn sich alle diese Methoden als unzureichend herausstellen, machen wir Krieg; wir lassen ein paar Leute Explosivstoffe herstellen und ein paar andere diese zünden, ganz als wären wir Kinder, die gerade Feuerwerk entdeckt haben.

    Und dann sagt er in der Abteilung Utopie:

    [Wenn die Leute nicht mehr so wahnsinnig viel arbeiten,] wird der der Hunger nach Krieg aussterben, teils aus diesem Grund [weil die Leute netter und weniger misstrauisch wären] und teils, weil Krieg viel und schwere Arbeit mit sich bringen würde.
  • Libellen aufs Kreuz gelegt

    Eine Königslibelle sitzt senkrecht an einem Stück Holz; seitlich hängt eine leere Hülle einer Libellenlarve.

    Diese Libelle – ausweislich der leeren Larvenhülle halbrechts unten wahrscheinlich gerade erst geschlüpft – ist hoffentlich Zeit ihres Lebens (ein paar Wochen im Sommer 2020) mit sehenden Augen in der Gegend vom Weißen Stein herumgeflogen.

    Als ich in den Kurzmeldungen in Forschung aktuell vom 16.5. (ab Minute 1:50) davon hörte, wie Leute Libellen auf den Rücken gedreht und dann fallen gelassen haben, habe ich unmittelbar Lausbuben assoziiert, die strampelnden Käfern zusehen. Das hörte sich nach einer vergleichsweise eher gutgelaunten Angelegenheit für meine fiktionale Ethikkommission an. Jetzt, wo ich die zugrundeliegende Arbeit, „Recovery mechanisms in the dragonfly righting reflex“, Science 376 (2022), S. 754, doi:10.1126/science.abg0946, gelesen habe, muss ich das mit der guten Laune etwas relativieren.

    Zunächst beeindruckt dabei der interdisziplinäre Ansatz. Hauptautorin ist Jane Wang, Physikerin von der Cornell University (kein Wunder also, dass im Paper eine Differentialgleichung gelöst wird), mitgeholfen haben der Luftfahrtingenieur James Melfi (auch von Cornell; kein Wunder, dass rechts und links Euler-Winkel gemessen werden) und der Neurobiologe Anthony Leonardo, der am Janelia Resarch Campus in Virgina arbeitet, augenscheinlich eine Biomed-Edeleinrichtung im Umland von Washington DC.

    Zusammen haben sie mit Hochgeschwindingkeitskameras eine Variante des Schwarzweiß-Klassikers „Wie eine Katze auf den Füßen landet[1] aufgenommen, dieses Mal eben mit Libellen. Dabei haben sie den Libellen einen Magneten auf den Bauch geklebt, sie mit diesem in Rückenlage an einem Elektromagneten festgeklemmt, gewartet, bis sich die Tiere beruhigt hatten und dann den Strom des Elektromagneten abgeschaltet, so dass die Libellen (im physikalischen Sinn) frei fielen.

    Libellen rollen präzise nach rechts

    Wenn das exakt so gemacht war, war offenbar sehr vorhersehbar, was die Libellen taten. Wang et al geben an, es sei ganz entscheidend, dass die Füße der Tiere in der Luft hängen, weil sonst einerseits eigene Reflexe von den Beinen ausgelöst würden und andererseits die Libellen selbst starten wollen könnten: „voluntary take-off via leg-kicks introduces a large variability“.

    Bis dahin regt sich meine Empathie nur wenig. Zwar schätzen es die Libellen ganz sicher nicht, auf diese Weise festgehalten zu werden. Aber andererseits ist das alles ganz gut gemacht, und die Ergebnisse der Studie sind soweit ganz überzeugend und beeindruckend. Die Tiere drehen sich konsistent um ihre Längsachse, um wieder auf den Bauch zu kommen, fangen mit der Drehung nach gerade mal 100 ms an (als Reaktionszeit für Menschen gelten so etwa 300 ms; aber ok, wir haben auch viel längere Nerven) und sind dann nach gut zwei Zehntelsekunden oder vier Flügelschlägen fertig, also bevor unsereins überhaupt beschlossen hätte, was zu tun ist.

    Für mich unerwarteterweise findet die Drehung sehr kontrolliert und offenbar vorgeplant statt. Ich lese das aus der Tatsache, dass die Winkelgeschwindigkeit der Drehung zwischen 170 Grad (fast auf dem Rücken) und vielleicht 40 Grad (schon recht gut ausgerichtet) praktisch konstant ist. Abbildung 2 B des Papers fand ich in der Hinsicht wirklich erstaunlich: nicht vergessen, das Tier bewegt derweil ja seine Flügel.

    Die AutorInnen betrachten weiter die Stellung der beiden Flügelpaare im Detail, um herauszubekommen, wie genau die Libellen die präzise Drehung hinbekommen. Das ist bestimmt sehr aufregend, wenn mensch irgendwas von Flugzeugbau versteht, aber weil ich das nicht tue, hat mich das weniger begeistert. Außerdem war ich zu dem Zeitpunkt bereits etwas voreingenommen, nachdem ich erfahren hatte, dass, um die Flügelstellung mit den Analyseprogrammen, die Wang et al hatten, rekonstruieren zu können, die Libellen mit Nagellack sechs Punkte auf die Flügel gemalt bekamen.

    Die Erzählung wird düsterer

    Für die Libellen noch unangenehmer dürfte, so denke ich mir, das kleines Y-förmige Plastikgestell gewesen sein, das ihnen die ExperimentatorInnen auf den Thorax geklebt haben. Sie sagen, es sei nötig, um das Bezugssystem der fallenden Libelle bestimmen zu können. Und dann gibts noch den Magneten, der die Libelle vor dem Abwurf hält: alles zusammen wiegt ungefähr 25 mg, bei einer Libelle, die selbst gerade mal ein Viertelgramm wiegt. Andererseits, und das will ich gerne glauben, nehmen heranwachsende Libellen bis zu 50 mg am Tag zu (sie haben ja auch nur ein paar Wochen Zeit als Imago), so dass sie Massenänderungen dieser Art vielleicht wirklich nicht belasten.

    Tote Königslibelle hängt in der Luft an einem Spinnfaden

    Wie es eine Spinne hinbekommen hat, diese Libelle zu erlegen, weiß nicht nicht. Aber immerhin sind ihre Augen und Ocellen nicht zugepinselt.

    Wirklich geregt hat sich mein Mitleid – unter der Maßgabe der letzten Absätze der Geschichte mit den Wespen – aber, als es um die Frage ging, woher Libellen eigentlich ihre Orientierung kennen, woher sie also wissen, ob sie gerade auf dem Rücken fliegen oder vielleicht auf der Seite.

    Die Arbeitshypothese von Wang et al war offenbar, dass das im Wesentlichen der Sehsinn ist. Moment: „Der Sehsinn“? Nein: „Die Sehsinne“. Libellen haben nämlich gleich zwei davon, einerseits ihre Facettenaugen, dazu jedoch noch einfache, nicht abbildende Sensoren, die Ocellen. Ich sags ganz ehrlich: Ich habe das Paper vor allem gelesen, weil ich wissen wollte, wie sie den Libellen die Augen und Ocellen verbunden haben.

    Da ich das jetzt weiß, kenne ich die Stelle, an der ich als Ethikkommission nein gesagt hätte, denn die Sinne der Tiere wurden mit einem bestimmt nicht mehr entfernbarem Pamp aus schwarzer Farbe vermischt mit UV-blockierendem Kleber zugekleistert. Die Versuchsreihe mit geblendeten Libellen haben Wang und ein lediglich in den Acknowledgements erwähnter Leif Ristroph unabhängig von der ersten durchgeführt, dramatischerweise im Courant-Institut, grob als „Angewandte Mathe“ zu klassifizieren, unangenehm nah an dem, wofür ich bezahlt werde.

    „Drei kamen durch“ ist kein Rezept für gute Wissenschaft

    Diese beiden haben also vierzehn Libellen in New York City gefangen und elf weitere von KollegInnen bekommen. Und jetzt (aus dem Supplementary PDF):

    Beim Bemalen der Augen und Ocellen ist es wichtig, einen feinen Pinsel zu verwenden, damit keine Farbe auf den Hals oder Mund [des Tieres] tropft.

    Aus dieser Sammlung von Libellen haben drei die vollständigen Experimente überlebt, zwei der Gattung Perithemis tenera, eine der Gattung Libellula lydia. Dies umfasste die Tests mit normalem Sehsinn und mit blockierten Sehsinnen. Alle waren präzise [? Original: rigorous] Flieger. Mit funktionierendem Sehsinn rollten sie nach rechts. Sie überlebten auch mindestens zwei Kältephasen im Kühlschrank, eine vor dem Ankleben des Magnets, eine weitere vor dem Bemalen der Augen.

    Nennt mich angesichts dessen, was wir täglich 108-fach mit Hühnern, Schweinen, Rindern und Schafen machen, sentimental, aber wenn ein Protokoll von 25 Tieren 22 tötet, bevor das Experiment fertig ist, ist es nicht nur roh, sondern fast sicher auch Mist. Es ist praktisch unvorstellbar, dass bei so einer Selektion nicht dramatische Auswahleffekte auftreten, die jedes Ergebnis mit Fragezeichen in 72 pt Extra Bold, blinkend und rot, versehen.

    In diesem Fall war das Ergebnis übrigens, dass die Libellen ohne Ocelli etwa 30% später mit dem Drehen anfingen und anschließend nicht mehr ins Gleichgewicht kamen, bevor die Kamera voll war (ich hätte es trotzdem nett gefunden, wenn Wang wenigstens anekdotisch berichten würde, ob sie es am Schluss geschafft haben). Mit zugepinselten Facettenaugen sind die Libellen ins Gleichgewicht gekommen, wenn auch langsamer und weniger kontrolliert. Waren Ocellen und Facettenaugen blockiert, sind die Libellen häufig einfach nur runtergefallen „like leaves“.

    Was aber, wenn – ja vielleicht im Einzelfall doch existierende – nichtoptische Gleichgewichtsorgane Libellen anfälliger dafür macht, die Torturen des Experiments nicht zu überleben? Was, wenn auch die überlebenden Libellen anfangs ein nichtoptisches Gleichgewichtsorgan hatten, das aber durchs Einfrieren oder eine andere überwiegend tödliche Prozedur kaputt gegangen ist?

    Hätte ich das Vorhaben ethisch begutachten müssen, wäre ich vermutlich eingestiegen auf Abschnitt 2.3 der ergänzenden Materialien (wenn etwas in der Art im Antrag gewesen wäre), in dem es heißt, „Dragonflies perform mid-air righting maneuvers often during their prey-capture maneuvers”.

    Also… wenn die solche Manöver auch freiwillig fliegen, wäre es dann nicht besser gewesen, sie in solchen Situationen zu filmen? Klar, das wäre dann wahrscheinlich fies den Ködern gegenüber, die mensch ziemlich sicher fest positionieren (und damit ihrerseits festkleben) müsste, damit das mit dem Hochgeschwindigkeitsfilmen klappt. Aber trotzdem: Für mich wäre das das mildere Mittel gewesen.

    Außerdem hätten die Köder ja Mücken sein können.

    Nachtrag (2022-07-11)

    Meine Sorgen über ethisch grenzwertige bis unhaltbare Experimente mit Insekten liegen offenbar im wissenschaftlichen Trend. Am 10. Juli haben die Science Alerts einen Beitrag über die Schmerzwahrnehmung von Insekten veröffentlicht, der einige weitere beunruhigende Experimente anführt (etwa zu Phantomschmerzen bei Drosophilen). Immer mehr sieht es aber so aus, als fände bei vielen Insekten durchaus Schmerzverarbeitung statt, auch wenn diese im Detail etwas anders funktioniert als bei uns.

    [1]

    Das Genre „Wir drehen Tiere auf den Rücken und lassen sie fallen“ ist ausweislich des Papers beeindruckend fruchtbar. Zumindest heißt es …

  • Ach Bahn, Teil 7: Endlich ehrlich

    Mindestens seit letztem September bezahlt die Bahn das Unternehmen hcaptcha dafür, ihre KundInnen nach einer mysteriösen Systematik beim Einloggen recht regelmäßig mit minder unterhaltsamen Spielen zu belästigen: Fahrräder, Wasserflugzeuge, Busse anklicken, bis entweder die „KI“ von hcaptcha oder der/die geneigte BahnkundIn die Geduld verlieren. Gleichzeitig ging auch der Eingeloggt-bleiben-Mechanismus der Bahn-Webseite kaputt – jedenfalls verlangt sie seitdem bei jeder Buchung ein neues Login –, und so durfte ich bei im Schnitt zwei von drei Kartenkäufen stupide auf Bilder klicken. Wäre das ein Tierversuch, würde ich die Ethikkommission einschalten.

    Ich habe hier schon im letzten Oktober über diesen Mist gejammert und angemerkt, dass eine Anfrage, ob das so sein soll und wann es repariert wird, seit zwei Wochen unbearbeitet bei der Bahn lag. Seitdem habe ich immer mal wieder bei der Bahn nachgefragt und habe auch zwei oder drei Mal „Abgabeinformationen“ bekommen, die in etwa so aussahen:

    webkit-box-shadow: 0px 4px 8px #828282; /*webkit browser */-moz-box-shadow:
    0px 4px 8px #828282; /*firefox */box-shadow: 0px 4px 8px
    [... ~100 Zeilen so weiter]
    .NormaleTabelle-C{vertical-align:top;}
    .TableNormal-C{vertical-align:top;} Ihre Nachricht vom: 22. Oktober
    2021Unser Zeichen: 1-XXXXXXXXXXXX Sehr geehrter XXXXXXXXXXXXXXXXXXX,
    vielen Dank für Ihre E-Mail.  Den geschilderten Sachverhalt haben wir
    sorgfältig durchgesehen. Damit Ihr Anliegen umfassend bearbeitet und
    beantwortet wird, haben wir Ihr Schreiben heute an die zuständige
    Abteilung weitergegeben.Wir bitten Sie um Geduld und freuen uns, wenn
    Ihr Anliegen von der Fachabteilung zu Ihrer Zufriedenheit beantwortet
    werden kann.  Mit freundlichen Grüßen Ihr Team vom Kundendialog
    

    (die vergurkte Formatierung in der text/plain-Alternative der Bahn-Antworten hatte ich schon vor Monaten an die Bahn berichtet und im April etwas ausführlicher diskutiert; repariert ist natürlich nichts). Nennt mich naiv: Ich hatte wirklich ein wenig Hoffnung, dass die „Fachabteilung“ irgendwas schreibt wie „es gibt da App-Schurken, die dasunddas tun, und wir wissen uns gerade nicht anders zu helfen als mit Captchas“ oder irgendwas dergleichen.

    Das ist natürlich nicht passiert. Aber irgendeine nicht völlig inhaltsleere Antwort hätte ich schon gerne gehabt, und so habe ich trotz der Bitte um Geduld doch noch ein, zwei Mal geschrieben, wenn ich mal wieder irgendwelche Verkehrsmittel abklicken musste, damit die Bahn mir erlaubte, ihr Geld zu geben.

    Zuletzt habe ich am 24.6. Folgendes geschrieben:

    > versichern Ihnen, dass jedes Anliegen bearbeitet wird und bitten
    > Sie noch um ein wenig Geduld.  Sie erhalten eine Antwort, sobald
    > Ihr Antrag geprüft wurde.
    
    Hm... Bei drei Buchungen der letzten Zeit hatte ich wieder zwei Mal
    ein Captcha zu lösen (heute: Fahrräder).  Insbesondere hatte ich mich
    auch jedes Mal wieder neu einzuloggen.
    
    Zumindest eine Aussage darüber, ob das beabsichtigtes Verhalten ist
    oder ein Fehler wäre, finde ich, in den 10 Monaten seit meiner ersten
    Anfrage schon drin gewesen, oder?  *Soo* katastrophal kann doch das
    Anfragevolumen gar nicht sein, dass auf dieser Zeitskala niemand
    entscheiden kann, ob sich das so gehört oder ob es sich für mich
    lohnt, auf Fehlersuche zu gehen.
    
    > Link. P.S.: Für Ihre Anregungen, Lob und Kritik sind wir jederzeit
    > gern unter 030 2970 für Sie da. Sie erreichen uns rund um die Uhr
    
    Hmja... das hatte ich auch mal versucht, und die arme Mitarbeiterin
    konnte nichts tun außer mir anzubieten, mir die Nutzung einer App zu
    erklären, was beim vorliegenden Problem nun auch nur eingeschränkt
    nützlich war.
    

    Ich finde, nach Lage der Dinge ist das eine vertretbar freundliche und durchaus vernünftig formulierte Anfrage samt dem Angebot, ihre Javascript-Wüste zu debuggen, wenn das bereits vorher beschriebene Verhalten nicht beabsichtigt sein sollte.

    Was soll ich sagen? Das Ergebnis war die, so glaube ich, erste halbwegs ehrliche Antwort der Bahn, unter dem Betreff „Ihre Erfahrung mit der Deutschen Bahn“:

    -webkit-box-shadow: 0px 4px 8px #828282; /*webkit browser
    */-moz-box-shadow: 0px 4px 8px #828282; /*firefox */box-shadow: 0px
    [... >100 Zeilen so weiter wie gehabt...]
    .NormaleTabelle-C{vertical-align:top;} Ihre Nachricht vom: 24. Juni
    2022Unser Zeichen: XXXXXXXXXXXXXX Sehr geehrter XXXXXXXXXXXXXXXXXXX,
     herzlichen Dank für Ihr Schreiben vom 24. Juni 2022. Sie haben sich
    die Zeit genommen, uns von Ihren Beobachtungen und Erlebnissen zu
    berichten. Ihre Unzufriedenheit können wir gut nachempfinden. Wir
    bedauern, dass das Erlebte keinen guten Eindruck bei Ihnen
    hinterlassen hat. Unser Anspruch ist es, unsere Leistungen stetig zu
    verbessern.  Alle Mitarbeiterinnen und Mitarbeiter arbeiten täglich
    daran, die Qualität und den Service auszubauen, die Verlässlichkeit
    sicherzustellen und die Verfügbarkeit und Aktualität von Informationen
    zu optimieren. Gerne stehen wir Ihnen für Ihre Fragen, Ihr Lob und
    Ihre Kritik zur Verfügung. Wir bitten Sie jedoch um Verständnis, dass
    wir von weiteren Stellungnahmen zu diesem Thema absehen. Für alle
    Anliegen zu anderen Themen stehen wir selbstverständlich zur
    Verfügung. Mit freundlichen Grüßen Ihr Team vom Kundendialog
    

    Zwar ist das erkennbar auch nur aus vorgefertigten Phrasen zusammengeklickter Nonsens, aber immerhin: sie geben ehrlich zu, dass sie „von weiteren Stellungnahmen zu diesem Thema“ absehen werden. Nun würde ich das „weiteren“ in der Formulierung bestreiten, und ich bleibe dabei, dass das für Leute, denen ich einige tausend Euro im Jahr gebe, eine etwas überarrogante Haltung ist. Ich möchte auch darauf bestehen, dass es wirklich nicht zu viel verlangt ist, von Captchas verschont werden zu wollen. Aber es ist viel besser als „Abgabeinformationen“ zu verschicken, die nie Konsequenzen haben – und bei denen das auch keineR erwartet.

    Tja, dann also hier in die Runde: Weiß jemand, ob es Absicht ist, dass mensch auf der Bahn-Webseite vor einer Buchung ausgeloggt wird? Und weiß wer, wie mensch die Chancen in hcaptchas Lotterie verbessert, ums Verkehrsmittelklicken herumzukommen?

  • Kopfzahlen: Über Grenzregimes

    Dann und wann können Kopfzahlen ziemlich bedrückend sein. So die 50000 Toten (genauer: 48647), die die, na ja, NGO UNITED for Intercultural Action in ihrer Liste der der Opfer der Festung Europa aus den Jahren zwischen 1993 und 2022 bestimmt. Das sind nur die gut dokumentierten Fälle, und da die in die EU Einwandernden vor allem im Mittelmeer und in den Weiten des Ostens sterben, dürften zu ihnen zahlreiche undokumentierte Tote kommen. Nimmt mensch sehr konservativ eine Dunkelziffer in der Größenordnung der dokumentierten Toten an und teilt durch die 30 Jahre, ergiben sich etwas wie 3000 Tote pro Jahr in direkter Folge der EU-Migrationskontrolle.

    Zum Vergleich: an der Berliner Mauer starben, Unfälle, Grenzsoldaten und Herzinfrakte eingeschlossen, zwischen 1961 und 1989 ungefähr 400 Menschen (vgl. Wikipedia-Artikel Mauertote). In dem Sinn könnte mensch sagen, dass das EU-Grenzregime jedes Jahr so viele Menschen umbringt wie sechs Berliner Mauern während ihrer ganzen Betriebsdauer.

  • Konferenzplattformen-Shaming

    In meinem Job hatte ich über die letzten Jahre reichlich Gelegenheit, mich über verschiedene Konferenzplattformen zu ärgern – und dabei gibt es weit Schlimmeres als indico, das dank CERN die meisten Konferenzen in meiner fachlichen Umgebung organisiert und auch schon reichlich Gelegenheit zum Kopfschütteln gibt. Jetzt gerade muss ich mich mit einer „Plattform“ auseinandersetzen, die mühelos den Klick-mich-weg-Preis für die grottigste Software ihrer Klasse abräumt: whova.com

    Das fängt dort an, wo die Tagesordnungs-Links nicht etwa auf das Programm der jeweiligen Session führen, sondern blind zu einem eingebetteten Zoom-Widget und hört noch lange nicht auf, wo die ProgrammiererInnen viel Mühe darauf verwenden, dass NutzerInnen die Zoom-Raumkennung nicht rauskriegen und so sowohl den proprietären Zoom-Scheiß und die murksigen Browser-Medien (im Gegensatz zum immerhin halbwegs ordentlich funktionierenden nativen Client) haben. Das Schlechteste aus allen Welten.

    Aber über sowas kann ich mich normalerweise nicht mehr aufregen[1]. Zur Tastatur greifen musste ich erst, als ich unvorsichtigerweise dem „Leaderboard“-Link in der Sidebar der Plattform folgte. Dabei zeigte sich folgendes:

    Screenshot eines Browserfensters: Eine Rangliste mit 308900, 211900 und 23400 Punkten an den ersten drei Plätzen.

    Ich habe ein wenig anonymisierend eingegriffen, weil ich Konferenzplattformen, aber keine Konferenzen oder Personen shamen will.

    Ich wollte meinen Augen nicht trauen: Diese Plattform will die TeilnehmerInnen mit albernen „Challenges“ und künstlichen Wettbewerben steuern? Nur der Klarheit halber: Das ist eine Konferenz mit lauter MoverInnen und ShakerInnen aus dem Wissenschaftsbetrieb, die endlos „Strategien“, „Nachhaltigkeit“ und, görks, „Innovation“ durchquirlen können. Solche Leute sollen wegen Fleißbienchen ihr Verhalten ändern? Tun die das am Ende gar?

    Wenn ich das richtig verstanden habe, werden folgende Dinge belohnt:

    • Add a topic or social group (20000 Punkte)
    • Suggest meet-ups (20000 Punkte)
    • Post a question in Session Q&A (10000 Punkte)
    • Recommend a conference (6000 Punkte)
    • Post a reply (500+ Punkte – wer entscheidet über das „+“?)
    • Share an article (500+ – und was ist, wenn die Urherberrechtspolizei kommt?)
    • Join a meet-up or share a ride (? Punkte)
    • Add 3 sessions to personal agenda (300 Punkte)
    • Beef up your profile (300 Punkte)
    • Say hi to someone in the attendee list (300 Punkte)
    • Post an Ice Breaker in the community board (? Punkte)

    „Hallo sagen“? Und das wird dann belohnt? Ich will mal hoffen, dass diese whova.com-Leute weit außerhalb der DSGVO-Jurisdiktion sitzen, denn mit welchem Buchstaben von Artikel 6 (1) sich so eine Datenverarbeitung begründen ließe, könnte ich mir auch mit starken bewusstseinserweiternden Substanzen nicht vorstellen. Und: Hat wirklich eine reale Person auf die „Congratulate“-Links geklickt? Wenn ja: Was ging derweil in deren Gehirnen vor? „Es könnte ja auch meine zweijährige Tochter sein, und mit meinem Lob verbessere ich ihren Wettbewerbswillen“?

    So entsetzt ich insgesamt über diesen Großangriff auf Menschenwürde und Vernunft bin, eine Frage drängt sich mir schon auf: Wenn die beiden „Leader“ jeweils zehn Mal mehr Punkte haben als die Person auf Platz drei: Sind das Beschäftigte, deren Job es ist, auf dieser Zumutung aus dem Webbrowser rumzuklicken? Oder sind es Leute, die ihren Computern beigebracht haben, Fleißbienchen für sie zu erklicken? Wenn Letzteres: Ist das stummer Protest oder demonstrative Selbstaufgabe?

    [1]Wobei: Ich habe ja nicht viel mit Jira zu tun, aber doch genug, um die Testimonials auf https://ifuckinghatejira.com/ mit grimmer Befriedigung zu lesen. Ganz so entspannt im Hinblick auf nervige proprietäre Software wie ich gerne wäre bin ich also doch nicht.
  • Darf mensch Königinnen aufeinander hetzen?

    Nicht in meiner DLF-Lieblingssendung Forschung aktuell, sondern im Freistil vom 5.6.2022 bin ich auf den nächsten Fall meiner kleinen Sammlung von Fragen an die Ethikkommission bei Tierversuchen gestoßen. Im Groben: Ist es ok, Tiere bewusst und absichtlich gegeneinander kämpfen zu lassen? Und gibt es im Hinblick auf diese Frage Unterschiede zwischen Stieren und Regenwürmern?

    Aus meiner Sicht nicht weit von der Mitte der Wurm-Rind-Skala entfernt befinden sich die Papierwespen, für die die deutsche Wikipedia enttäuschenderweise auf die ordinäre Wespenseite weiterleitet. Speziell für die Stars dieses Posts, Polistes fuscatus – die biologische Normenklatur könnte mich der Physik abspenstig machen – gibt es immerhin einen Link auf der Feldwespen-Seite, doch hat sich noch niemand gefunden, der/die die zugehörige Seite angefangen hätte.

    Portraits von vier Wespen

    Fast noch spannender als die Frage, ob Wespen die Gesichtszeichnungen von Individuen auseinanderhalten können, finde ich ja die Frage, ob sie auch mal gut gelaunt aussehen können. Bildrechte: doi:10.1016/j.cub.2008.07.032 (bearbeitet).

    Bei Freistil klang es nun so, als habe jemand jeweils zwei Königinnen dieser Wespen miteinander bekannt gemacht; dass sie sich erkennen können, und zwar ziemlich sicher am Gesicht, ist offenbar spätestens seit den Arbeiten von Michael Sheehan und Elizabeth Tibbetts wohlbekannt. Unter den einschlägigen Artikeln, die ab den 2000er Jahren an der Uni von Michigan in Ann Arbor entstanden sind, ist viel zitiert „Specialized Face Learning Is Associated with Individual Recognition in Paper Wasps“ (viel zitiert vermutlich weil: Science 334 (2011), 1272, doi:10.1126/science.1211334). Das darin beschriebene Experiment ist erkennbar nicht das, von dem im Freistil die Rede war, wirft aber selbst eine ethische Frage auf:

    Darf mensch Königinnen elektroschocken?

    Sheehan und Tibbet gaben den Wespen nämlich eine T-förmige Flugzone, die überall Elektroschocks verabreichte, bis auf eine Stelle, die dann mit einem von einem paar von Bildern markiert war. Mithin war der Reiz, den die Leute zum Training der Wespen nutzten, die Abwesenheit von Elektroschocks, wenn es die Wespen richtig machten. Hm. Hrrmmmmmmmm! Wäre das nicht auch etwas freundlicher gegangen?

    Ausgangspunkt der Arbeit war die Vermutung, dass fuscatus-Wespen, die staatenbildend sind und deren Königinnen sich vor Gründung ihres Staates mit einem ganzen Haufen anderer Wespen raufen, zwei verschiedene Wespengesichter besser auseinanderhalten können („habe ich gegen die schon mal verloren?“) als metricus-Wespen, die meist allein leben und sich wenig prügeln. Um ein wenig sicherer zu sein bei der Frage, was da eigentlich beobachtet wird, haben Sheehan und Tibbetts auch Versuchstiere („healthy wild-caught adult female[s]“) auf Raupen (die die Wespen gerne essen), geometrische Zeichen (Kreuze, Dreiecke und sowas) und Wespenköpfe ohne Antennen trainiert.

    Das Ergebnis: Wespengesichter mit Antennen haben ausgelernte fuscatus-Wespen in 80% der Fälle vorm Elektroschock bewahrt (wobei der Nulleffekt 50% wäre), und sie haben die Gesichter schneller gelernt als die an sich viel einfacheren Zeichen. Waren die Antennen rausretuschiert, hat das Lernen länger gedauert, und bei 70% richtiger Wahl war Schluss.

    Wie viel Ausdauer braucht es für 10'000 Versuchsläufe?

    Und von wegen „Erst kommt das Fressen, dann kommt die Moral“: Wenn der Hinweis aus verschiedenen Raupensorten bestand, haben die Wespen nur in 60% der Fälle die trainierte Raupe gefunden, also fast nicht häufiger als durch Zufall zu erwarten. Und etwa genauso gut wie die einsiedlerischen metricus-Wespen, die mit den Gesichtern ihrer Artgenossinnen gar nichts anfangen konnten.

    Fleißbienchen am Rande: grob überschlagen müssen Sheehan und Tebitt die Wespen gegen 10'000 Mal haben fliegen lassen. Ich mag mir gar nicht vorstellen, wie viel Ausdauer es dafür gebraucht haben mag. Auf beiden Seiten. Aufgrund vorheriger Interaktionen mit Wespen vermute ich jedoch fast, dass für diese der repetetive Charakter der Unternehmung weniger problematisch gewesen sein dürfte. Ach ja, und ich würde gerne wissen, wie viele Stiche sich die beiden Menschen während der Arbeiten eingefangen haben.

    Wie ist es mit Kämpfen?

    Sheehan, der inzwischen an die Cornell-Universität in New York gewechselt ist, hatte schon zuvor (und hat noch weiter) mit den Wespen gearbeitet und berichtet darüber zum Beispiel in Current Biology 18 (2008), Nr. 18, R851 (doi:10.1016/j.cub.2008.07.032), „Robust long-term social memories in a paper wasp“. Für diese Studie haben die Leute ebenfalls einen Haufen fuscatus-Papierwespen gefangen, dieses Mal aber gezielt Begegnungen herbeigeführt. Dabei haben sie an Tag 0, 6 und 8 jeweils Wespen zusammengeführt, die sich nicht kannten, am siebten Tag dagegen nochmal die von Tag 0 vorbeigeschickt. Das fand ich schon mal ein recht cleveres Design: Wenn sich die Rauflustigkeit der Wespen generell geändert hätte, wäre das durch die Kontrollen an den Tagen sechs und acht aufgefallen.

    Aber das führt auf die Eingangsfrage: Ist diese Sorte Experiment nicht ziemlich eng verwandt mit Hahnenkämpfen, bei denen zwei Tiere, die, wären sie nicht in menschlicher Gefangenschaft, vermutlich friedlich vor sich hingelebt hätten, künstlich dazu gebracht werden, aufeinander einzuhacken? Wäre ich in einer Ethikkommission, müsste ich zumindest mal etwas nachdenken, ob ich Königinnenkämpfe eigentlich absegnen möchte, auch wenn es hier nicht um das Gaudium einer blutrünstigen Menge, sondern um die Förderung der Wissenschaft geht.

    Unter Bekannten doppelt so viele Begegnungen ohne Gewalt

    Immerhin scheinen die Kämpfe der Wespen relativ zivilisiert abzulaufen. Zumindest berichten Sheehan et al nicht davon, dass die Begegnungen an Tag 7 mal hätten ausfallen müssen, weil die Besucherinnen von Tag 0 inzwischen vielleicht totgestochen worden wären (Disclaimer: ich habe die Zusatzdaten nicht auf solche Vorkommnisse hin durchgesehen, denn ich war ja eigentlich auf der Suche nach etwas anderem).

    Das Ergebnis ist wieder recht beeindruckend; kannte sich ein Wespenpaar, gingen offenbar doppelt so viele Begegnungen ohne Gewalt aus wie andernfalls.

    Meine eingestandenermaßen oberflächliche Literaturrecherche hat aber leider kein Paper geliefert, bei dem jemand Wespen geschminkt hätte; ich hatte ich die Geschichte aus dem Freistil nämlich so verstanden, dass jemand zwei Wespen bekannt gemacht hat und dann das Gesicht einer der beiden verändert, um zu prüfen, ob es wirklich das ist, an das sich die Wespen erinnern und nicht etwa, sagen wir, der Geruch oder die Melodie des Summens. Auch wenn das Elektroschockexperiment das sehr nahelegt: Ich finde es völlig plausibel, so ein Schminkexperiment zu machen. Wer die dazugehörige Studie findet: das Antwortfomular gehört völlig euch.

    Empathietraining

    Wer die ganze Sendung hört, dürfte auf ein anderes ethisches Problem stoßen, eines, das mir, der ich nicht in einer Ethikkommission sitze, deutlich mehr Sorgen macht: Im O-Ton wird eingespielt, wie jemand eine Drosophile erst mit Wachs festklebt und dann immer weiter fesselt. „Drosophile“: Ihr merkt, ich habe rein emotional ein spezielles Verhaltnis zu Fruchtfliegen, weil ich in ihnen, die wie ich Obst nicht widerstehen können – je süßer, je besser – ganz entfernt Geistesverwandte sehe.

    Andererseits: Wenn ich den Kompostmüll leere, nehme ich, ehrlich gesagt, keine Rücksicht darauf, wie viele von ihnen ich dabei wohl zerquetsche. Die insgesamt vergleichbar menschenähnlichen Mücken und Zecken töte ich sogar gezielt, wenn ich kann. Und nun habe ich diesen Bericht gehört und musste mich sehr beherrschen, um mich nicht zu empören. Das mag ein wenig zu tun haben mit dem völlig überflüssigen Gag, Enrico Caruso durch das Drosophilenohr aufzunehmen, denn Folter[1] ist nochmal schlimmer, wenn irgendeine Sorte, ach ja, „Humor“ mitschwingt.

    Aber auch ohne das: Ist es verlogen, wenn ich mich über die Misshandlung von Lebewesen empöre, die ich andererseits ohne große Reue und ganz nebenbei – oder gar gezielt – töte?. Auf der anderen Seite will mensch, so glaube ich, diese Anflüge von Empathie auch nicht wirklich bekämpfen. Die Charakterisierung der Feinde als Ratten und Schmeißfliegen (der Namenspate des Münchner Flughafens, Franz Josef Strauß, war Meister dieses Genres), als Tiere also, mit denen Empathie zu haben wirklich schwerfällt, wenn sie sich erstmal ordentlich vermehrt haben, ist ein recht konstantes Feature so gut wie aller Kriege und anderer Massenmorde der Geschichte.

    Mit diesem Gedanken bin ich nach der Freistil-Sendung auf folgendes Fazit gekommen: Selbst wenn es nicht der Tiere selbst wegen geboten sein sollte, schon ganz speziezistische Humanität gebietet es, diese Sorte von Mitleid mit jeder Kreatur zu hegen und nicht zu kritisieren. Und vor den Feldzügen gegen die Nacktschnecken wenigstens noch ein wenig mit sich zu ringen.

    [1]Ja, ich behaupte, es ist Folter, wenn mensch so ein Lebewesen bei lebendigem Leibe immer weiter eingießt, bis es (nehme ich an) erstickt, weil die Tracheen alle dicht sind.
  • Zum Glück ist das nicht Hollywood

    Die ziemlich hörenswerte Miniserie über Pilze und Menschen in der Deutschlandfunk-Sendung Wissenschaft im Brennpunkt (Teil 1, Teil 2) endet mit folgenden Worten von (ich glaube) Oliver Kurzai von der Uni Würzburg:

    Deswegen müssen wir glaub ich nicht damit rechnen, dass wir in absehbarer Zeit tasächlich, ich sag mal, eine Killerpilz-Pandemie kriegen, die auch den normalen, gesunden Menschen bedroht.

    Wenn unsere Realität irgendeine Ähnlichkeit hat mit einem zünftigen Katastrophenfilm, wisst ihr, was als Nächstes passieren wird.

  • (Un)verstandene Infektionsdynamik

    Ich habe vorhin einen Beitrag zu den Wirkungen nicht-pharmazeutischer Maßnahmen gehört, der in der Deutschlandfunk-Sendung Forschung aktuell am dritten Juni lief. Darin hieß es:

    Vielleicht sind die vielen Einflussfaktoren ein Grund, warum auf diesem Gebiet überhaupt wenig geforscht wird. Die Bessi-Collaboration zur Erforschung sozialer, Umwelt- und Verhaltens-Pandemiemaßnahmen zählt aktuell nur 18 veröffentlichte Studien aus diesem Bereich, aber 974 zu Impfstoffen oder Medikamenten.

    Das hat mich daran erinnert, dass ich spätestens seit Oktober 2021 eine ziemlich grundsätzliche Lücke bei unserem Verständnis der Epidemiologie von SARS-2 gewittert habe, und zwar ganz unabhängig von meinen misslungenen Vorhersagen im letzten Herbst. Ich habe nämlich bis genau heute aufgrund von, Fanfare, Unabhängigkeitsargumenten für sehr unplausibel gehalten, dass sich die Varianten gegenseitig verdrängen. Lasst mich spoilern: Mein Instinkt, dass da was nicht stimmen kann, war falsch, Mensch soll einfach nie die Exponentialfunktion unterschätzen.

    Aber langsam. Zunächst habe mir die R-Wert-Schätzungen des RKI vorgenommen. Zur Erinnerung: Der R-Wert soll sagen, wie viele Leute einE InfizierteR zu einer bestimmten Zeit im Mittel ansteckt; ist er konstant größer als eins, wächst die Inzidenz exponentiell, ist er konstant kleiner als eins, schrumpft sie exponentiell.

    Ich möchte auf der Basis der R-Werte den Pandemieverlauf nacherzählen, um der Variantenverdrängung auf die Spur zu kommen. Dabei nutze dabei die Kurvenfarbe als Indikator für die geschätzte Inzidenz – beachtet, dass sowohl die Skalen auf dieser Hilfsachse als auch auf der Ordinate von Bild zu Bild drastisch verschieden sind.

    Plausibler Anfang

    Dabei habe ich mir nacheinander ein paar Phasen vorgenommen. Von März bis Juli 2020 konnte mich mir alles prima zusammenreimen:

    Kurve mit einem Peak von über drei, die dann Richtung eins abfällt.

    Fig 1: R-Werte der ersten Welle

    Die unkontrollierte Infektion lief anfangs mit dem geschätzten R0 (also: wie groß ist das R ganz ohne Maßnahmen und Immunität?) der Wuhan-Variante (im Winter etwas wie 3) los, dann griffen die Maßnahmen, und wie sie nacheinander so griffen, fiel auch der R-Wert.

    Ich war damals mit dieser Interpretation soweit glücklich, auch wenn Leute immer mal wieder an den Zeitskalen rumgemäkelt haben: Reagiert das nicht schon vor den Maßnahmen? Hätte das nicht schneller auf Schul- und Betriebsschließungen reagieren müssen? Zu letzterem Punkt zumindest ist einzuwenden, dass es einerseits zwei, drei Wochen gedauert hat, bis die Leute wirklich im Coronamodus waren. Andererseits sind für die Mehrzahl der Fälle auch nur Melde-, nicht aber Infektionszeitpunkte bekannt. Da diese ohne Weiteres um ein oder zwei Wochen auseinanderliegen können, wäre selbst eine scharfe Stufe in R in den RKI-Schätzungen weich ausgeschmiert; ein weiteres Beispiel übrigens für die Gefahren von Big Data.

    Ein merkwürdiger Balanceakt

    Gegen Ende des ersten Coronasommers kam mir aber schon komisch vor, wie sehr sich das effektive R immer ziemlich genau um die Eins herum hielt. Bei sowas Kitzligem wie einem Infektionsprozess, der davon lebt, dass sich immer mal wieder ein ganzer Haufen Leute ansteckt, ist es alles andere als einfach, diese Sorte von Gleichgewicht (es stecken sich in jeder Zeiteinheit ungefähr genauso viele Leute an wie gesund werden) zu halten – die Überdispersion der Wuhan-Variante soll was wie 0.1 gewesen sein, so dass vermutlich überhaupt nur ein oder zwei von zehn Infizierten zur Ausbreitung der Krankheit beitrugen (dann aber auch gleich richtig, also mit mehreren Angesteckten).

    Unter diesen Umständen einen R-Wert von um die eins zu haben, ist ein Balanceakt ganz ähnlich der Steuerung eines AKW (das zudem nicht mit der Überdispersion zu kämpfen hat): mach ein bisschen zu wenig und die Infektion stirbt rapide aus (der Reaktor wird kalt); mach ein bisschen zu viel und du bist gleich wieder bei enormen Zahlen (der Reaktor geht durch). Dennoch hat sich der R-Wert (abgesehen vom Tönnies-Zacken Mitte Juni, der ganz gut demonstriert, was ich mit „kitzlig“ meine) im Sommer doch recht gut rund um 1 bewegt:

    Kurve, die um Eins rumzittert

    Fig 2: R-Werte im Sommer 2022

    Was hat R so (relativ) fein geregelt? Sind die Leute in Zeiten ansteigender R-Werte wirklich vorsichtiger geworden? Und waren sie unvorsichtiger, wenn die R-Werte niedrig waren? Erschwerend im Hinblick auf so eine Regelung kamen zumindest im Juli und August nennenswert viele Infektionen nicht durch Reproduktion im Land zustande, sondern kamen mit Rückreisenden aus Gegenden mit höheren Inzidenzen. Wie das genau lief, ist aber wieder schwierig zu quantifizieren.

    Mein erstes kleines Rätsel wäre also, warum die Inzidenz im Sommer 2020 über ein paar Monate hinweg im Wesentlichen konstant war. Im Herbst 2020 schien mir das eher wie eine Anekdote, zumal es recht erwartbar weiterging:

    Kurve mit einigen Peaks

    Fig 3: R-Werte der zweiten und dritten Wellen

    Die hohen R-Werte im Oktober sind überaus zwanglos durch Schulen, Betriebe und ganz kurz auch Unis mit allenfalls lockeren Maßnahmen bei lausig werdendem Wetter zu erklären. Der Abfall zum November hin wäre dann der „Lockdown Light“. Wieder mag mensch sich fragen, warum der Abstieg schon Mitte Oktober einsetzte, während der Lockdown Light ja erst Anfang November in Kraft trat, aber seis drum. Der nächste Buckel, hier schon in rot, weil mit für damalige Zeiten enormen Inzidenzen einhergehend, dürfte ganz grob Weihnachtsmärkte (Aufstieg) und deren Schließung (Abstieg; ok, es hat auch noch einige weitere Lockdown-Verstärkungen gegeben) im Dezember 2020 reflektieren.

    Verdrängt oder nicht verdrängt?

    Dass bei gleichbleibenden Maßnahmen der R-Wert ab Mitte Februar stieg, habe auch ich mir damals dadurch erklärt, dass die Alpha-Variante infektöser ist. Richtig schöne Grafiken dazu gibt es erst später, so etwa hier aus dem RKI-Wochenbericht vom 7.10 (der gerade nicht im RKI-Archiv zu finden ist):

    Farbig markierte Anteile verschiedener SARS-2-Varianten, die sich offenbar verdrängen

    Fig 4: Anteile der verschiedenen Varianten vom Oktober 2021 (Rechte: RKI)

    Während der, sagen wir, ersten 13 Kalenderwochen des Jahres 2021 hat also Alpha den Wuhan-Typ im Wesentlichen kompett, nun ja, verdrängt. Und das schien mir bis jezt sehr unplausibel. Anschaulich gesprochen nämlich kann Alpha den Wuhan-Typ nur dann verdrängen, wenn die Varianten „sich sehen“, also überhaupt nennenswert viele Menschen, die der Wuhan-Typ infizieren möchte, schon zuvor Alpha gehabt hätten[1].

    Das war im Frühling 2021 ganz klar nicht so. Der RKI-Bericht vom 16.4.2021 (in dem sich übrigens auch die damaligen Gedanken zu den Varianten spiegeln) spricht von rund 3 Millionen Infizierten. Plausible Dunkelziffern werden den Anteil der bereits mit SARS-2 (in der Regel noch nicht mal Alpha) Infizierten kaum über 10% heben. Die Wuhan-Variante kann also im Wesentlichen nichts von Alpha gesehen haben, und damit kann sie auch nicht verdrängt worden sein[2].

    Mit einem zweiten Blick stellt sich heraus, dass es das auch nicht brauchte, denn unter den recht drakonischen Maßnahmen vom Januar 2021 – wir reden hier von der Zeit nächtlicher Ausgangssperren – hatte der Wuhan-Typ so in etwa einen R-Wert von 0.9 (das lese ich jedenfalls aus Fig. 3). Nun rechnet(e) das RKI den R-Wert in etwa so, dass er das Verhältnis der Infektionen in einem Viertageszeitraum zum vorherigen Viertageszeitraum angibt; der Gedanke ist, dass es (die „Serienlänge”) von einer Infektion bis zur Ansteckung in der nächsten Generation bei SARS-2-Wuhan sowas wie eben die vier Tage dauern sollte[3].

    Unter der angesichts konstanter Maßnahmen wenigstens plausiblen Annahme eines konstanten R-Werts (gegen Ende des Zeitraums mag er wegen Wetter sogar noch weiter gefallen sein), kann mensch ausrechnen, dass nach 13 Wochen vom Wuhan-Typ nur noch

    0.913⋅7 ⁄ 4 ≈ 10%

    übrig waren, und weil bei hinreichend niedrigen Inzidenzen der Bestand eines im Wesentlichen ausbruchsgetriebenen Erregers wie der Wuhan-Variante eh schon prekär ist: Eigentlich reicht das schon, um das praktische Verschwinden der Wuhan-Variante ganz ohne Verdrängung durch Alpha zu erklären.

    Zero Covid vs. die vierte Welle

    Wenn das die Erklärung ist, wäre das in gewisser Weise eine gute Nachricht für die Zero Covid-Fraktion: Wir haben Corona schon mal ausgerottet, inzwischen sogar drei Mal, nämlich den Wuhan-Typ, Alpha und (wahrscheinlich) Delta. Die „Maßnahmen“ für die jeweils infektiösere Variante haben offenbar ausgereicht, ihre Vorgänger (praktisch) vollständig auszurotten. Damit wäre zwar immer noch nicht das Langfrist-Problem gelöst – denn global wird SARS-2 sicher nicht verschwinden –, so dass ich nach wie vor eifrig gegen Zero Covid argumentieren würde, aber ein lokales Ende von Corona haben wir offenbar schon mehrfach hinbekommen.

    Gehen wir weiter in der Zeit:

    Bunte Linie mit zwei ausgeprägten zweigipfeligen Höckern

    Fig 5: R-Werte während des Anlaufs zur vierten Welle.

    Im Anlauf zur vierten Welle wird es unübersichtlich, weil nennenswert viele Menschen geimpft waren. Es mag sein, dass der Wuhan-Typ etwas empfindlicher auf die Impfung reagiert als Alpha, so dass es vielleicht glaubhaft ist, dass der R-Wert des Wuhan-Typs nicht wieder auf das „gut 1“ aus dem Sommer 2020 zurückgeschnappt ist, nachdem die Beschränkungen aus dem Winter 20/21 nach und nach wegfielen; dann wäre zumindest klar, warum der Wuhan-Typ nicht wiederkam.

    Bei Alpha und Delta liegen die Verhältnisse wahrscheinlich komplizierter. Der Umschlag von Alpha auf Delta war noch schneller als der von Wuhan auf Alpha; abgeschätzt aus Fig. 4 vielleicht zwischen den Kalenderwochen 21 und 27. Davor, also im Juni, lag der R-Wert um 0.8, angesichts relativ entspannter Verhältnisse zu diesem Zeitpunkt vermutlich bereits eher durch Impfung als durch nichtpharamzeutische Maßnahmen bedingt. Sechs Wochen R = 0.8 bringen die Inzidenzen, immer noch unter der Annahme der Unabhängigkeit der konkurrierenden Infektionsprozesse, wiederum runter auf

    0.86⋅7 ⁄ 4 ≈ 10%

    – das Aussterben von Alpha kommt also erneut so in etwa hin, wenn …

  • Aus der Seele gesprochen

    Selten hat mir jemand so aus der Seele gesprochen wie Susanne Fischer in ihrer Glosse 9-Euro-Reporter in der taz von gestern, in der sie nach etwas Spott über die verbreitete Berichterstattung in Sachen 9-Euro-Ticket – anscheinend größtenteils geschrieben von Menschen, die schon lange keine Züge mehr von innen gesehen haben – ihre eigene Situation beschreibt:

    Der größte Mehrwert für mich ist, dass ich neuerdings in fremden Städten den ÖPNV nutzen kann, ohne vorher ein mehrstündiges Tarifstudium zu absolvieren – mit praktischer Prüfung an Automaten, deren Software vom sadistischen Andi-Scheuer-Fanclub programmiert wurde.

    Ja! Ja! Ja! Ich kann mich nicht erinnern, wann ein Satz zuletzt so in Resonanz mit meinen eigenen Gedanken stand.

  • Ach Bahn, Teil 6: Vernünftiges HTML ist möglich

    Über absurd komplexe Captive Portals in öffentlichen WLANs, die insbesondere die Ausführung von Unmengen von Javascript erfordern – was besonders kitzlig ist, da in der Situation der Accesspunkt der ultimative Man-in-the-middle ist –, habe ich mich hier schon öfter geärgert. Was wäre so verkehrt an einer einfachen HTML-Seite, die kurz die Regeln erläutert, wenns dringend sein muss, noch ein Häkchen verlangt und sich ansonsten auf <input type="submit" value="Connect"/> (für Interoperabilität; ich selbst hätte auch nichts gegen ein <button>Connect</button>) beschränkt? Nebennutzen: Sowas abzuschicken wäre leicht automatisierbar[1].

    Stellt sich heraus: Wer auch immer diesen Mist bastelt, könnte auch anders. Jetzt gerade fahre ich – zum ersten Mal mit 9-Euro-Ticket[2] – in einem S-Bahn-Zug der Bahn und bin mit einem WIFI@DB-Netz verbunden. Beim Versuch, die nötigen Beschwörungen fürs Internet zu vollführen, kam eine ganz schlichte Meldung: „We are offline“, so schlicht, dass ich mir gleich den Quelltext angucken musste, und siehe da (ich habe ein paar Leerzeilen gekürzt):

    <html lang="de"><head>
        <meta http-equiv="Cache-Control" content="no-store">
        <meta http-equiv="Cache-Control" content="no-cache">
        <meta http-equiv="Pragma" content="no-cache">
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title>SRN Startseite</title>
        <link rel="stylesheet" href="scss/styles.css">
    </head>
    <body>
    We are offline...
    </body></html>
    

    Gut: Das Übertöten bei der Cache-Kontrolle ist nicht optimal, und auch nicht, dass englischer Text als Deutsch ausgezeichnet ist; generell wäre ich zwecks einfacher Parsbarkeit auch immer für XHTML zu haben, und wenn sie schon UTF-8 als Zeichensatz haben, sollten sie aus typografischen Gründen statt ... lieber … (alias U+2026) schreiben – aber anonsten: So kann modernes HTML („modern“ wg. des dämlichen viewport-metas) auch aussehen.

    Ach so: Das stylesheet gibt natürlich ein 404, und würde ich die Kennung meiner Netzwerkkarte nicht ohnehin auswürfeln, wäre nicht amüsiert, dass die URL, unter der der Kram ausgeliefert wird, genau diese Kennung enthält, aber verglichen mit den üblichen Javascript-Wüsten wäre das wirklich ein Fortschritt. Warum gehen Captive Portals nicht immer so?

    Wobei: ganz so einfach ist das natürlich auch nicht. Zieht mensch nämlich einfach irgendeine Webseite, kommt als Request Body des Redirects auf die obige schlichte Seite sowas hier:

    <HTML><BODY><H2>Browser error!</H2>Browser does not support redirects!</BODY>
    <!--
    <?xml version="1.0" encoding="UTF-8"?>
    <WISPAccessGatewayParam
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:noNamespaceSchemaLocation="http://www.wballiance.net/wispr_2_0.xsd">
    <Redirect>
    <MessageType>100</MessageType>
    <ResponseCode>0</ResponseCode>
    <VersionHigh>2.0</VersionHigh>
    <VersionLow>1.0</VersionLow>
    <AccessProcedure>1.0</AccessProcedure>
    <AccessLocation>CDATA[[isocc=,cc=,ac=,network=HOTSPLOTS,]]</AccessLocation>
    <LocationName>CDATA[[94800463058]]</LocationName>
    <LoginURL>https://www.hotsplots.de/auth/login.php?res=wispr&amp;uamip=192.168.44.1&amp;uamport=80&amp;challenge=7e9b9ebbcbaa23dcee39cd94b42695fd</LoginURL>
    <AbortLoginURL>http://192.168.44.1:80/abort</AbortLoginURL>
    <EAPMsg>AQEABQE=</EAPMsg>
    </Redirect>
    </WISPAccessGatewayParam>
    -->
    </HTML>
    

    Heilige Scheiße – HTML-Tags in Großbuchstaben und in einen HTML-Kommentar eingebettetes XML: da waren klare SpezialexpertInnen am Werk. Wenn die Leute, die sich das ausgedacht haben, das hier lesen: Ich mache zum Sonderpreis von 9 Euro eine Fortbildung in XML Namespaces und wie sie für so Zeug einzusetzen wären.

    Ansonsten sollte ich wahrscheinlich mal bei http://www.wballiance.net vorbeischauen; vielleicht lässt sich mit diesem Zeug ja irgendwas basteln, das die lästigen Vorschaltseiten, die sowas ausliefern, ganz ohne Javascript webzaubert?

    Nur nicht gerade jetzt, denn: We are offline....

    [1]Also gut: Was wäre verkehrt daran, den Captive-Portal-Scheiß ganz zu lassen?
    [2]Ich würde gerne sagen, dass ich extra zu dessen Erwerb zum Bahnhof Mainz Römisches Theater gefahren bin, denn das ist schon einer der schönsten Bahnhofsnamen der Republik, aber das wäre eine Lüge.
  • Entering Wild Unicode in Vim

    Screenshot of a vi session showing the unicode PILE OF POO symbol

    This is what this post is about: being able to type PILE OF POO (a.k.a. U+1f4a9) in vim in…tuitively. For certain notions of intuition.

    As a veteran of writing texts in TeX, I've long tended to not bother with “interesting” characters (like the quotes I've just used, or the plethora of funny characters one has for writing math) in non-TeX texts. That is, until I started writing a lot of material not (directly) formatted using TeX, as for instance this post. And until reasonably robust Unicode tooling was widely available.[1]

    I enter most of my text in vim, and once I decided I wanted the exotic unicode characters I experimented with various ways to marry unicode and vim. What I ended up doing is somewhat inspired by TeX, where one enters funny characters through macros: a backslash and a few reasonably suggestive letters, as perhaps \sigma for σ or \heartsuite for ❤.

    What lets me do a similar thing in vim are interactive mode abbreviations and unicode escapes. I've found the abbreviations do not inconvenience me otherwise if I conclude them with a slash. And so I now have quite a few definitions like:

    iab <expr> scissors/ "\u2702"
    

    in my ~/.vimrc. This lets me type scissors/␣ to get ✂ (and blank/␣ to get the visible blank after the scissors). This works reasonably well for me; it's only when the abbreviation is not bounded by blanks that I have have to briefly leave the insert mode to make sure that vim recognises the abbreviation. For instance y▶y – where the abbreviation needs to directly abut the letter – I have to type as y<ESC>aarrleft/ <BACKSPACE>y. I don't know about people who didn't grow up with TeX, but in my world such a thing passes as really natural, and for me it easily beats the multibyte keymaps that, I think, the vim authors would recommend here.

    And how do I figure out the unicode code points (i.e., the stuff after the \u)? Well, there is the unicode(1) command (Debian package unicode), which sounds cool but in reality only points me to what I'm looking for every other time or so: It's hard to come up with good words to look for characters the name of which one doesn't know.

    In practice, most of the time I look at the various code blocks linked from the Wikipedia unicode page. Going by their titles in my experience is a good way to optically hunt for glyphs I'm looking for. The result is the following abbreviations – if you make interesting new ones, do send them in and I will update this list:

    iab <expr> deg/ "\u00B0"
    iab <expr> pm/ "\u00B1"
    iab <expr> squared/ "\u00B2"
    iab <expr> cubed/ "\u00B3"
    iab <expr> times/ "\u00D7"
    iab <expr> half/ "\u00BD"
    iab <expr> acirc/ "\u00E2"
    iab <expr> egrave/ "\u00E8"
    iab <expr> idia/ "\u00EF"
    iab <expr> subtwo/ "\u2082"
    iab <expr> euro/ "\u20ac"
    iab <expr> trademark/ "\u2122"
    iab <expr> heart/ "\u2764"
    iab <expr> smile/ "\u263A"
    iab <expr> arrow/ "\u2192"
    iab <expr> emptyset/ "\u2205"
    iab <expr> bullet/ "\u2022"
    iab <expr> intersects/ "\u2229"
    iab <expr> scissors/ "\u2702"
    iab <expr> umbrella/ "\u2614"
    iab <expr> peace/ "\u262e"
    iab <expr> point/ "\u261b"
    iab <expr> dots/ "\u2026"
    iab <expr> mdash/ "\u2014"
    iab <expr> sum/ "\u2211"
    iab <expr> sqrt/ "\u221a"
    iab <expr> approx/ "\u2248"
    iab <expr> neq/ "\u2260"
    iab <expr> radio/ "\u2622"
    iab <expr> hazmat/ "\u2623"
    iab <expr> pick/ "\u26cf"
    iab <expr> eject/ "\u23cf"
    iab <expr> check/ "\u2713"
    iab <expr> alpha/ "\u03b1"
    iab <expr> beta/ "\u03b2"
    iab <expr> gamma/ "\u03b3"
    iab <expr> delta/ "\u03b4"
    iab <expr> epsilon/ "\u03b5"
    iab <expr> zeta/ "\u03b6"
    iab <expr> eta/ "\u03b7"
    iab <expr> theta/ "\u03b8"
    iab <expr> kappa/ "\u03ba"
    iab <expr> lambda/ "\u03bb"
    iab <expr> mu/ "\u03bc"
    iab <expr> nu/ "\u03bd"
    iab <expr> Delta/ "\u0394"
    iab <expr> Xi/ "\u039e"
    iab <expr> pi/ "\u03c0"
    iab <expr> rho/ "\u03c1"
    iab <expr> sigma/ "\u03c3"
    iab <expr> chi/ "\u03c7"
    iab <expr> supp/ "\u207A"
    iab <expr> supm/ "\u207B"
    iab <expr> tripleeq/ "\u2261"
    iab <expr> cdot/ "\u22c5"
    iab <expr> powern/ "\u207f"
    iab <expr> chevopen/ "»"
    iab <expr> chevclose/ "«"
    iab <expr> element/ "\u2208"
    iab <expr> notelement/ "\u2209"
    iab <expr> subset/ "\u2282"
    iab <expr> superset/ "\u2283"
    iab <expr> blank/ "\u2423"
    iab <expr> block/ "\u2588"
    iab <expr> achtel/ "\u266a"
    iab <expr> clef/ "\u1d11e"
    iab <expr> arrleft/ "\u25B6"
    iab <expr> arrdown/ "\u25BC"
    iab <expr> poop/ "\U1f4a9"
    

    One last thing one should know: quite a few interesting unicode characters are outside of what's known as the „Basic Multilingual Plane“, which is a pompous way to say: within the first 65536 code points. That in particular includes all the emoijs (please don't torture me with those), but also the timeless PILE OF POO character, the rendering of which in the Hack font is shown in the opening image. Addressing codepoints above 65536 needs more than four hex characters, and to make vim grok those, you need to say \U rather than \u.

    [1]Which, I give you, has been the case as of about 10 years ago, so it's not like all this is bleeding-edge.

« Seite 9 / 17 »

Letzte Ergänzungen