Entertain me on a sunday

Sunday was great weather, 0° and sunny, after breakfast I went outside on a 90 minutes long walk and three podcasts:

The Bicycle Artist by Home of the Brave

An interview with a bike designer in Walnut Creek, California, that has his own opinions on bike design, and about what he thinks makes a great bike. Refreshing.

Two More Stories About Mountains by Home of the Brave

Starts off with a monologue by the author and then continues into a story that first aired in '96 on public radio. A psychedelic trip into the kind of industry that deliveres ultimate experiences. All set against the backdrop of the narrators plan to ascend the famous mountain K2. Mind-boggling.

The Reservoir Tapes on BBC Radio 4

The first installment in the series features only a single speaker, but it's not a monologue. In fact it is just one side of a conversation, that is held with the parents of a teenager that has disappeared. Stirring.

Haddawys 'Arabian Nights'

I'm currently reading Haddawys new translation of 'Arabian Nights' and I enjoy it greatly. The short format of each story or 'night' is delightful. I'm totally blown away, that something stemming from a 14th century manuscript could be translated into this kind of vivid, modern English.

And the short-story format is very friendly, when you just have three tube stations time to get some reading done, before you spend the rest of the day at work.

With texts this age you always feel like the value canon of the character is just way off. With the bad stories, the read will drag on forever. But Haddawys translation is just that good, that it pulls you in immediately.

Ideal reading for the tube.

Arabian Nights at Goodreads

Yeast population growth

I started educating beer judges two months ago and the upcoming topic will be 'fermentation'. This peaked my curiosity a little. I do have two text which cover this. This is Heinrich Lüers "Wissenschaftliche Grundlagen von Mälzerei und Brauerei" and White and Zainasheff "Yeast". Lüers is more of a basic science text, written in 1950, while White is specifically aimed at the ambitious homebrewer and maybe the microbrewer.

Let's review Lüers most important ideas.

Yeast population growth

Lüers give for the population growth:

$$ N_f = N_0 e^{kt} $$

With (N_0) the initial mass, (N_f)the end mas and (k) the growth constant.

This, he states, is reformulated for (k)

$$ k= (\log N_f - \log N_0) / 0.4343 *t $$

More precisely[1]

$$k= (\ln N_f - \ln N_0) / t$$

He states that this rule will hold true for the initial growth phase, but that growth will diminish once nutrients are metabolized by the yeast.

He gives as the generation time

$$g=t*\log 2/(\log b - \log a)$$

With (a) and (b) as the cell count at the beginning and end of the experiment respectively[2].

Lüers give the generation time for a yeast that was grown according to Hägglund (mineral salt added to solution) as 8 hours 17 minutes. The same yeast has a generation time of 4 hours and 12 minutes, when a small amount of autolyzed yeast is added to the solution. He gives another example of wort with fine trub having a generation time of 5.5 hours, while those without fine trub has a generation time of 3 hours.

As a rule of thumb, Lüers give a generation time between 5 and 9 hours in beer wort.

The role of temperature

Lüers cites Bertalanffry in attributing two differences in fermentation: with increasing temperature the fermentation process increases, but the individual cell size at the end will decrease. He attributes this to the fact that the mitosis rate grows faster than the cells ability to assimilate nutrients, hence resulting in more, but smaller cells.

For a lager yeast, he lists the following generation times:

  • 4°C: 20 hours
  • 13°C: 10.5 hours
  • 23°C: 6.5 hours
  • 28°C: 5.8 hours
  • 38°C: no growth

He notes that the maximum growth will be reached between 27.5°C and 30°C.

As the pasteurization temperature for yeast, he lists 58-60°C for a yeast culture with the name "Saaz". In the same vein he relates the fact that yeast can be deep frozen for multiple months, without killing it. He states that the main problem of freezing is the speed at which the yeast is cooled and the temperature it's stored at. It should be frozen quickly and stored at or below -20°C.

Lastly sporulation optima lie at different temperatures[3].

Other factors

We still need to investigate wort concentration, alcohol concentration as well as oxygen content of wort.

White and Zainasheff relate the fact, that most of the aromatic compounds produced by the yeast, will already be formed during the exponential growth phase.

We will observe White and Zainasheff in a later post and hopefully get to some more details about fermentation.

Footnotes


  1. Compare http://www.krysstal.com/logarithms.html for the factor in difference. ↩︎

  2. Compare Wikipedia / Doubling time which has the same derivation. ↩︎

  3. p.638 ↩︎

