Sunday, October 27, 2019

Finally, the Baltic Nations

Riga Food Market
When I lived in Stockholm, I always wanted to visit the neighbor countries such as the Scandinavian nations and Baltic nations. There were cruises between Stockholm and these nations. Even a cruise to Saint Petersburg in Russia is possible without a visa given that we return to our origin by cruise within 72 hours and we remain in Saint Petersburg for our entire stay.

However, I visited only Helsinki by cruise during those days. Somehow I missed the Baltic countries until I left Europe in 2018. This time, I had a chance to fly to Riga, Latvia, during my recent trip to Munich for the GSoC mentor summit

Riga is colorful and beautiful. I should have visited these Baltic nations in 2013 when I was staying in Stockholm. Somehow I missed them. But this year, I visited all 3 of them, including day trips to Estonia and Lithuania as well. This was also my first time to visit former USSR countries. Baltic countries have nicely transitioned from USSR to EU. Sometimes in the architecture and environment, I was still able to feel USSR style. I loved Riga and its Black Balsam. Now I have finally managed to visit all the Baltic nations. They are worth the visit. Make sure to keep them in your bucket list!

When you have too much time in hand in a random town

The Panevėžys Train Station
Have you have ever had a day trip to a relatively dull town and ended up having too much time in your hand? That's what happened to us when we ended up in Panevėžys, Lithuania, in a bus ride from Riga, Latvia, using Ecolines. We already had a return ticket in slightly later than 10 hours from our arrival time. We ended up having nothing much to do after going on speed walking across the town, exploring the whole town and suburbs by foot, enjoying a proper Lithuanian meal, and exploring their shopping malls. Eventually, we resorted to visiting one interesting cafe, not once - but twice (since we ran out of things to do)!

Due to a 75% discount going on with Ecolines, for journeys between Riga and Vilnius, instead of buying a return ticket to Panevėžys from Riga (would cost 20 Euro), we bought our onward journey from Riga to Vilnius and return trip from Panevėžys to Riga.  The bus has an intermediate stop in Panevėžys. But they check the names when you enter the bus. If you do not enter at the designated stop, they cancel your trip. So we cannot buy a return ticket to Vilnius from Riga (it would cost only 10 Euro). With two tickets (5 Euro from Riga to Vilnius and 11 Euro from Panevėžys to Riga), we paid 16 Euro. Still saved 4 Euro. Yet, we had a risk. In case if no one gets in or gets out at Panevėžys, our bus would take us to Vilnius. Then from Vilnius, we would have to find our way back to either Panevėžys or Riga, by purchasing a connecting return bus. Luckily, the bus indeed stopped in Panevėžys, because there was one (!) person getting down at
Panevėžys.

The way how we explored Panevėžys was interesting, and I am sure I will replicate this in the future often. Eventually, Panevezys got some cult status in my life. It is a small town with lots of lakes and parks. Nice paths to walk around. Quite boring place - yet you have many things to do in the town as well as quick trips to nearby Baltic cities such as Riga or Vilnius. I have also made it into a verb.

Panevėžys
verb.
1. Wander aimlessly, because you have too much time in hand without specific plans.
"We should totally panevėžys tomorrow when we arrive in Panama." 

Exploring a "ghost town"

Beautiful and shallow Baltic Sea in low tides
When we go to a touristic town in the wrong season, it can feel deserted. We had the pleasure to explore Pärnu in Estonia, a summer beach resort in the Baltic sea this October. It felt like a ghost town with cold empty beaches. Most shops and restaurants were closed. One even had a note, "We are closed. We will open in May 2020". We also experienced the freezingly cold Baltic sea by wetting our feet. :P It was still a pleasant experience though.

Saturday, October 26, 2019

Deciding on travel destinations

Salzburg: Typical Europe
After our day trip to Zugspitze and the Baltic trip, we still had time before the GSoC Mentor Summit. We were contemplating Innsbruck and Salzburg. But given the activities in Innsbruck seem similar to Zugspitze, we decided to go with Salzburg. It was a pleasant surprise to see tourists in large amounts in autumn. A contrast to what we witnessed in the Baltic states. Austria is indeed touristic. Anyway, this Austrian town was charming in its true European form. So it surely is not a disappointment to anyone. I still haven't been to Vienna, although I have been to Austria two times by now. Maybe I will visit Austria again in the future again anyway, including Vienna and Innsbruck.

P.S: I found these live cams quite useful.


Zugspitze by public transport

