Mar 10 2022
|Authors:||Sergey Mitryukovskiy, Danny E. P. Vanpoucke, Yue Bai, Théo Hannotte, Mélanie Lavancier, Djamila Hourlier, Goedele Roos and Romain Peretti|
|Journal:||Physical Chemistry Chemical Physics 24, 6107-6125 (2022)|
|Graphical Abstract: Comparison of the measured THz spectrum of 3 phases of Lactose-Monohydrate to the calculated spectra for several Lactose configurations with varying water content.|
The nanoscale structure of molecular assemblies plays a major role in many (µ)-biological mechanisms. Molecular crystals are one of the most simple of these assemblies and are widely used in a variety of applications from pharmaceuticals and agrochemicals, to nutraceuticals and cosmetics. The collective vibrations in such molecular crystals can be probed using terahertz spectroscopy, providing unique characteristic spectral fingerprints. However, the association of the spectral features to the crystal conformation, crystal phase and its environment is a difficult task. We present a combined computational-experimental study on the incorporation of water in lactose molecular crystals, and show how simulations can be used to associate spectral features in the THz region to crystal conformations and phases. Using periodic DFT simulations of lactose molecular crystals, the role of water in the observed lactose THz spectrum is clarified, presenting both direct and indirect contributions. A specific experimental setup is built to allow the controlled heating and corresponding dehydration of the sample, providing the monitoring of the crystal phase transformation dynamics. Besides the observation that lactose phases and phase transformation appear to be more complex than previously thought – including several crystal forms in a single phase and a non-negligible water content in the so-called anhydrous phase – we draw two main conclusions from this study. Firstly, THz modes are spread over more than one molecule and require periodic computation rather than a gas-phase one. Secondly, hydration water does not only play a perturbative role but also participates in the facilitation of the THz vibrations.
Feb 27 2022
Python, as any other scripting language allows you to define variables and functions. These are very basic entities when it comes to programming. However, sometimes it is useful to keep variables and functions that are related to one-another close together. This is the main idea behind Object Oriented programming and is present in programming languages such as C++ and fortran, but also in scripting languages like java and python. In this tutorial, you can find a first brief introduction into this topic, focusing on the concept of a class.
1. The Python class
A class is a complex variable type, which contains specific methods (or functions) and attributes (or properties). An instance of such a complex variable is called an object, and different objects can have different values for their attributes (and even methods).
To create a class in python the class keyword is used followed by the name you want to assign your class. In our case this is the WordleAssistant class.
This WordleAssistant contains the attributes relevant to our puzzle solver. For example, if we want to make a generic solver, two useful attributes would be the wordle word length (WordleSize) and a dictionary of possible words (FullWordset). Unlike fortran or C++, attributes are not defined in the class definition, but can be dynamically created for a class-object. This a feature (or design flaw) gives rise to some dangerous practices such as the runtime (accidental) addition of attributes to an object. For good practices, one should refrain from this and create all attributes by initializing them during the initialization of the class instance. This is done using the __init__() method of the class:
class WordleAssistant(): def __init__(self, size: int = 5, dictionary: str = None): self.WordleSize = size if dictionary is None: dictionary = "Mydict.txt" self.FullWordset = self.readDictionary(dictionary)
Here the WordleSize attribute is defined by setting it to the size parameter of the __init__ method, while the FullWordset attribute is defined by assigning it the result of the readDictionary method of the WordleAssistant class. As is common (and good) practice in OO langues we use the self variable to indicate the instance of the class, binding attributes and methods to the instance. You may also have noted python uses a dot-notation to indicate attributes/methods of a class, similar as C++ (while fortran uses the % symbol with the same effect).
!! NOTE: There also exist “class attributes” which are defined the way one would define instance attributes in fortran or C++. However, in python these attributes are shared by all instances of the class, as such changing them in one object will change them in all objects, creating a mess.
In the previous section, we already defined a first method, the initialization method. As a method is a function, it is constructed as any other function in python using the def keyword, with the body indented. The method itself is indented one level with respect to the class level. Similar as for a usual function, one can indicate the expected type and default value for each function parameter, and if a result is returned the type can be indicated as well, as can be seen in the example below for the readDictionary method.
class WordleAssistant(): def __init__(self, size: int = 5, dictionary: str = None): ... def readDictionary(self, wordlist: str = None)->list: ... return wordlist
Although private attributes and methods don’t technically exist in Python, it is convention that attributes and methods prefixed with a single underscore are to be treated as non-public parts of the API. In addition, using two or more underscores gives rise to name mangling, which gives a practical behavior akin to making attributes and methods private. The __init__ method above is an example. We will come back to this when discussing inheritance and child classes.
2. The Python Object
Once the class is implemented, it can be used in a script by creating instances of the class. These instances are called Objects.
WA = WordleAssistant()
The above command creates an object WA which is of the class WordleAssistant. The object is initialized through a call to the __init__ method, which is performed by the assignment above. If defaults are provided for all parameters of the __init__ method, then no variables need to be passed to the WordleAssistant class call. Otherwise the creation of an instance could look like this:
wordleSize = 5 WA = WordleAssistant(size=wordleSize,dictionary='MyWords.txt')
Access to the attributes and methods of the WA object s gained using the dot-notation:
wordsize = WA.WordleSize wordlist = WA.FullWordset Top10Guess = WA.getTop(top = 10)
Within the context of data-encapsulation one should never access attributes directly but use get and set methods instead.
3. Additional sources:
Feb 16 2022
Over that last few months the wordle game has become increasingly popular, with people sharing their daily feats on Twitter. Currently the game is hosted by the NY times which bought it the end of January 2022 from its creator. The game is rather straightforward: you have 6 guesses to find a 5-letter English word. Every guess, the game tells you if a letter is (1) not in the word [grey], (2) in the word at a different position [yellow/orange], or (3) in the word at the exact same position [green].
|Wordle 242 4/6
|An example of the result (as it looks when shared on Twitter). My first guess was the word “PIANO”, which means the A is in the word but at a different position. My second word, “QUERY”, adds the U to the list of letters that are present. With my third guess, “STUCK”, the position of the U and the K are fixed and we now also know the letter C is involved. At this point, I was also stuck, so I got some help of my wordle-assistant program, which taught me there could only be 1 word matching all the information we had: “CAULK“.|
This seamlessly brings me to the central topic of this post: writing a program to help win this game as efficiently as possible. Not terribly original, but it’s a means to an end, as this simple project allows us to explore some more advanced topics in programming in python as well as artificial intelligence.
During this exploration I’ll be including and updating a set of tutorials as well as this post. The python side of the project will focus on efficiency and easy of use and distribution, while the AI side will focus on smart ways predicting the best possible next guess. For the latter, an important caveat is that this means that the program should also work if you’re the last player living on earth, or if you decide to play wordle in a different language or a different number of letters. This means that creating a distribution of the tweeted results of other players and comparing this with the complete set of brute-forced distributions to guess the wordle of the day in a single guess, would not satisfy my definition of AI. It is an interesting Big-data kaggle competition though.
- Classes in Python. This tutorial provides a simple introduction in the concept of classes in python.
- Child Classes. Continuing on the previous we deal now with child classes and the intricacies of function overriding and accessibility.
- Python Library on Github.
- Jupyter Notebook examples.
- Slow Python: Profiling python in Jupyter. We look into profiling a Jupyter notebook script, to find the bottlenecks.
- Slow Python: speeding up copying.
- Distributions of words and letters.
- Information theory of wordle?
The WordleAssistant Library and notebooks.
All tutorial code and jupyter notebooks can be found in this github repository.
Jan 21 2022
|Authors:||Dries De Sloovere, Danny E. P. Vanpoucke, Andreas Paulus, Bjorn Joos, Lavinia Calvi, Thomas Vranken, Gunter Reekmans, Peter Adriaensens, Nicolas Eshraghi, Abdelfattah Mahmoud, Frédéric Boschini, Mohammadhosein Safari, Marlies K. Van Bael, An Hardy|
|Journal:||Advanced Energy and Sustainability Research 3(3), 2100159 (2022)|
|Graphical Abstract: Understanding the electronic structure of Na-TFSI interacting with NMA.|
Sodium-ion batteries are alternatives for lithium-ion batteries in applications where cost-effectiveness is of primary concern, such as stationary energy storage. The stability of sodium-ion batteries is limited by the current generation of electrolytes, particularly at higher temperatures. Therefore, the search for an electrolyte which is stable at these temperatures is of utmost importance. Here, we introduce such an electrolyte using non-flammable deep eutectic solvents, consisting of sodium bis(trifluoromethane)sulfonimide (NaTFSI) dissolved in N-methyl acetamide (NMA). Increasing the NaTFSI concentration replaces NMA-NMA hydrogen bonds with strong ionic interactions between NMA, Na+, and TFSI–. These interactions lower NMA’s HOMO energy level compared to that of TFSI–, leading to an increased anodic stability (up to ~4.65 V vs Na+/Na). (Na3V2(PO4)2F3/CNT)/(Na2+xTi4O9/C) full cells show 74.8% capacity retention after 1000 cycles at 1 C and 55 °C, and 97.0% capacity retention after 250 cycles at 0.2 C and 55 °C. This is considerably higher than for (Na3V2(PO4)2F3/CNT)/(Na2+xTi4O9/C) full cells containing a conventional electrolyte. According to the electrochemical impedance analysis, the improved electrochemical stability is linked to the formation of more robust surface films at the electrode/electrolyte interface. The improved durability and safety highlight that deep eutectic solvents can be viable electrolyte alternatives for sodium-ion batteries.
Dec 31 2021
|Authors:||Danny E. P. Vanpoucke and Sylvia Wenmackers|
|Journal:||Chaos 31, 123131 (2021)|
|pdf:||<Chaos> (Open Access) <ArXiv v1>|
|Graphical Abstract: Examples of Malament’s Mounds, of which the Norton Dome is the special case where α=½.|
We present a method for assigning probabilities to the solutions of initial value problems that have a Lipschitz singularity. To illustrate the method, we focus on the following toy-example: , , and , with a∈]0; 1[. This example has a physical interpretation as a mass in a uniform gravitational field on a dome of particular shape; the case with a = ½ is known as Norton’s dome. Our approach is based on (1) finite difference equations, which are deterministic; (2) elementary techniques from alpha-theory, a simplified framework for non-standard analysis that allows us to study infinitesimal perturbations; and (3) a uniform prior on the canonical phase space. Our deterministic, hyperfinite grid model allows us to assign probabilities to the solutions of the This allows us to assign probabilities to the solutions of the initial value problem in the original, indeterministic model.
May 06 2021
Happy to announce my TEDxUHasselt talk is officially part of the TEDx universe: https://www.ted.com/talks/danny_vanpoucke_the_virtual_lab .
I enjoyed talking about the VirtualLab. Showed examples from atoms to galaxies, from computer-chips to drug-design and from to opinion-dynamics to epidemiology. I looked at the past and and glanced towards the future, where machine learning and artificial intelligence are the new kids on the block.
Apr 04 2021
Recently, I decided to add a custom registration form to my website, as part of an effort to improve and streamline the “HIVE-STM tool experience” 😉 . Up until now, potential users had to directly send me an e-mail, telling me a bit more about themselves and their work. I would then e-mail them the program, and add their information to a user list for future reference (i.e., support and some statistics for my personal entertainment).
This has the drawback that any future user needs to wait until I find the time to reply. To improve on the user-friendliness, I thought it would be nice to automate this a bit. A first step in this process entails making the application a bit more uniform: using an online registration form.
The art of learning something new: Do it from scratch
Searching for specific solutions with regard to creating a custom form in WordPress I was astounded at how often the default suggestion is: “use plugin XXX” or “use tool YYY”. Are we loosing the ability to want to craft something ourselves? Yes of course, there are professional tools available which can be better than anything you yourself can build in a short amount of time…but should it discourage you of trying, and feeling the satisfaction of having created something? I digress.
In the end, I discovered a good quality tutorial (once you get past the reasons why not to do it) and I started a long uphill battle trying to bend WordPress to my will:
- Paste form-code in post ⇒ WP countermove: remove relevant tags essentially killing the form.
- Solution: put the form in a dedicated template ⇒ WP countermove: hard to integrate in existing theme, will be removed upon update of the theme
- Solution: create a child-theme ⇒ WP countermove: interesting exercise is getting the CSS style-sheet to work together with that of the parent theme. (wp_enqueue_style, wp_enqueue_scripts, get_template_directory_uri() and get_stylesheet_directory_uri() saved the day.)
- Add PHP back-end to the form…and deal with the idiosyncrasies of this scripting language. Crashed the website a few time due to missing “;”… error messages would be nice, instead of the blank web-page.
Trying not to torture future users
At this point, the form accepted input, and collected it via the PHP $_POST global variable. En route to this point, I read quite a few warnings about Cross-Site Request Forgery (CSRF) and that one should protect against it. Luckily, the tutorial practically showed how to do this in WordPress using nonces…in contrast to WordPress theme handbook which gives in formation, but not easy to understand if you are new to the subject.
With a basic sense of security, I was aiming at making things user-friendly, i.e., if something goes wrong it would be nice if you do not need to again fill out the form entirely. Searching for ways to keep this information I came across a lot of options, none of which seemed to work (cookies, PHP variables, global variables, etc). The problem appeared to originate from the fact that the information was not persistent. Once the web page started reloading, everything got erased. It was only at this point that I learned about “transients” in WordPress, and using get_transient() and set_transient() resolved all the issues instantaneously. There is only one caveat at this point: If two potential users submit their registration at almost the same time one may end up seeing the registration information of the other. (However, at this time the program is far from famous enough to present any issues, so statistics will save us from this).
Only one thing remained to be done: put all relevant information into two e-mail messages, one to be sent to myself, and one to be sent to the potential user. For this, I made use of the PHP mail() function. It works quite nicely, and after playing around with it for a bit (and convincing myself a nice HTML formatted layout will not work for example in gmail) the setup was complete. That evening, I went to bed, happy with the accomplishment: I had created something.
Too popular for comfort
The next morning, I was amazed to find already several applications for the HIVE-STM program in my mailbox (that is, in addition to my own test runs). These were not sent by real humans, but appeared to be the work of bots just filling out the form and sending it off. This left me a bit puzzled, and I have been looking for the reason why anyone would actually bother writing a bot for this purpose. So far I’ve seen the suggestion that this is to improve the SEO of websites, generate spam-email (to yourself or with you as middleman), DOS-attacks, get access to your SQL database via code injection,…and after all my searches, I start to get the impression this may also be a means of promoting all the plugins, tools, frameworks that block these bots? In roughly each discussion you find, there will be at least one person promoting such a foolproof perfect tool 😯 🙄 …but might just be me.
So how do we deal with these bots, preferably without driving potential users crazy? Reading all the suggestions (which unfortunately provide extremely little information on the actual working and logic of spam-bots themselves) I added, in several rounds, some tricks to block/catch the bots, and have been tracking the submits since the form went live. As you can see there is a steady stream of some 50 bots weekly trying to fill out the form. The higher number in the first week is due to any submission being redirected to the original form page, as such the same bots performed multiple attempts within the time-range of a few minutes. In about two months, I collected the results of 400 registration attempts by bots (and 4 by humans).
Analyzing the results, I learned learned some interesting things.
1. To Captcha or not to Captcha?
One of the first things to add, from a human perspective is “a captcha”. The captcha is manually implemented simple random sum/product/subtraction. It should be easy for humans, but it is annoying as they need to fill out an extra field (and may fill it out incorrectly). Interestingly, 56% of the bots fill out the Captcha correctly. Of course more complicated versions could be implemented or used…but the bottom line is simple: it generally does not do the job, and annoys the actual human being.
2. Bot Trapping for furs?
Going beyond captcha’s, a lot of tutorials suggest the use of a honeypot. One can either make use of automated options of existing frameworks, plugins or …implement these oneself. This option appears to be very successful in targeting bots. The 1% successful cases coincided with the only human submissions. At this point we appear to have a “fool-proof” method for distinguishing between humans and bots.
3. Dropping the bot down the box?
Interestingly, drop-down menu’s with not generally used topics seem to throw off bots as well. The seniority drop-down menu shows failure rates even better than the captcha.
Writing your own form from scratch is a very interesting exercise, and well worth the time if you want to learn more about web-security as well as the inner workings of the framework used for your website. Bots are an interesting nuisance, and captcha’s just bother your user as most bots can easily deal with them. Logging the inputs of the bots does show a wide range in quality of these bots. Some just fill out garbage, while others appear to be quite smart, filling out reasonable answers. Other bots clearly have malignant purposes, which becomes clear from the code they try to plug into the form fields.
Mar 19 2021
Saturday March 20th at 19h00, I have the pleasure of speaking at the TEDxUHasselt 2021 event.
We will visit the virtual lab and I’ll dive into the important questions about computational researchers: Who are we? Why do we like supercomputers…and rubber ducks? And what does the future hold?
Along the way, I’ll touch on the use of computational research for any subject imaginable: from atoms to galaxies, to the spread of diseases as well as opinions.
The entire live-stream is still online available at here. (My presentation starts at ~7’30 😉 ).
Jan 16 2021
“Once upon a time, there was a young researcher studying the formation of Pt nanowires on Ge substrates using quantum mechanical simulations. The results of the experimental counterparts were excellent; they provided Scanning Tunneling Microscopy images of ridiculously high quality …but not really atomistic structural information or detailed electronic band structures. On the other hand, the calculation-software of the young researcher provided only ground state energies and electronic band structures…but no Scanning Tunneling Microscopy images. So the young researcher set out to resolve this discrepancy.”
About 15 years ago, when starting out as a fresh Ph.D. student, I faced this mismatch between what my calculations could do and what my experimental counterparts had on offer. High quality ground state energies are nice, but rather useless in an experimental context governed by meta-stable states and high temperature transitions (especially since DFT represents only 0K results). I had to find a way to connect my calculations directly to the available experimental data, which boiled down to simulating Scanning Tunneling Microscopy (STM) images.
At that time, my programming skills were still nascent, but I felt king of the world knowing both pascal/Delphi and C/C++. I had written toy-programs in both languages, going from a text based battleships in turbo-pascal over a brick-buster game in C/C++using the djgpp compiler and allegro library to create the GUI, and many GUI programs in Delphi (e.g., the programs needed to numerically calculated Bose-Eistein condensation behavior for molecular condensates during my masters thesis). Based on those experiences, I knew that writing a GUI program was much more straight forward in Delphi. So I set out writing my STM program using Delphi in the year(s) 2005-2006**. On the right you can see an screenshot of this program, generated today 15 years later, on the electron density of graphene. The program written in windows XP, ran smoothly and without modification or required recompile on both windows 7 and the current windows 10. Not to bad, if I say so myself. Try that with a python “program” 😈 .
The program was designed to work for my specific use-case at the time: a germanium 001 surface, with a nice rectangular surface unit cell (see figure on the left). This has the unfortunate consequence that systems with a non-rectangular unit cell appear skewed, as is seen for the graphene example above. However, as I never needed such systems myself, no fix was ever included.
After presenting STM results in my first published paper in 2008, I got some questions if it was possible to share the program. I shared the program on an as-is basis: free to use, and I hope it works for you as well, but no support.
Reading the above you may wonder: “Why didn’t you put the source on GitHub, such that other people could collaborate with you on it, and extend it and fix bugs?” The answer is rather simple (and sobering at the same time): GitHub didn’t exist yet when I wrote the program, as it was founded only in February 2008. It grew rapidly since then (surpassing SourceForge in mid 2011), but as I was working on other projects there was no time to support such a setup.
The number of people asking for the program grew steadily, and there was the nagging feeling at the back of my head that I should really clean up the code and make it cross-platform. In 2011, I had a short period when I decided to start from scratch and write the program anew in Java. Unfortunately, my available time ran out, and initial tests showed the program had a hard time reading the large charge-density files fast. So the original Delphi version remained in use being distributed to new users. By September 2012, this program developed for my own purposes had been requested by 100 researchers (which is a lot considering the boundary conditions: (1) needing atomic scale STM simulations and (2) using VASP for DFT calculations), and over 200 researchers had requested it by 2015. Currently, in January 2021, the counter indicates over 400 requests. Still the same piece of software, being used by people I never imagined would be interested on OS’s it was never designed for. Despite its simplicity, this unexpected interest makes me extremely proud. 😎
Thorny roses: Some issues popping up
Given the original intent of the program and its eventual use, one should not be amazed that some issues popped up over the years. However, no serious bugs were encountered (which still amazes me).
- Non-orthogonal surface units: This is the oldest known limitation of the program. It assumes a rectangular surface unit as it uses the direct grid used in the VASP CHGCAR file as a pixel grid. This suited my own purposes well, but is unfortunate for the user studying hexagonal surfaces.
- “Smart” Antivirus software (1): In the early days, I just sent a zipfile with the program and manual to new users. Unfortunately, AVs do not like people mailing executables, leading to mails being blocked. For some time the problem could be circumvented by zipping the zipfile and later even renaming the extension of the second zip round to prevent the AV of trying to look inside. I know, one should not do this and applaud the AVs for protecting their users, as people did spread trojan horses and other viruses like this back in the days. (Who clicks on those strange attachments anyhow?) So we ended up storing the program and zip online with password protection. We are not yet safe of AVs as some still complain about the risks of downloading things of the internet…but at least we are not (yet) back at the automatic shredding of the program.
- “Smart” Antivirus software (2): Did I say the program was written in Delphi? Apparently so were a lot of computer viruses and worms. (Must be a sign of being a nice and easy to use language 🙂 ) With smart AVs training on pieces of code from such fraudulent software it becomes rather hard to write any code using Delphi which has not been part of a virus…and thus your program gets flagged. Some AVs are nice enough to tell the user, and even provide an option to keep the program. Others just shred it without even mentioning it (not cool). This is unfortunately becoming more of a problem. Online multi-virus-scanners give a rather bleak picture, as can be seen below.
- Windows 10: Extending on the previous, windows 10’s anti-virus protection follows suit throwing up warnings and messages of possible security threats.
- Mac and 64bit: Although the program was written for windows, it also runs smoothly in unix environments when using an emulator such as Wine, making the program available to Linux and Mac users as well. Unfortunately since the Mac OS version Catalina, Mac has dropped support for 32bit executables, making it no longer possible to run the 15 year old executable.  Remember that in 2006 64bit programs were new and not generally supported. Furthermore, 32bit executables tend to work smoothly on a 64bit system, they just “waste” half the memory.
The Future of HIVE-STM
Over the years, I’ve often considered it time to clean up the code, and upgrading it. Unfortunately time was always a major issue. In addition, I no longer had a working Delphi compiler so I was lured to the idea of rewriting it in a different programming language (I seriously considered reworking it in fortran, though the easy access to a GUI stopped me from doing this).
The latest issue with Macs and the zealous persecution of Delphi programs by AVs finally got me to the point of starting a full rework of the HIVE-STM program as a hobby project. The maturity of the Lazarus IDE and free-pascal compiler is an important second component. During the summer holidays of 2020, I started porting the original Delphi code to the Lazarus IDE and free-pascal. This successful port gave me the courage to continue working on it, and I am currently performing a full rewrite of the internals (so far things have gone smoothly). The new version will become available via GitHub once I am confident it is working well and a have setup a good method of keeping track of new users.
New years resolution 2021:
“Finally build a new ‘updated’ version of HIVE-STM “
 “Challenge to scientists: does your ten-year-old code still run?“, J.M. Perkel, nature technology feature, august 24th 2020.
 “Formation of Pt-induced Ge atomic nanowires on Pt/Ge(001)“, D.E.P. Vanpoucke & G. Brocks, Phys. Rev. B 77, 241308(R) 2008.