Astro observation log 27.12.2021

Finally clear skies and I was at a bortle 2 location. I also had my new Canon EOS RP Camera.

M 42 – The Orion Nebula again

M 42 at a bortle 2 location was great! Last time I imaged the Orion Nebula I struggled with tracking. This time I had fine tracking (for my dobsonian anyway) and I finally got pretty round stars. I got 20 good 15 second exposures at 1600 ISO. After stacking in AstroPixelProcessor and post processing in Pixelmator Pro i got this result:

Around 15 light frames, and 20 dark frames stacked.

NGC 2024 – Flame Nebula

I have tried to observe the Flame Nebula visually many times, and I have failed every time. I was therefore planning to only do some testing photos of the region. I had trouble lining up the finder scope and camera, and I therefore did some visual observing. The nebula showed up surprisingly clear. Bortle 2 skies are really something.

Once back inside I regretted not observing more carefully visually as well as taking several image sequences. The Horsehead Nebula showed up quite clearly in my images, and with the bortle 2 skies, maybe it would have been visible visually as well.

5 lights stacked of the Flame nebula (upper left), Horsehead nebula (lower right) and NGC 2023 in the lower middle center.

M 33 – Triangulum galaxy

The galaxy showed up very clearly, and I got some images. Sadly the tracking worked badly in that region of the sky, and my focus was off. Looking forward to try this again some other time.

Single M33 shot

M 1 – Crab Nebula

I also got some images of the crab nebula. My focus work was not great, and I should use my Powermate next time, to get more nebula data.

NGC 281 – Pacman Nebula

I have tried and never even gotten close to observe this visually before. This night it was visible, and I got few images that were fine. I do not have enough data to stack, but my single ok light frame looks like this:

NGC 869/NGC 884 – Perseus double cluster

This cluster is easy to find, and with little battery left, and tracking that was not working, I decided to do 2 second shots. Stacking those resulted in this, which by far is my best open cluster image to date.

NGC 869 (left) and NGC 884 (right)

Closing thoughts

All in all this was a very rewarding session, and I finally got some deep sky data that was worth it to process. The Orion nebula image turned out way over my expectations.

I am thinking about getting an equatorial mount, and maybe a guide camera, so I can take longer exposures. It was also really great to finally see some of the more difficult nebulae visually.

Here’s to hoping I get a night in 2022 that beats this one.

Adventures in creating a Snap from an LWJGL2 based game

The old Artifact is still kicking, not too long ago I created a Snap for it. Creating the Snap felt a bit like concocting a magical snapcraft.yaml and and hoping it works out. For the first few attempts the magic never works out, and the process of figuring things out tend to be tedious at best. This was no exception. Here are some of the problems I ran into, hope it helps someone else.

Xprop missing

My first Snap attempt immediately spit out this during startup:

java.io.IOException: Cannot run program "/usr/bin/xprop": error=2, No such file or directory

This was fixed by adding these lines to my snapcraft.yaml. The layout is needed since xprop is referred to by an absolute path. See this thread for more information.

layout:
  /usr/bin/xprop:
    bind-file: $SNAP/usr/bin/xprop

parts:
  mypart:
    stage-packages:
      - x11-utils

A xrandr puzzle

Next in line was this:

Exception in thread "main" java.lang.ExceptionInInitializerError
	at org.newdawn.slick.AppGameContainer$1.run(AppGameContainer.java:39)
	at java.security.AccessController.doPrivileged(Native Method)
	at org.newdawn.slick.AppGameContainer.<clinit>(AppGameContainer.java:36)
	at game.Artifact.main(Unknown Source)
Caused by: java.lang.ArrayIndexOutOfBoundsException: 0
	at org.lwjgl.opengl.LinuxDisplay.getAvailableDisplayModes(LinuxDisplay.java:951)
	at org.lwjgl.opengl.LinuxDisplay.init(LinuxDisplay.java:738)
	at org.lwjgl.opengl.Display.<clinit>(Display.java:138)
	... 4 more

This was caused by xrandr not being installed in the snap, which LWJGL2 uses to find display stuff. This was fixed by adding the x11-server-utils package, which installs xrandr.

stage-packages:
  - x11-xserver-utils

For debugging snaps and finding packages these commands were great.

#This allows you to look at the system as seen from the snap
snap run --shell <your-snapname> 

#This will give the package that installed an executable, in this case xrandr
dpkg-query -S /bin/xrandr

I hope this helps someone else looking to get their application in a Snap.

Expanding the disk on a QEMU run Ubuntu VM

A few days ago I started up Ubuntu in a VM to run some silly experiment. Suddenly I needed a bit more space though, and instead of creating a new disk I decided to expand the current one instead. This took some time to figure out, so posting it here for my future self and others who possibly might want to do this.

