Author: Nico Mittenzwey

Testing Googles Indexing of www.frontiersin.org

foto of a laptop on a desk

On 15th of December 2021 a paper was published on www.frontiersin.org: “The Impact of the COVID-19 Pandemic on Avoidance of Health Care, Symptom Severity, and Mental Well-Being in Patients With Coronary Artery Disease”.

Frontiers is a leading Open Access Publisher and Open Science Platform with multiple peer-reviewed and editorial board led journals.

Neither Google, Bing nor DuckDuckGo did index it until today (24th of December). The paper was posted to ResearchGate on 17th of December. The ResearchGate page was indexed within days by Google, Bing and DuckDuckGo.

Now let’s see how long it will take the search engines to index this post (first published on 24th of December). To test this I will search for “Neither Google, Bing nor DuckDuckGo” and the paper title.

Update 26th of December:

This post was indexed by DuckDuckGo. Google and Bing do not yet show it in their results when searching for “Neither Google, Bing nor DuckDuckGo”. None of the search engines finds the paper.

Update 27th of December:

The Frontiers paper and this post was indexed by Bing. DuckDuckGo now also links to Frontiers when searching for the title. No results from Google yet.

Update 29th of December:

Google indexed this post. However, it still doesn’t find the paper on frontiersin.org

Update 4th ofJanuary:

Google finally indexed the frontiersin.org page.

Conclusion: FrontiersIn.org admins need to look into their SEO.

Free and Easy Horizontal Stacked Bar Graphs with Google Colab / Jupyter (as well as Python and Pandas)

Stacked Bar Graph

Recently, my wife needed to create some stacked bar graphs for her publications. She wasn’t able to find a tool on the internet which allowed her to do this in an easy and shareable way. So I used this opportunity to look into Jupyter Notebooks. These notebooks allow you to document and run code and thus computations on a remote server from your browser and display the results directly in your browser as well

Google offers their version of Jupyter as a free service called Colab. Already having a Google account it was an easy choice to start there. But there are other similar services available on the internet and the code should run there as well (with minimal changes).

The file is quite self explanatory and can be saved within your own Google drive for editing. You can find it here.

The Notebook

Horizontal Stacked Bar Graph

This notebook will create a horizontal stacked bar graph within your browser based on the data you enter below. Just edit the data in 1) and execute the “gray blocks” in 1), 2) and 3) by either pressing “Shift + Enter” or the “Play” button in each blocks top left corner. To see the “Play” button you need to move your mouse over the block.

You can change the design of the graph in 2). This includes the unit which should be displayed on the bar. You will moste likely need to change the position of the legend as it depends on the data and size of the graph. To do this, change the x value of FigLegPosOffset slightly.

The code within a block is written in Python. Everything after a # is considered a comment. So you can add your own comments to your data or your changes.

1) Preparing the Data
Define your data below and execute the block when done. If everything is correct, your data will be displayed as table below the block.

# importing the functions needed to generate the graph 
import pandas as pd

# Axis captions
FigAxiXCap="Cocktails"
FigAxiYCap="Which Cocktail do you want for the Party?"

# Data (beware: the first entry will be displayed last)

## Data Indexes 
DataIndexes = ['Caipirinha', 'Piña Colada', 'Cuba Libre', 'Mai Tai', 'Ipanema', 'Caribbean Night']
## Data Options
DataYesPlease =  [73.2, 23.8, 24.7, 31.2, 56.6, 68.2]
DataSureWhyNot = [20.3, 51.7, 60.3, 19.2,  4.8, 22.3]
DataJustNo =     [ 6.5, 24.5,   15, 59.6, 38.6,  9.5]

## Name of each column (for the legend)
df = pd.DataFrame(data={'Yes, please!': DataYesPlease, 'Sure, why not?': DataSureWhyNot, 'Just no!': DataJustNo})

#-------------------------------------------------------------------------------
#no need to edit below this line
df.index = DataIndexes

# print table for convinience/debugging (transposed)
df

2) Figure Properties

In the block below you can change the format of the figure. When done (or fine with the defaults) execute it to set all properties.

#################
# Figure Design #
#################
#Figure
## Figure Size
FigSizeX = 20
FigSizeY = 5
## Figure background color 
FigBackColor="white"
## Axis Caption Size
FigAxiXCapFontSize=45
FigAxiYCapFontSize=45
## Axis Labels Font Size
FigLabelFontSize=20

# Blocks
## Colormap of the blocks (all Options: https://matplotlib.org/stable/gallery/color/colormap_reference.html)
FigColMap="Pastel2"
## Width of bars (everything above 1 will overlap)
FigBarsWidth=0.8
## FontSize of bar lables
FigBarsFontSize=20
# Data and Captions (needs to be defined)
## Unit to display within bars
FigBarUnit="%"

# Legend
## Legend Font Size
FigLegFontSize=20
## Legend position [best|upper right|upper left|lower left|lower right|right|center left|center right|lower center|upper center|center]
FigLegPos="upper center"
## Figure OffSet (will move the legend box slightly to match actual figure position)
FigLegPosOffset=(1.11, 1.0)