My morning papers

The taz has a report on the radical left group KOMITEE. Three guys who tried to bomb an immigration removal jail. This jail was not yet opened. Their intention was to stop it from going into service. All of this happened in the nineties.

They've been on the German most wanted list for 20 years. All three hid in South America, most recently requesting refugee status in Venezuela, where they now live. The report tells the story of a lot of personal hardship on their side as well as on the side of their families.

After 20 years, the prosecutor still refuses to drop the charges, arguing that the statute of limitations does not apply, since the three men formed a terrorist group and prepared to commit a felony. The report features pictures of the guys, who are now in their mid-fifties, clad in T-shirts by the band Irie Revoltes.

http://www.taz.de/Linksradikale-Gruppe-KOMITEE/!5464717/


MotherJones has a longer read comparing the German and the U.S. coal industries. Or rather: painting a picture of the last remaining hard-coal mine in Germany. The Ruhr valley, the former industrial heartland of Germany, isn't that bad off, compared to its twin in Appalachia.

There's a lot of innovation going on in cities like Bottrop, that turned around and made a name for themselves by investing in renewable energy. There's no delusion about the return of coal in Germany.

http://www.motherjones.com/environment/2017/12/germanys-war-on-coal-is-over-coal-lost/#


The taz reports that the police is trying to prove that there was large scale preparation for the G20 protests in Hamburg, that included depositing material like pyrotechnics and black clothes in hidden places. According to them it was all set up in advance and coordinated by the Hamburg left.

http://www.taz.de/Razzia-wegen-G20-Krawallen/!5467534/


Meanwhile Trump got his way at the Supreme Court, the immigration stop for 6 Muslim countries will no longer be delayed. This does not mean it's legal, the court just ruled that the provisions cannot be delayed by the lower courts.

http://www.taz.de/Kommentar-US-Einreisestopp/!5467537/


Brexit talks have become very convoluted. When an agreement between London and Brussels had already been found, the DUP of Northern Ireland called Theresa May during a meeting with commission president Juncker, to tell her that they won't agree to anything that gave special status to Northern Ireland. The Irish government labeled this as a collapse of talks to this date. Scottish First Minister Sturgeon had already proposed to find a similar solution for Scotland and mayor Khan had asked for a similar solution for London.

Time is of the essence in the current talks. On December 15 the EU wants to sign the preliminary agreements concerning Brexit. If 27 member states have to find a consensus and sign this paper, there is hardly any time left to complete the preliminary talks and send the paper to the members.

The DUP can sabotage any talks, because they're in power in Norther Ireland and also tolerate Mays government in the UK parliament. Without the DUP there will be no solution to the question of the future borders between Ireland and Northern Ireland.

https://www.theguardian.com/politics/2017/dec/04/juncker-and-may-fail-to-reach-brexit-deal-amid-dup-doubts-over-irish-border

My morning papers

taz on the change in leadership of the AfD. Apparently the extremist wing of an already right wing party has had its say. The AfD moves in a more extremist direction, discounting its "moderate" wing.

http://www.taz.de/Kommentar-Neue-Parteichefs-der-AfD/!5467235/

taz on the blockades during the general meeting of the AfD. Police act with utmost brutality to stop upright citizens from doing peaceful protests against the extremist party.

http://www.taz.de/Aktionen-in-Hannover/!5467223/

This report details the plans for London to create publicly accessible water refill stations. I hope this works out. I always cringe, when I see people carrying water bottle (without carbonic acid), when they could just fill up at the nearest tap. Hard to understand that people pay a lot of money for the privilege of drinking other peoples tap water.

I hope this plan bears fruition.

https://www.theguardian.com/environment/2017/dec/04/sadiq-khan-plans-network-of-london-water-fountains-to-reduce-plastic-waste

In 1995 a compromise on abortion was struck in the German parliament. From there on, abortion would be illegal, but the would be no penalty imposed. But one remnant of that time is the pragraph 219a, which forbids advertising abortions in any way. An obstetrician now listed abortion on her website, as part of a list of procedures she performs. That led to lawsuit against her, that ended in her having to pay a 6,000 EUR fine.

taz has background on the situation and about the parties in the German parliament that want to abolish this law.

http://www.taz.de/Abschaffung-von-219a/!5463558/

This report details the UKs immigration removal detention centres. We had a similar debate in Germany, when the government basically built immigration removal jails. This dates back to the 1990s and subsequently was ruled to be illegal by the European Court of Justice.