Since there was nothing of real importance on this VM, I did most steps on the VM while it was running. Take backups if you attempt this and care about your data, I am not sure all of it is safe.

I am running QEMU using UTM on my M1 mac, and the .qcow2 files get put somewhere deep in the users Library folder by default. Once I found the file, I shut down the VM and did this on the host:

qemu-img resize disk-0.qcow2 50G

Then I started the VM, installed gparted and expanded the partition. df still reported the disk to be 90% full though. Eventually I figured that I also needed to expand the logical volume. The command to do this was:

sudo lvextend -l +100%FREE /dev/mapper/<volume name>

But still df reported the volume to be full. Seems the ext4 filesystem also needs to be expanded. This did the job:

sudo resize2fs /dev/mapper/<volume name>

Finally df reports lots of free space! Sweet!

At the beginning, I shut down the VM before I did the first resizing of the .qcow2 file. I am not sure that was necessary. The next time I need to expand a disk on an unimportant VM, I will try without shutting it down for sure.

Observation log 18. of April 2021.

Conditions were not great, moonlight was a pain, and some red light leaked from some camera status light into all of my M3 images.

On the positive side I finally got to see M3 and M5 and also M57 (Ring nebula), and I got decent images (for me anyway) of M13 and the leo triplet.

M57 (Ring Nebula)

I have long wanted to try to observe a planetary nebula, but I think I had the size all wrong. I was looking for something larger.

In my finder scope M57 looked a lot like a star, and if it was not so easy to locate due to being in between two bright stars I would have probably scanned past it. Once I found it, the ring structure was clearly visible at medium magnification. Really neat!

I think that having calibrated my expectations now, finding other planetary nebulae will be easier.

M13 (Hercules globular cluster)

Earlier this year I ordered a 2x TV Powermate mainly for planetary observation. To test it I tried using it together with my 2″ Aero on the globular clusters and M57. It worked way beyond my expectations.

I also took 15 seconds exposure of M13 below (the most my tracking was good for). The two red spots I marked are two Cepheid variable stars, which I found comparing the chart here to my image.

M13, with two marked Cepheid variable stars. These are stars are used as distance measures, since their period determine their absolute (actual) brightness.

These stars have a periodic change in brightness. The period of their change in brightness determine their absolute brightness. Then the relative brightness (the brightness observed from Earth) and the absolute brightness can be used to find the distance to the star.

It would be really nice to try and observe M13 with the same magnification over time, and see if I can catch the blinking.

Leo triplet

I observed these galaxies visually some time ago, but this time I got to take a series of pictures as well. Out of like around 20 exposures of 15 seconds, I got 6 images that were fine. After stacking this was the result. Noisy, but some structure at least.

M65 top right, M66 to left, NGC 3628 bottom

I had a lot of fun this night!

Artifact Snap and AppImage for Linux

Some time ago I added an AppImage for my old game Artifact, as an easy way of installation on Linux. AppImages have a neat architecture, and hopefully will keep Artifact running for a long time on a lot of systems. AppImages can also be run sandboxed using Firejail if you have little trust in me or the source of the AppImage.

Artifact running as a Snap

Now, AppImages do not really have a nice centralized location where applications can be discovered. There are some initiatives, but it feels a bit crude and lacking some polish.

Snaps and their central registry on the other hand feel way more polished. If anything the content in the store often feels unpolished compared to the store. Snaps also run sandboxed by default. While this is good, it sometimes causes unexpected issues, and can be opted out of.

Making a Snap of a LWJGL 2 application was a bit of a headache, but it worked out in the end. My experience with the Snap documentation in general was good, and most of the work was a breeze after I got the game running as a Snap.

Now, go play some Artifact on Linux!

Less light pollution; better photos.

So I finally got to try to take astro photographies from somewhere with less light pollution. I still have trouble with movement from either my tracking lagging a bit, or me not having a remote control for the camera (so I cause movement in the telescope when I start the shot).

M42 – Orion Nebula again

M42 is so easy to find observe and shoot. I also finally got to see some of the Flame Nebula, by doing a 30 seconds exposure into what looked like nothing at all. It sadly did not turn out very well because of movement in the camera, but I finally saw something! Anyway, here is my M42 shot. Getting better at this!

M42 20s exposure with pretty much no editing. Increased contrast a bit and moved the black point.

M31 – Andromeda Galaxy

The moon would easily fit in this picture, but the Andromeda galaxy takes more space, so this is mostly the core and some of the arms. I think I could fit most of the galaxy if I had rotated the camera. I randomly also caught M32 (barely visible at the left edge) and M110 (in the lower right corner). Looking forward to try Andromeda with an even longer exposure, or many stacked images.