## 3) Generate and Display the Figure
The block below will generate the figure. You do not need to change anything here. Just be sure to execute it again **after changing anything above**.

# define plot type and layout
ax = df.plot(stacked=True, kind='barh', figsize=(FigSizeX, FigSizeY), colormap=FigColMap, width=FigBarsWidth, fontsize=FigBarsFontSize, xlim=[0,100])

# Add labels to the bars 
# Attribution: Trenton McKinney on StackExchange: https://stackoverflow.com/a/60895640/3764407 CC BY-SA 4.0
for rect in ax.patches:
    # Find where everything is located
    height = rect.get_height()
    width = rect.get_width()
    x = rect.get_x()
    y = rect.get_y()
    
    # The width of the bar is the data value and can be used as the label
    label_text = ""
    if width > 4:
      label_text = f'{width:.1f}' + FigBarUnit  ##### use {width:.2f} or {width:.3f} to increase precision  ####
    
    # ax.text(x, y, text)
    label_x = x + width / 2
    label_y = y + height / 2

    # plot only when height is greater than specified value
    if height > 0:
        ax.text(label_x, label_y, label_text, ha='center', va='center', fontsize=FigBarsFontSize)

# Set legend position and style
ax.legend(bbox_to_anchor=FigLegPosOffset, loc=FigLegPos, borderaxespad=0., fontsize=FigLegFontSize)    
# Set y label
ax.set_ylabel(FigAxiXCap, fontsize=FigAxiXCapFontSize)
# Set x label
ax.set_xlabel(FigAxiYCap, fontsize=FigAxiYCapFontSize)
# Set Background Color
ax.set_facecolor(FigBackColor)

3) Generate and Display the Figure
The block below will generate the figure. You do not need to change anything here. Just be sure to execute it again after changing anything above.

define plot type and layout
ax = df.plot(stacked=True, kind='barh', figsize=(FigSizeX, FigSizeY), colormap=FigColMap, width=FigBarsWidth, fontsize=FigBarsFontSize, xlim=[0,100])

# Add labels to the bars 
# Attribution: Trenton McKinney on StackExchange: https://stackoverflow.com/a/60895640/3764407 CC BY-SA 4.0
for rect in ax.patches:
    # Find where everything is located
    height = rect.get_height()
    width = rect.get_width()
    x = rect.get_x()
    y = rect.get_y()
    
    # The width of the bar is the data value and can be used as the label
    label_text = ""
    if width > 4:
      label_text = f'{width:.1f}' + FigBarUnit  ##### use {width:.2f} or {width:.3f} to increase precision  ####
    
    # ax.text(x, y, text)
    label_x = x + width / 2
    label_y = y + height / 2

    # plot only when height is greater than specified value
    if height > 0:
        ax.text(label_x, label_y, label_text, ha='center', va='center', fontsize=FigBarsFontSize)

# Set legend position and style
ax.legend(bbox_to_anchor=FigLegPosOffset, loc=FigLegPos, borderaxespad=0., fontsize=FigLegFontSize)    
# Set y label
ax.set_ylabel(FigAxiXCap, fontsize=FigAxiXCapFontSize)
# Set x label
ax.set_xlabel(FigAxiYCap, fontsize=FigAxiYCapFontSize)
# Set Background Color
ax.set_facecolor(FigBackColor)

4) Download the Figure (from Google Colab)
To export the generated figure use the following block. You can change the file name and type as well as its resolution (dots per inch/DPI).

# Define the file name
FigureFileName="figure"
# Define the type (jpg, png, pdf, svg)
FigureFileType="png"
# Define DPI (setting this too high might result in long wait times and finally an error)
FigureDPI=30

# do not edit below
FigFile=FigureFileName + "." + FigureFileType
ax.figure.savefig(FigFile,dpi=FigureDPI,bbox_inches = 'tight')
from google.colab import files
files.download("/content/" + FigFile )

CUDART Error in Singularity Container Workaround

Singularity is a Linux container system similar (and compatible to) Docker. It’s advantage over Docker is that is was designed to allow users without superuser privileges to run containers within their environment. I recently encountered the following error when running a Nvidia CUDA application within a Singularity container using “singularity run -nv <container>:

CUDART: cudaGetDeviceCount(&deviceCount); = 999 (unknown error)

Workaround: After running /usr/local/cuda/samples/1_Utilities/deviceQuery/deviceQuery outside of the container, the CUDA application within the container ran without any problem.

Fix/Solution: TODO

Finding the NUMA Node of a Nvidia CUDA GPU in Linux

For some applications it might be useful to pin their CPU processes to the NUMA node which is connected to the GPU. To find out which GPU is located at which NUMA node one can use the following script:

for i in $(nvidia-smi -x -q | grep "gpu id" | awk -F "\"" '{print $2}' | awk -F ":" '{print "0000:"  $2 ":"  $3}' | tr '[:upper:]' '[:lower:]'); do echo $i; cat "/sys/bus/pci/devices/$i/numa_node"; done

Pinning the CPU process to the right NUMA node can speed up your application significantly on all Nvidia GPUs like the double precision HPC GPUs Tesla V100, A100 and A10, the professional Quadro RTX GPUs as well as all CUDA capable GeForce GPUs.

Bouldern in der Boulderlounge Chemnitz

climber in Boulderlounge Chemntiz

Waren heute in der Boulderlounge in Chemnitz. Ab 21:00 wurden Routen umgeschraubt, wodurch leider kein entspanntes Bouldern mehr möglich war. In Chemnitz ist insbesondere die Trainingsecke sehr interessant. Als Inspiration für die eigene Bouldertrainingsecke bzw. Klettertrainingsecke haben wir mal zwei Fotos gemacht:

Die Boulderlounge wird im nächsten Jahr in ein neues Gebäude mit “mehr Platz und Licht” umziehen. Wir sind gespannt!

Nachtrag: Die Boulderlounge ist nun schon seit einiger Zeit in der neuen Location angekommen und hat dabei nicht zu viel versprochen. Das lichtdurchflutete neue “alte” Industriegebäude bietet mit 850 qm Kletterfläche zahlreiche Bereiche die das Bouldern sehr Abwechslungsreich machen. Auch die Trainingsecke hat wieder ein neues Gimmick dazubekommen: eine “LED-Wand”, die sich über eine App steuern lässt. Kleine LEDs neben den Griffen zeigen Dir, welcher Griff als nächstes zu greifen ist – leider auf Grund mangelnder Kondition selbst noch nicht ausprobiert.

Also nichts wie hin in die neue Boulderlounge! Als Vorbereitung auf den nächsten Boulder-Ausflug hier noch eine Packliste mit den wichtigsten Utensilien für Indoor in der Halle (oder auch Outdoor am Fels). Solltest Du doch etwas vergessen haben, dann können bestimmte Dinge, auch in der Boulderlounge vor Ort ausgeliehen werden.

Thunderbird / Lightning Kalender mit Google Kalender verbinden und Termineinladung automatisch eintragen

  1. Installation des Provider for Google Calendar AddOns
  2. Neustarten
  3. In Kalenderansicht wechseln
  4. Neuen Kalender anlegen per Rechtsklick in “Kalender” Spalte -> Neuer Kalender -> Netzwerk -> Google Kalender -> GMail-Adresse eingeben -> Bestätigen
  5. Einstellungen -> Erweitert -> Config Editor -> calendar.google.enableEmailInvitations auf “true” und calendar.google.sendEventNotifications auf “true”
  6. Neustarten
  7. Rechtsklick auf Kalender -> Emailadresse auswählen, die Termine eintragen darf.

How to set C, C++ or Fortran compiler for CMake

To use a different compiler (e.g. Intel Compiler, CLANG or PGI) or a different version then CMake uses by default, one can either set environment variables or modify
the CMakeLists.txt file.

CMake evaluates the environment variables CC for the C compiler, CXX for the C++ compiler and FC
for the Fortran compiler:

CC=/path/to/icc cmake ..
CXX=/path/to/icpc cmake ..
FC=/path/to/ifort cmake ..

For a more permanent solution, one can also edit the CMakeLists.txt file:

SET(CMAKE_C_COMPILER /path/to/pgcc)
SET(CMAKE_CXX_COMPILER /path/to/pgc++)
SET(CMAKE_FC_COMPILER /path/to/pgfortran)

BTW: The environment variables LDFLAGS, CFLAGS, CXXFLAGS or FFLAGS are also evaluated by CMake.

SPACK and Intel Parallel Studio: “error while loading shared libraries: libimf.so”

Spack is a package manager for supercomputers, Linux, and macOS. It makes installing scientific software easy. With Spack, you can build a package with multiple versions, configurations, platforms, and compilers, and all of these builds can coexist on the same machine.

However, when using the Intel Compiler as compiler, I got the following error for some packages:

error while loading shared libraries: libimf.so: cannot open shared object file: No such file or directory

To solve this, edit your ~/.spack/linux/compilers.yaml file and set the extra_rpaths to your Intel Compiler libraries directory:

- compiler:
    environment: {}
    extra_rpaths: [/opt/intel/compilers_and_libraries_2018.1.163/linux/compiler/lib/intel64/]
    flags: {}
    modules: []
    operating_system: centos7
    paths:
      cc: /opt/intel/compilers_and_libraries_2018.1.163/linux/bin/intel64/icc
      cxx: /opt/intel/compilers_and_libraries_2018.1.163/linux/bin/intel64/icpc
      f77: /opt/intel/compilers_and_libraries_2018.1.163/linux/bin/intel64/ifort
      fc: /opt/intel/compilers_and_libraries_2018.1.163/linux/bin/intel64/ifort
    spec: intel@18.0.1
    target: x86_64