This is on the occasion of a report by the British Medical Association on the conditions of medical care in the detention centres.

https://www.theguardian.com/uk-news/2017/dec/04/bma-calls-for-home-office-to-phase-out-immigration-removal-centres

Next steps for ox-epub

About ox-epub

I'm the author of ox-epub an org mode extension that let's you export your org files in EPUB format. This allows you to easily get your notes or plans onto a Kindle or other ebook device. Documents formatted with org-epub display well on limited capability devices like phones and e-readers.

This week I'm preparing ox-epub version 0.3.0. This version will come with baked in support for mathematical formulae. On the project side, this version also now includes a basic CI pipeline using Travis CI. The documentation has been expanded to include actual sample code, besides the reference-oriented README file.

ox-epub is a niche mode, there were a total of 48 downloads on MELPA during the 8 month lifetime of the project. But reception on Github was more welcome, all counted, it received 25 stars and has already two other contributors, besides me. Every few weeks or so, somebody pops in to report an issue or request help.

So what are the next steps for ox-epub?

Parity with ox-html

One of the earlier issues ox-epub faced was the bulging feature set of ox-html. Fortunately most of these translate well into the epub format. It was necessary to adapt ox-epub for image export, formula export and linking.

In this category, most of the time will be spent on reviewing ox-html and writing test/sample code to verify that those features actually work with ox-epub and translate well into the EPUB format.

This point will take up most of the time. This should be time well invested. Future-proofing ox-epub and enabling people to use the features they expect to be there.

Better ebooks

ox-epub already supports title pages with custom images, as well as custom stylesheets for your books. It also has support for setting the most common metadata defined in the EPUB specification

There's also baked in support for automatically generating the table of contents. The outline is directly taken from the headings of your org document. This table of contents is then specially treated by an ebook reader and presented out of band to the user, to facilitate document navigation.

Some options for the future are:

  • Fine grained table of contens inclusion
  • Support for footnotes
  • Preview function from C-c C-e menu

Nowadays the EPUB 3 specification has been out for some time, adoption however remains laggard. In essence we're limited to create EPUB 2 books. These however will convert well into MOBI or any other format that you could imagine, because of their limited functionality.

I've mixed feelings about EPUB 3. While it allows to use JavaScript and HTML in a more convenient way, I don't see these as essential elements of the EPUB experience. For me an EPUB is basically about getting electronic text into a form that I can easily digest in longer sessions. Something that seems elusive, when sitting in front of a Laptop.

Using sudo in org-babel

Here's a simple way of using sudo in org-babel:

#+NAME: just-open
#+BEGIN_SRC shell :tangle no :dir /sudo::~mark/writing
exec 2>&1
mkdir -p perf && cd perf
/home/mark/.guix-profile/bin/perf stat -e 'block:*' ../open-perf
#+END_SRC
  • Use :tangle no to exlude this snippet from being tangled
  • Use :dir /sudo::~mark/writing to activate TRAMP (/sudo) and set the current path that is to be used. Note: paths relative to the document didn't work out for me
  • Use exec 2>& to redirect stderr to stdout to capture the entire output of your command, not just stdout
  • Finally use the full path to the command, because your user environment may be different then the sudo environment you're running in.

That's it. Tested on org-mode 9 and emacs 25.3.

Investigating open() and close() performance

On another day, the question came up, in how far the performance of

open() affects a certain system. In my mind I was going through the

need to go to disk and do sync() calls to open a file that didn't

exist. Eventually I decided to write a simple tester for this use

case. open-tester.cpp will open ten thousand files.

In combination with Linux perf tool, this leaves us in a convenient

position to benchmark the performance of this particular system call.

The questions that I want to answer is, whether open() or close() will

be synchronous, i.e. if they will go to disk. And if they do, how

often they will do it.

  #include <fcntl.h>
  #include <string.h>
  #include <unistd.h>

  #include <sys/types.h>
  #include <sys/stat.h>

  #include <cstdlib>

  /* taken from https://stackoverflow.com/questions/440133/how-do-i-create-a-random-alpha-numeric-string-in-c */
  void gen_random(char *s, const int len) {
      static const char alphanum[] =
      "0123456789"
      "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
      "abcdefghijklmnopqrstuvwxyz";

      for (int i = 0; i < len; ++i) {
      s[i] = alphanum[rand() % (sizeof(alphanum) - 1)];
      }

      s[len] = 0;
  }

  int main(int argc, char **argv){
      bool do_write;
      bool do_close;

      if(argc > 1){
      if(strchr(argv[1], 'w') != NULL){
          do_write = true;
      }
      if(strchr(argv[1], 'c') != NULL){
          do_close = true;
      }
      }

      const int num_opens = 1000;
      char names[num_opens][11];
      int fds[num_opens];

      for(int i = 0; i < num_opens; i++){
      gen_random(names[i], 10);
      }

      for(int i = 0; i < num_opens; i++){
      fds[i] = open(names[i], O_CREAT | O_WRONLY | O_TRUNC);
      if(do_write){
          write(fds[i], "0123456789", 10);
      }
      }

      if(do_close){
      for(int i = 0; i < num_opens; i++){
          if(fds[i] > 0){
          close(fds[i]);
          }
      }
      }

      return 0;
  }