M31 30s exposure, and some editing (contrast, black point)

Astro log – Through the smog and light pollution

A month back I finally got a new stepper motor and got the tracking for my telescope working. One dark night I took it to a pretty dark spot close to Bergen and did some observations.

M42 – Orion Nebula

I have observed the Orion nebula under bad light pollution before, but this time I got to observe it with under better conditions. It was stunning. Very sharp.

The next day I took my first deep space photography ever from our apartment. The light pollution was really bad, and there was some smog as well. I also forgot that I could use a timed shot. So i think some blurring is due to the camera moving slightly after I started the exposure.

I think it turned out fine for a first:

M42 taken with a 5 – 10 seconds exposure. Very heavy light pollution. The left image is the raw image, the right ones are versions where i increased contrast and tried to remove the pollution. The latter is an attempt to make it look somewhat like what a visual observation of M42 looks like in my telescope (it is sharper when visually observed)

M1 – Crab Nebula

My original plan for the trip, was to observe M42 and the Andromeda Galaxy. I was also hoping to get to see the Flame Nebula since it was really dark. I sadly did not see any trace of the Flame Nebula so I started looking for some open clusters to look at in Taurus. While scanning for them I suddenly saw that the Crab Nebula was close, and I found it immediately. It is the first supernova remnant I have observed, and I think I saw some small amount of detail. Hoping to get a picture of it one of these days.

M31 and M110 – Andromeda Galaxy and a friend

Andromeda is a not that interesting to visually observe since it is so hard to see anything beyond the core. I think I saw some more since it was really dark, but it was very faint. These two are prime targets for a photo some day, since that should bring out some more detail.

An injection induced horror story

TLDR; Never use field Injection in Spring, scope APIs well, and do not mock value objects.

As this story starts, I was the system responsible for an old application which was being replaced. The replacing application was made by an external team (largely outsourced and supposedly seniors), but once in production, the new system would become part of the responsibility of the maintenance team I was on.

Beginning this transition, I started looking at the new system. My initial impression was good. The database schema was cleaned up compared to the old system. The project seemed more organized. It had a DB migrations system set up. A big improvement compared to what it was replacing.

To get more accustomed to new application, I started looking at simple bugs. My first bug was a simple mapping error towards an external system. I quickly found the offending code, and changed the implementation. My change should have broken some tests, but instead of assertion failures I kept getting weird NPEs from data that could not possibly be null.

Testing the tests

Weirded out, I started looking into the test suite. The tests all looked something like this:


class MapperTest {

   @InjectMocks
   Mapper mapper;
   
   @Mock
   SubMapper mockedSubMapper;
   @Mock
   SubMapper2 mockedSubMapper2;
   
   @Mock
   NuValue next;
   
   @Mock
   Value value;
   public void testMock() {
         when(value.getFoo()).thenReturn("Foo");
         when(value.getBar()).thenReturn("Bar");
         when(mockedSubMapper.map(any())).thenReturn(next);
         when(mockedSubMapper2.map(any())).thenReturn(next);

         NuValue nu = mapper.mapMaiStuff(value);
         assertNonNull(nu); 
   }

}

What does this do:

  • @InjectMocks will when hit by the MockitoRunner, instantiate the @InjectMocks annotated class, grab the relevant @Mock classes and add them to the @InjectMocks annotated one.
  • All the when().thenReturn() then create the mock behavior as well as build return values. Essential re implementing or ignoring most of the behavior that should be under test.

Even this simplified example is hard to read, but the tests I was dealing with, had when() mock statements that went on and on, and there were from 2-10 mocked dependencies, and several levels of mocked value objects.

What does this have to do with dependency injection and Spring? Is it not excessive mocking that is the problem?

The responsibility for this mess lies with the developers, but I think it is interesting to try to understand how they ended up in this dark alley. I think mocking is a symptom and not a cause here.

Much of the cause in my opinion lies with Spring. Spring dependency injection can be done by constructor, setter, or field injection. The classes I had trouble with all used field injection. They looked a lot like this.

@Component
class Mapper {

   @Inject
   private SubMapper subMapper;
   
   @Inject
   private SubMapper1 subMapper1;

   public NuValue map(AllTheData data)
       String v1 = subMapper.map(data);
       String v2 = subMapper1.map(data);
       return new NuValue(v1,v2);
   }

}

The mocking was done because the class itself can not be properly constructed without some magic. The only way to test here is to either fire up Spring (slow) or use something to reach in and set the dependencies. One way is to use Mockito @InjectMocks.

While this partly explains what happened, it does not explain why the value objects were mocked.