Crossing the border by foot, to Austria ;)
Zugspitze is the tallest mountain summit in Germany. It shares the border with Austria. Since Austria has taller peaks, Zugspitze has more interest from the German side, dubbed as the Top of Germany. This time we visited Zugspitze from Munich, using public transport. It was quite an easy trip, thanks to this blog post. At 2,962 meters, Zugspitze is also the highest elevation I have been in my entire life. Sri Lanka's tallest peak Pidurutalagala is 2,524 m. My other summits, Vall de Nuria, Spain (2013) is at 2,252 m and peaks of Malbun, Liechtenstein (2016) slightly less than 2,000 m. I will wait to see when I will overtake my current highest elevation in the future.

We managed to catch only the 10:32 train to

The summit
Even in these autumn days, Zugspitze had the ice on the glacier and the summit. I believe this must be permafrost that never melts. The glacier was so bright and watching them made me lose eyesight for a few seconds! The snow-capped mountains were reflecting the sunlight from all the angles, making it brighter than directly staring at the sun.

Google Summer of Code Mentor Summit 2019

The mentor summit in full swing
This is the first time the Google Summer of Code (GSoC) mentor summit came outside of the CA/USA, and the first time to Europe. The mentor summit was in Munich this year, and I am back to the summit after 8 years. Last time I represented AbiWord in 2011 in GooglePlex (the GoogleHQ in MountainView, CA, USA). This time, the Department of Biomedical Informatics, Emory University as both the primary organization administrator as well as a mentor. We traveled from Atlanta to Munich for the mentor summit. I am a happy participant of GSoC for 10 years, under various capacities - student, mentor, and organization administrator. I have been with AbiWord, OMII-UK, Emory BMI between 2009 - 2019.

As the mentor summit was in Munich, Google had organized it longer than usual. Usually, the mentor summits were just 2 days. This time, it was 3 days. The first day was a free day for social activity: a visit to Nymphenburg Palace, followed by a scavenger hunt. The remaining 2 days were the actual mentor summit. The format did not change at all, after almost a decade. It was unconference, where we propose our own topics in a post-it note among the available 8+ slots per session. Then folks join a session that they are interested in (or propose a session of their own). This time I coordinated 2 sessions. The first one was on "Universities as mentoring organizations" and the other one was on "The great proposals". The first one had active participation from around 25 mentors, with most of them representing a university or an umbrella organization formed by universities. The second one was a session I coordinated as the last session of GSoC, mostly because the only other session was "Fail your students," and I did not want to end the mentor summit on a negative note.

I enjoyed coordinating the 2 sessions as well as attending some exciting sessions in all the slots. Of course, I missed several sessions that I would like to participate as I can be physically present in only one session in any given timeslot. I met several mentors from multiple mentoring organizations. We also had a few free days in Europe since the mentor summit was just 3 days, and we were in Europe for a week. We used those days to explore Germany, Austria, and the Baltic nations. Quite a packed trip, indeed.

It was a rewarding experience to attend the mentor summit and proactively contribute to the summit. I made connections with many of the mentor summit participants. Please keep in touch, if you are one of those who attended the mentor summit. :)

Friday, October 25, 2019

Me and daylight savings

I have this love-hate relationship with the daylight saving time settings. In the spring, European countries and most US states clocks are moved 1-hour faster. Then in the autumn, the clocks are turned back to the regular time. That means when the sun starts to rise late, when you have to go to work in the darkness, you suddenly get one more hour of sleep. But then, you also lose one more hour in the evening. When you come home, it is already very dark. While I appreciate the attempts to adapt to the seasons, such time changes also create an artificial and abrupt timeshift on a single day. I am not sure whether I love or hate these time changes. However, Europe is getting rid of these timeshifts by 2021. There is always a 2-week difference when EU changes time each semester and when the USA changes. There was a time I was flying from Lisboa to Phoenix via MSP. Interestingly, that day the USA was having the time shifted to summertime. However, Arizona doesn't follow daylight savings. This confused me a bit, together with my delayed luggage. I am waiting to see how different EU countries will choose their permanent times as they bid goodbye to daylight savings.

Wednesday, October 2, 2019

Running a PixelMed DICOM Server

PixelMed has a reference Java implementation of the DICOM specifications. It is quite easy to set up and run PixelMed. This blog post summarizes the steps to get it run quickly.

First, download the source, binary, and dependencies of PixelMed DICOM server. At the time of writing, the latest version can be found here.

$ mkdir pixelmed-src

$ cd pixelmed-src

$ wget http://www.dclunie.com/pixelmed/software/20190626_current/pixelmedjavadicom_sourcerelease.20190626.tar.bz2