I then ran this program with three different options.

Just open the files

We're passing O_CREAT to open(), so this entails creating the file. I

wasn't sure if this would go directly to disk.

perf stat -e 'block:*' ../open-perf

|             |                            |       |         |                 |
| Performance | counter                    | stats | for     | '../open-perf': |
|             |                            |       |         |                 |
|       5,935 | block:block_touch_buffer   |       |         |                 |
|           0 | block:block_dirty_buffer   |       |         |                 |
|           0 | block:block_rq_abort       |       |         |                 |
|           0 | block:block_rq_requeue     |       |         |                 |
|           0 | block:block_rq_complete    |       |         |                 |
|           0 | block:block_rq_insert      |       |         |                 |
|           0 | block:block_rq_issue       |       |         |                 |
|           0 | block:block_bio_bounce     |       |         |                 |
|           0 | block:block_bio_complete   |       |         |                 |
|           0 | block:block_bio_backmerge  |       |         |                 |
|           0 | block:block_bio_frontmerge |       |         |                 |
|           0 | block:block_bio_queue      |       |         |                 |
|           0 | block:block_getrq          |       |         |                 |
|           0 | block:block_sleeprq        |       |         |                 |
|           0 | block:block_plug           |       |         |                 |
|           0 | block:block_unplug         |       |         |                 |
|           0 | block:block_split          |       |         |                 |
|           0 | block:block_bio_remap      |       |         |                 |
|           0 | block:block_rq_remap       |       |         |                 |
|             |                            |       |         |                 |
| 0.006021314 | seconds                    | time  | elapsed |                 |
|             |                            |       |         |                 |

Open and close the files

The second test case will open 1000 files and then close them, given

O_CREAT, my assumption was, that this close() operation will go

directly to disk, persisting the file (name).

perf stat -e 'block:*' ../open-perf c


|             |                            |       |         |               |     |
| Performance | counter                    | stats | for     | '../open-perf | c': |
|             |                            |       |         |               |     |
|       5,935 | block:block_touch_buffer   |       |         |               |     |
|           0 | block:block_dirty_buffer   |       |         |               |     |
|           0 | block:block_rq_abort       |       |         |               |     |
|           0 | block:block_rq_requeue     |       |         |               |     |
|           0 | block:block_rq_complete    |       |         |               |     |
|           0 | block:block_rq_insert      |       |         |               |     |
|           0 | block:block_rq_issue       |       |         |               |     |
|           0 | block:block_bio_bounce     |       |         |               |     |
|           0 | block:block_bio_complete   |       |         |               |     |
|           0 | block:block_bio_backmerge  |       |         |               |     |
|           0 | block:block_bio_frontmerge |       |         |               |     |
|           0 | block:block_bio_queue      |       |         |               |     |
|           0 | block:block_getrq          |       |         |               |     |
|           0 | block:block_sleeprq        |       |         |               |     |
|           0 | block:block_plug           |       |         |               |     |
|           0 | block:block_unplug         |       |         |               |     |
|           0 | block:block_split          |       |         |               |     |
|           0 | block:block_bio_remap      |       |         |               |     |
|           0 | block:block_rq_remap       |       |         |               |     |
|             |                            |       |         |               |     |
| 0.006067496 | seconds                    | time  | elapsed |               |     |
|             |                            |       |         |               |     |

Contrary to my intuition, this did not lead to any block IO operations

being submitted to the disk. This simply seems to dirty the

corresponding inode the file is defined in. This is a very nice

outcome and this path looks well optimized.

Open, read, close

The last test-case will open a file, write to it and then bulk close

all the files. This should lead to block io being performed, my

assumption here is again that close is synchronous.

perf stat -e 'block:*' ../open-perf cw