I think the value objects were mocked because some of these methods take very large value objects as input. The code under test only reads a very small part of the huge object. This means the test now needs to create that huge value object, which is tedious. So someone came up with mocking the value objects, and rewiring them using Mockito. (This essentially means the value object has been re implemented).

Both these practices seemed to have been adopted as convention. The result was:

  • Tests that were clinging to the existing class structure, but that did not test anything useful. Mostly they tested themselves and Mockito. They tried to test some useful cases though, so they could not just be deleted.
  • Extremely low development velocity. Every change to one of these classes caused a chain reaction of tests that had to be either hacked so that they compiled, or fully rewritten. Fully rewriting a test often caused other chain reactions of changes that were really hard to manage.
  • It took close to half a year to get most of this code in an halfway acceptable shape with decent test coverage.

Most of these classes were refactored to pure functions. The classes were mostly transforming data from one representation to another. There was no need to involve Spring at all.

For some reason whenever I see Spring projects, they all manage way too much using Spring. My hypothesis is that once an annotation based DI framework is in use, using it becomes an alluring path of least resistance. It is so easy to copy an existing class with @Component, and hack from there, instead of thinking about the design.

Closing thoughts

This and other experience has fueled a strong skepticism against annotation based dependency injection frameworks in me. I have found that they are not needed most of the time. They can be used responsibly, but are they worth it? In my experience they create just as many problems as they solve.

To be fair, Spring seems to not use field injection in their documentation anymore. That said, Spring does define what can be done. Field injection at best saves 3-5 lines of code for each dependency, and it is never the right thing to do. Spring should just crash at startup if it detects field injection, that would be sane.

As far as Mockito goes, I think it was mostly innocent in this story, though I do think @InjectMocks should log warnings when it has to break the class contract to add mocks. During all of this, I also had the displeasure to learn what Mockito.RETURNS_DEEP_STUBS does. The documentation has this gem though (A a redeeming factor in my eyes.):

WARNING: This feature should rarely be required for regular clean code! Leave it for legacy code. Mocking a mock to return a mock, to return a mock, (…), to return something meaningful hints at violation of Law of Demeter or mocking a value object (a well known anti-pattern).

Good quote I’ve seen one day on the web: every time a mock returns a mock a fairy dies.

Pauper tribal – A fresh MTG format

A tribal pauper game in cockatrice
A pauper-tribal example game in Cockatrice

One of the things I find most fun about Magic The Gathering is exploring deck construction under new constraints. Me and some friends are currently exploring a format which have these rules.

Rules

  • Normal constructed magic rules. Decks are 60 cards, players start with 20 life, 15 card sideboards, and so on.
  • Only cards that are legal in Pauper and not on the Pauper tribal ban list can be played.
  • The deck must at all times contain 20 cards from the same tribe. Tribal instants and changeling cards count towards this total.
  • The chosen tribe can not be Elf, Human or Goblin. This restriction is to ensure other tribes are feasible.

Ban list

The point of a format is to explore magic in an interesting way. If single cards dominate or are too obvious choices, they might end up here.

My thoughts so far

I really like that the constraints for this format are so simple. It is easy to make a format that is fresh, but where the constraints are complex. For some reason such complex constraints make a format feel inelegant and less appealing to me.

Babynavnvelgeren – Fast exploration of Norwegian given names

My good friend Feda Curic recently came to me and wanted to make something together during his parental leave. At first we started out with something a bit too ambitious (for the time we had set aside), but then his wife came up with a great idea we could finish in our limited amount of time.

She wanted an app where you could quickly look up names for babies. Here in Norway Statistisk sentralbyrå (SSB) has statistics for all names used 4 or more times. The SSBs user interface leaves something to be desired though. It is either small lists containing some names, or a name search, where you input the exact name, and then get statistics about that specific name.

The SSB interface is not at all useful for exploratory search for names. In Babynavnvelgeren (the app we made) we have a lightning fast interactive search and filtering options. The data is available locally in the app, so it mostly works offline as well.

The very simple but effective UI of Babynavnvelgeren

Babynavnvelgeren makes searching for names easy and fun. My 8 year old daughter loves searching while sorting for the least popular names. She found some very interesting ones like:

  • Sau – Sheep in Norwegian.
  • Lillebil – I initially thought this was a bug for sure, but it is a name. My daughter finds it hilarious (“Lille” means small and “bil” is car in Norwegian).

More generally I think Interactivity and responsiveness is essential for exploration, and the process of exploration often leads to accidental discoveries and new hypothesis building. UIs which support this kind of interactivity are very useful in my experience, and I think more applications/data providers should have this in mind when presenting their data.

I also think there is a lot of low hanging fruit in this space, and small improvements in interactivity often cause massive increases in efficiency. For Norwegian names, Babynavnvelgeren has got you covered. Go get it!