$ tar -xvf pixelmedjavadicom_sourcerelease.20190626.tar.bz2


Extract the binary.

$ mkdir ../pixelmed

$ cd ../pixelmed

$ wget http://www.dclunie.com/pixelmed/software/20190626_current/pixelmedjavadicom_binaryrelease.20190626.tar.bz2

$ tar -xvf pixelmedjavadicom_binaryrelease.20190626.tar.bz2

Extract the source and copy testserver.properties from com.pixelmed.server package to the root folder of the binary. The package also has the core class of the DICOM Server.

Adopt the testserver.properties for your needs.

# Where to store the database support files
Application.DatabaseFileName=/tmp/testserverdb

# Where to store the images stored in the database
Application.SavedImagesFolderName=/tmp/testserverimages

# Name to use for external TCP access to database (such a server will not be started if this property is absent)
Application.DatabaseServerName=testserverdb

# The root URL for the WebServer - if missing will default to the fully qualified local host name (which may not always be available, or appropriate for NAT'd external connections from outside the firewall)
WebServer.RootURL=http://192.168.14.45:7091/


# The name of the stylesheet for the WebServer
WebServer.StylesheetPath=stylesheet.css


# The name of the request type to use for displaying instances for the WebServer
# One of INSTANCELIST, IMAGEDISPLAY, or APPLETDISPLAY
WebServer.RequestTypeToUseForInstances=INSTANCELIST


# WebServer.ListeningPort should be set to whatever port the web server listens
# on for incoming connections.
WebServer.ListeningPort=7091


# WebServer.NumberOfWorkers should be set to a sufficient number to manage simulataneous incoming connections
WebServer.NumberOfWorkers=5


# Dicom.StorageSCUCompressionLevel determines what types of compressed Transfer Syntaxes are
# proposed:
#    0 = none
#    1 = propose deflate
#    2 = propose deflate and bzip2 (if bzip2 codec is available)
Dicom.StorageSCUCompressionLevel=0


# Dicom.ListeningPort should be set to whatever port this DicomImageViewer application is to
# listen on to accept incoming associations.
Dicom.ListeningPort=4008

# Dicom.CalledAETitle should be set to whatever this DicomImageViewer application is to
# call itself when accepting an association.
Dicom.CalledAETitle=BMIPACS


# Dicom.CallingAETitle should be set to whatever this DicomImageViewer application is to
# call itself when initiating an association.
Dicom.CallingAETitle=BMIPACS

# Dicom.PrimaryDeviceType should be set to the type of device, e.g., WSD, ARCHIVE.
Dicom.PrimaryDeviceType=ARCHIVE


# Dicom.RemoteAEs is a space or comma separated list of all the available remote AEs;
# each AE may be named anything unique (in this file) without a space or comma; the name
# does not need to be the same as the actual AE title.
#
#Dicom.RemoteAEs=osirix helgray
#
# Each remote AE (listed in Dicom.RemoteAEs) needs to be described by three
# properties:
# Dicom.RemoteAEs.XXXXX.CalledAETitle
# Dicom.RemoteAEs.XXXXX.HostNameOrIPAddress
# Dicom.RemoteAEs.XXXXX.Port
#
# where XXXXX is the name of the AE displayed to the user and used in this file
#

Extract the dependencies and copy the lib folder to the root folder of the binary.



$ mkdir ../pixelmed-dep

$ cd ../pixelmed-dep

$ wget http://www.dclunie.com/pixelmed/software/20190626_current/pixelmedjavadicom_dependencyrelease.20190626.tar.bz2

$ tar -xvf pixelmedjavadicom_dependencyrelease.20190626.tar.bz2

$ cp -r lib/ ../pixelmed
 

$ cd ../pixelmed

$ java -server -Djava.awt.headless=true -Xms128m -Xmx512m -cp ./pixelmed.jar:./lib/additional/hsqldb.jar:./lib/additional/commons-compress-1.12.jar:./lib/additional/vecmath1.2-1.14.jar:./lib/additional/commons-codec-1.3.jar:./lib/additional/jmdns.jar:./lib/additional/aiviewer.jar com.pixelmed.server.DicomAndWebStorageServer testserver.properties

[main] INFO com.pixelmed.server.DicomAndWebStorageServer properties=
{Dicom.PrimaryDeviceType=ARCHIVE, Application.SavedImagesFolderName=tmp, Dicom.CallingAETitle=STORESCP, Dicom.CalledAETitle=STORESCP, Dicom.ListeningPort=11112}

Now, you may see the web view of the PixelMed DICOM viewer from http://192.168.14.45:7091 from your browser.