|             |                            |       |         |               |      |
| Performance | counter                    | stats | for     | '../open-perf | cw': |
|             |                            |       |         |               |      |
|      10,868 | block:block_touch_buffer   |       |         |               |      |
|       1,000 | block:block_dirty_buffer   |       |         |               |      |
|           0 | block:block_rq_abort       |       |         |               |      |
|          19 | block:block_rq_requeue     |       |         |               |      |
|           0 | block:block_rq_complete    |       |         |               |      |
|         176 | block:block_rq_insert      |       |         |               |      |
|         157 | block:block_rq_issue       |       |         |               |      |
|           0 | block:block_bio_bounce     |       |         |               |      |
|           0 | block:block_bio_complete   |       |         |               |      |
|         843 | block:block_bio_backmerge  |       |         |               |      |
|           0 | block:block_bio_frontmerge |       |         |               |      |
|       1,000 | block:block_bio_queue      |       |         |               |      |
|         157 | block:block_getrq          |       |         |               |      |
|           0 | block:block_sleeprq        |       |         |               |      |
|         157 | block:block_plug           |       |         |               |      |
|         157 | block:block_unplug         |       |         |               |      |
|           0 | block:block_split          |       |         |               |      |
|       1,000 | block:block_bio_remap      |       |         |               |      |
|           0 | block:block_rq_remap       |       |         |               |      |
|             |                            |       |         |               |      |
| 0.017545475 | seconds                    | time  | elapsed |               |      |
|             |                            |       |         |               |      |

And indeed it lead to a series of block IO requests. Note that this

example queues 1,000 block IO operations, but only fires 157 block IO

operations, a testament to the effectiveness of the IO scheduler.

From a speed perspective these operations are all negligible, when

performed on my notebook, even when writing to disk, this will only

issue 157 IO operations, which are easily completed in two hundredths

of a second.

In a followup I would like to look into continously writing random

files to disk.

So the takeway is, that essentially open() is not synchronous, it goes

directly to the dentry cache, close() does not incur any immediate

block device requests, iff no data has to be committed.

Review: The Great Gatsby

I completed reading The Great Gatsby last week. This book was a classic topic of English courses during my high-school years. I did however take only basic courses in English and never got to read this book. Instead we read "The Loneliness of the Long-Distance Runner".

But back to Gatsby. The book started off, with the protagonist moving to the eastern United States and joining the bond selling business. It details the luxurious property of Gatsby. For me this led to a rather slow start. Bond business and high-society babble being not my favorite topic.

The plot does develop quickly however, a short passage anticipating the true identity of Gatsby, and some pages later the disconnected characters of the novel get woven into the tight fabric of the story.

I'll admit: I liked it. Despite the setting early in the 20th century and the eclectic mix of characters, that seemingly have no profane sorrows and only care for their entertainment, the story is surprisingly classical in it's structure.

But I can't make myself see any deeper meaning, any social relevance. The

story looks a little bit like a crime story set in the roaring twenties. The narrator is styled as a man with modest roots from the mid-west. This makes the story more relatable, but doesn't compensate for the shallow drama of the story.

I think it's masterfully executed, but nonetheless I feel like leaving the book with a disdain for the shallow story.

Review: Great Ideas on Radio New Zealand

It's a tranquil Sunday afternoon in Hamburg. The rain is pouring down, i already confirmed that the ice cream parlor has closed for today. So it's radio time for me.

And there's a particular gem I would like to recommend to you. It's Radio New Zealand's "Great Ideas" series, that started out with the episode on "Rebellion and Revolution". A show formatted as a talk between multiple scholars and a host.

They launch into an exploration that spans history, from antique times to the modern day revolution in Egypt and the black lives matter movement in the US. All the while maintaining their overarching themes of liberty and democracy.

They touch on the uncertainty of becoming a great revolutionary or just filling up the killing fields. Is it justified to use lethal force against an repressive regime? With new studies suggesting that rape and petty murder ran high, even during the American evolutionary war.

Then there's the doubt; what will the future bring, after the revolutionary deed has been done. Is there going to be a more humane and equitable rule, or is there going to be a revolutionary furor, a bloodbath, that will spoil the fruits of the revolution.

With changes in the modern world, the enrichment of knowledge and technology, what brings the future? Will humanity come under control of a global dictator? And do we have a moral obligation to resist said dictator? Although the system may work well for me, does it work for others?

At the end they wrap up with the question, whether there is still the glorious revolutionary of past times.

45 enjoyable minutes, available at Radio New Zealand