<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Projects | Joris Paret</title>
    <link>https://jorisparet.github.io/project/</link>
      <atom:link href="https://jorisparet.github.io/project/index.xml" rel="self" type="application/rss+xml" />
    <description>Projects</description>
    <generator>Wowchemy (https://wowchemy.com)</generator><language>en-us</language><lastBuildDate>Sat, 07 Jan 2023 00:00:00 +0000</lastBuildDate>
    <image>
      <url>https://jorisparet.github.io/media/icon_huf5b7e9305d8ca00c36bcf7194f7e4936_69678_512x512_fill_lanczos_center_3.png</url>
      <title>Projects</title>
      <link>https://jorisparet.github.io/project/</link>
    </image>
    
    <item>
      <title>submv</title>
      <link>https://jorisparet.github.io/project/submv/</link>
      <pubDate>Sat, 07 Jan 2023 00:00:00 +0000</pubDate>
      <guid>https://jorisparet.github.io/project/submv/</guid>
      <description>&lt;h1 id=&#34;submv&#34;&gt;submv&lt;/h1&gt;
&lt;p&gt;&lt;strong&gt;submv&lt;/strong&gt; allows you to shift a subtitle file by a given amount to synchronize it to a video stream using a simple command line tool.&lt;/p&gt;
&lt;h2 id=&#34;quickstart&#34;&gt;Quickstart&lt;/h2&gt;
&lt;p&gt;In a console, simply type&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;submv path/to/subtitles.srt -1.5
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;to shift the file &lt;code&gt;subtitles.srt&lt;/code&gt; by -1.5s. By default, it will &lt;strong&gt;overwrite&lt;/strong&gt; the original file.&lt;/p&gt;
&lt;p&gt;More options:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The shifted subtitles can be written to a new file by using the &lt;code&gt;--output&lt;/code&gt; flag (or &lt;code&gt;-o&lt;/code&gt; for short). Example: &lt;code&gt;submv file.srt 2.1 --output new_file.srt&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;The default format is &lt;a href=&#34;https://en.wikipedia.org/wiki/SubRip&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;SubRip&lt;/a&gt; (&lt;code&gt;*.srt&lt;/code&gt; files). Other formats can be read using the &lt;code&gt;--format&lt;/code&gt; flag (or &lt;code&gt;-f&lt;/code&gt; for short). Example: &lt;code&gt;submv file.sub --format sub&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;For certain formats such as &lt;a href=&#34;https://en.wikipedia.org/wiki/MicroDVD&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;MicroDVD&lt;/a&gt; (&lt;code&gt;*.sub&lt;/code&gt; files), the timecodes depend on the video framerate. To account for this, the correct framerate must be specified with the &lt;code&gt;--framerate&lt;/code&gt; flag (or &lt;code&gt;-r&lt;/code&gt; for short). Example: &lt;code&gt;submv file.sub --framerate 30&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;installation&#34;&gt;Installation&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;1.&lt;/strong&gt; From &lt;a href=&#34;https://pypi.org/project/submv/&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;PyPI&lt;/a&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;pip install submv
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;p&gt;&lt;strong&gt;2.&lt;/strong&gt; From the &lt;a href=&#34;https://github.com/jorisparet/submv&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;code repository&lt;/a&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;git clone https://github.com/jorisparet/submv
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;cd submv
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;pip install .
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id=&#34;linux&#34;&gt;Linux&lt;/h4&gt;
&lt;p&gt;The default folder should be under &lt;code&gt;/home/&amp;lt;user&amp;gt;/.local/bin/&lt;/code&gt;. Make sure this location (or the correct one, if different) is included in your &lt;code&gt;$PATH&lt;/code&gt; environment variable to be able to run the scripts from the console. If not, type the following command &lt;code&gt;export PATH=$PATH:/path/to/submv/script/&lt;/code&gt; in the console or add it your &lt;code&gt;.bashrc&lt;/code&gt; file.&lt;/p&gt;
&lt;h4 id=&#34;windows&#34;&gt;Windows&lt;/h4&gt;
&lt;p&gt;The default folder should be under &lt;code&gt;C:\Users\&amp;lt;user&amp;gt;\AppData\Local\Programs\Python\&amp;lt;python_version&amp;gt;\Scripts\&lt;/code&gt;. Make sure this location (or the correct one, if different) is included in your &lt;code&gt;$PATH&lt;/code&gt; environment variable to be able to run the scripts from the console. If not, type the following command &lt;code&gt;set PATH=%PATH%;C:\path\to\submv\script\&lt;/code&gt; in the console, or select &lt;code&gt;Edit the system environment variables&lt;/code&gt; in the search bar, click &lt;code&gt;Environment Variables…&lt;/code&gt;, click &lt;code&gt;PATH&lt;/code&gt;, click &lt;code&gt;Edit...&lt;/code&gt; and add the correct path to the scripts.&lt;/p&gt;
&lt;h2 id=&#34;author&#34;&gt;Author&lt;/h2&gt;
&lt;p&gt;&lt;a href=&#34;https://www.jorisparet.com/&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Joris Paret&lt;/a&gt;&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>hamoco</title>
      <link>https://jorisparet.github.io/project/hamoco/</link>
      <pubDate>Sun, 29 May 2022 00:00:00 +0000</pubDate>
      <guid>https://jorisparet.github.io/project/hamoco/</guid>
      <description>&lt;p&gt;















&lt;figure  &gt;
  &lt;div class=&#34;d-flex justify-content-center&#34;&gt;
    &lt;div class=&#34;w-100&#34; &gt;&lt;img alt=&#34;&#34;
           src=&#34;https://jorisparet.github.io/project/hamoco/logo.svg&#34;
           loading=&#34;lazy&#34; data-zoomable /&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h1 id=&#34;hamoco&#34;&gt;Hamoco&lt;/h1&gt;
&lt;p&gt;&lt;strong&gt;hamoco&lt;/strong&gt; (&lt;em&gt;handy mouse controller&lt;/em&gt;) is a python application that allows you to control your mouse from your webcam using various hand gestures. You have a laptop equipped with a webcam? Well, good news, that&amp;rsquo;s all you need to feel like Tom Cruise in &lt;a href=&#34;https://en.wikipedia.org/wiki/Minority_Report_%28film%29&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Minority Report&lt;/a&gt;! Kind of.&lt;/p&gt;
&lt;h3 id=&#34;demonstration&#34;&gt;Demonstration&lt;/h3&gt;
&lt;p&gt;In the example below, the hand is used to move the pointer, open a file by double-clicking on it, scroll through it, select a paragraph and cut it. The file is then dragged and dropped into a folder.&lt;/p&gt;
&lt;p&gt;















&lt;figure  &gt;
  &lt;div class=&#34;d-flex justify-content-center&#34;&gt;
    &lt;div class=&#34;w-100&#34; &gt;&lt;img src=&#34;https://raw.githubusercontent.com/jorisparet/hamoco/main/images/demo.gif&#34; alt=&#34;&#34; loading=&#34;lazy&#34; data-zoomable /&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 id=&#34;how-does-it-work&#34;&gt;How does it work?&lt;/h3&gt;
&lt;p&gt;By using the power of &lt;a href=&#34;https://pypi.org/project/PyAutoGUI/&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;PyAutoGUI&lt;/a&gt; to control the mouse, &lt;a href=&#34;https://pypi.org/project/opencv-python/&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;OpenCV&lt;/a&gt; to process the video feed, and &lt;a href=&#34;https://google.github.io/mediapipe/&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;MediaPipe&lt;/a&gt; to track hands, &lt;strong&gt;hamoco&lt;/strong&gt; predicts the nature of a hand pose in real-time thanks to a neural network built with &lt;a href=&#34;https://keras.io/&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Keras&lt;/a&gt; and uses it to perform various kinds of mouse pointer actions.&lt;/p&gt;
&lt;h2 id=&#34;installation&#34;&gt;Installation&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;1.&lt;/strong&gt; From &lt;a href=&#34;https://pypi.org/project/hamoco/&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;PyPI&lt;/a&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;pip install hamoco
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;p&gt;&lt;strong&gt;2.&lt;/strong&gt; From the &lt;a href=&#34;https://github.com/jorisparet/hamoco&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;code repository&lt;/a&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;git clone https://github.com/jorisparet/hamoco
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;cd hamoco
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;pip install -r requirements.txt
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;pip install .
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;hr&gt;
&lt;p&gt;The installation copies three scripts in the default script folder of &lt;code&gt;pip&lt;/code&gt;:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;hamoco-run&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;hamoco-data&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;hamoco-train&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h4 id=&#34;linux&#34;&gt;Linux&lt;/h4&gt;
&lt;p&gt;The default folder should be under &lt;code&gt;/home/&amp;lt;user&amp;gt;/.local/bin/&lt;/code&gt;. Make sure this location (or the correct one, if different) is included in your &lt;code&gt;$PATH&lt;/code&gt; environment variable to be able to run the scripts from the console. If not, type the following command &lt;code&gt;export PATH=$PATH:/path/to/hamoco/scripts/&lt;/code&gt; in the console or add it your &lt;code&gt;.bashrc&lt;/code&gt; file.&lt;/p&gt;
&lt;h4 id=&#34;windows&#34;&gt;Windows&lt;/h4&gt;
&lt;p&gt;The default folder should be under &lt;code&gt;C:\Users\&amp;lt;user&amp;gt;\AppData\Local\Programs\Python\&amp;lt;python_version&amp;gt;\Scripts\&lt;/code&gt;. Make sure this location (or the correct one, if different) is included in your &lt;code&gt;$PATH&lt;/code&gt; environment variable to be able to run the scripts from the console. If not, type the following command &lt;code&gt;set PATH=%PATH%;C:\path\to\hamoco\scripts\&lt;/code&gt; in the console, or select &lt;code&gt;Edit the system environment variables&lt;/code&gt; in the search bar, click &lt;code&gt;Environment Variables…&lt;/code&gt;, click &lt;code&gt;PATH&lt;/code&gt;, click &lt;code&gt;Edit...&lt;/code&gt; and add the correct path to the scripts.&lt;/p&gt;
&lt;h3 id=&#34;requirements&#34;&gt;Requirements:&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://pypi.org/project/PyAutoGUI/&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;PyAutoGUI&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://pypi.org/project/numpy/&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;NumPy&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://pypi.org/project/opencv-python/&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;OpenCV&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://google.github.io/mediapipe/&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;MediaPipe&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.tensorflow.org&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;TensorFlow&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;quick-start&#34;&gt;Quick start&lt;/h2&gt;
&lt;h3 id=&#34;running-the-scripts&#34;&gt;Running the scripts&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;hamoco&lt;/strong&gt; is composed of three executable scripts: &lt;em&gt;&lt;a href=&#34;#hamoco-run&#34;&gt;hamoco-run&lt;/a&gt;&lt;/em&gt;, &lt;em&gt;&lt;a href=&#34;#hamoco-data&#34;&gt;hamoco-data&lt;/a&gt;&lt;/em&gt;, and &lt;em&gt;&lt;a href=&#34;#hamoco-train&#34;&gt;hamoco-train&lt;/a&gt;&lt;/em&gt;, that are listed below. Run these scripts directly from the console, &lt;em&gt;e.g.&lt;/em&gt; &lt;code&gt;hamoco-run --sensitivity 0.5 --show&lt;/code&gt;.&lt;/p&gt;
&lt;h3 id=&#34;hamoco-run&#34;&gt;hamoco-run&lt;/h3&gt;
&lt;p&gt;&lt;em&gt;hamoco-run&lt;/em&gt; is the &lt;strong&gt;main application&lt;/strong&gt;. It activates the webcam and allows to use hand gestures to take control of the mouse pointer. Several basic actions can then be performed, such as &lt;em&gt;left click&lt;/em&gt;, &lt;em&gt;right click&lt;/em&gt;, &lt;em&gt;drag and drop&lt;/em&gt; and &lt;em&gt;scrolling&lt;/em&gt;. Note that it requires &lt;strong&gt;a bit of practice&lt;/strong&gt; before getting comfortable with the controls. Various settings can be adjusted to customize the hand controller to your liking, such as the global sensivitity, parameters for motion smoothing and much more. Type &lt;code&gt;hamoco-run --help&lt;/code&gt; for more information on the available options.&lt;/p&gt;
&lt;p&gt;Examples:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;hamoco-run --sensitivity 0.4 --scrolling_threshold 0.2&lt;/code&gt; : adapts the sensitivity and sets a custom threshold value to trigger scrolling motions.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;hamoco-run --min_cutoff_filter 0.05 --show&lt;/code&gt; : sets a custom value for the cutoff frequency used for motion smoothing and opens a window that shows the processed video feed in real-time.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;hamoco-run --scrolling_speed 20&lt;/code&gt; : sets a custom value for the scrolling speed. Note that for a given value, results may differ significantly depending on the operating system.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;hamoco-run --margin 0.2 --stop_sequence THUMB_SIDE CLOSE INDEX_MIDDLE_UP&lt;/code&gt; : adapts the size of the detection margin (indicated by the dark frame in the preview windows using &lt;code&gt;--show&lt;/code&gt;), and changes the sequence of consecutive poses to stop the application.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Configuration files with default values for the control parameters can be found in the installation folder, under &lt;code&gt;hamoco/config/&lt;/code&gt;. Simply edit the file that corresponds to your operating system (&lt;code&gt;posix.json&lt;/code&gt; for &lt;strong&gt;Linux&lt;/strong&gt; and &lt;code&gt;nt.json&lt;/code&gt; for &lt;strong&gt;Windows&lt;/strong&gt;) to save your settings permanently, and hence avoid specifying the parameters by hand in the console.&lt;/p&gt;
&lt;h4 id=&#34;hand-poses--mouse-actions&#34;&gt;Hand poses &amp;amp; Mouse actions:&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;OPEN&lt;/code&gt; : the pointer is free and follows the center of the palm (indicated by the white square) ;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;CLOSE&lt;/code&gt; : the pointer stops all actions. The hand can be moved anywhere in the frame without moving the pointer. This is used to reset the origin of motion (see the &lt;em&gt;nota bene&lt;/em&gt; below) ;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;INDEX_UP&lt;/code&gt; : performs a left-click at the current pointer location. Execute twice rapidly for a double-click ;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;PINKY_UP&lt;/code&gt; : performs a right click at the current pointer location ;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;INDEX_MIDDLE_UP&lt;/code&gt; : holds the left mouse button down and moves the pointer by following the center of the palm. This is used for selection and drag &amp;amp; drop ;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;THUMB_SIDE&lt;/code&gt; : enables vertical scrolling using the first triggering location as origin. Scrolling up or down is done by moving the hand up or down relative to the origin while keeping the same hand pose ;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;N.B.&lt;/strong&gt; note that, much like a real mouse, the recorded motion of the pointer is &lt;em&gt;relative&lt;/em&gt; to its previous position. When your mouse reaches the edge of your mouse pad, you simply lift it and land it back somewhere on the pad to start moving again. Similarly, if your hand reaches the edge of the frame, the pointer will stop moving: simply close your fist and move it back into the frame to reset the origin of motion (exactly like when lifting and moving a real mouse).&lt;/p&gt;
&lt;p&gt;The various hand poses are illustrated below:&lt;/p&gt;
&lt;p&gt;















&lt;figure  &gt;
  &lt;div class=&#34;d-flex justify-content-center&#34;&gt;
    &lt;div class=&#34;w-100&#34; &gt;&lt;img src=&#34;https://raw.githubusercontent.com/jorisparet/hamoco/main/images/hand_poses.jpg&#34; alt=&#34;&#34; loading=&#34;lazy&#34; data-zoomable /&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h4 id=&#34;exiting-the-application&#34;&gt;Exiting the application:&lt;/h4&gt;
&lt;p&gt;There are two ways to exit the application:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;In the preview mode (&lt;code&gt;--show&lt;/code&gt; option enabled), simply click on the preview window and press &lt;code&gt;ESC&lt;/code&gt; ;&lt;/li&gt;
&lt;li&gt;Execute a predetermined sequence of consecutive hand poses. The default sequence can be found in the help message (&lt;code&gt;hamoco-run --help&lt;/code&gt;). A new sequence can be specified with the &lt;code&gt;--stop_sequence&lt;/code&gt; option followed by the consecutive hand poses, or it can simply be changed in the &lt;code&gt;.json&lt;/code&gt; configuration file.&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&#34;hamoco-data&#34;&gt;hamoco-data&lt;/h3&gt;
&lt;p&gt;&lt;em&gt;hamoco-data&lt;/em&gt; activates the webcam and allows to record your own labeled data for hand poses in order to train a custom neural-network-based classification model for the main application. This model can then be used in place of the one provided by default and will be more performant, as it will be trained on your personal and natural hand poses (see &lt;em&gt;&lt;a href=&#34;#hamoco-train&#34;&gt;hamoco-train&lt;/a&gt;&lt;/em&gt;). Type &lt;code&gt;hamoco-data --help&lt;/code&gt; for more information on the available options.&lt;/p&gt;
&lt;p&gt;This application requires two arguments:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;pose&lt;/code&gt;: a string that indicates the type of hand pose you intend to record. It should be one of: &lt;code&gt;OPEN&lt;/code&gt;, &lt;code&gt;CLOSE&lt;/code&gt;, &lt;code&gt;INDEX_UP&lt;/code&gt;, &lt;code&gt;PINKY_UP&lt;/code&gt;, &lt;code&gt;THUMB_SIDE&lt;/code&gt;, &lt;code&gt;INDEX_MIDDLE_UP&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;path_to_data&lt;/code&gt;: path to the folder inside of which you want the recorded data to be saved.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Examples:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;hamoco-data OPEN data/ --delay 1.0&lt;/code&gt; : starts the recording for the &lt;code&gt;OPEN&lt;/code&gt; hand pose, stores the resulting data in the &lt;code&gt;data&lt;/code&gt; folder (provided it exists!), and takes a new snapshot every second.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;hamoco-data INDEX_UP data/ --delay 0.25 --images&lt;/code&gt; : starts the recording for the &lt;code&gt;INDEX_UP&lt;/code&gt; hand pose, stores the resulting data in the &lt;code&gt;data&lt;/code&gt; folder, takes a new snapshot every 0.25s, and saves the images (in addition to the numeric data file used for training the model). Saving images can be useful if you want to manually check if your hand was in a correct position when its numerical data was recorded, and hence keep or remove specific data files accordingly.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;hamoco-data CLOSE data/ --reset --stop_after 200&lt;/code&gt; : starts the recording of the &lt;code&gt;CLOSE&lt;/code&gt; hand pose, stores the resulting data in the &lt;code&gt;data&lt;/code&gt; folder, deletes every previously recorded file for this hand pose, and automatically stop the recording after taking 200 snapshots.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;hamoco-train&#34;&gt;hamoco-train&lt;/h3&gt;
&lt;p&gt;Provided a path to a directory with compatible data, &lt;em&gt;hamoco-train&lt;/em&gt; trains a customizable NN-based classification model to predict a hand pose. This classification model can then be used in the main application in place of the one provided by default. Type &lt;code&gt;hamoco-train --help&lt;/code&gt; for more information on the available options.&lt;/p&gt;
&lt;p&gt;This application requires two arguments:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;path_to_model&lt;/code&gt; : path to save the newly trained model.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;path_to_data&lt;/code&gt; : path to the data folder to use to train the model (see &lt;em&gt;&lt;a href=&#34;#hamoco-data&#34;&gt;hamoco-data&lt;/a&gt;&lt;/em&gt;).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Examples:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;hamoco-train my_custom_model.h5 data/ --hiden_layers 50 25 --epochs 20&lt;/code&gt; : trains and save a model named &lt;code&gt;my_custom_model.h5&lt;/code&gt; that contains two hidden layers (with dimensions 50 and 25 respectively) over 20 epochs, by using the compatible data in the &lt;code&gt;data&lt;/code&gt; folder.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;hamoco-train my_custom_model.h5 data/ --epochs 10 --learning_rate 0.1&lt;/code&gt; : trains and save a model named &lt;code&gt;my_custom_model.h5&lt;/code&gt; with default dimensions over 20 epochs and with a learning rate of 0.1, by using the compatible data in the &lt;code&gt;data&lt;/code&gt; folder.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Your model can then be used in the main application with the &lt;code&gt;--model&lt;/code&gt; flag of &lt;em&gt;&lt;a href=&#34;#hamoco-run&#34;&gt;hamoco-run&lt;/a&gt;&lt;/em&gt;, &lt;em&gt;e.g.&lt;/em&gt; &lt;code&gt;hamoco-run --model &amp;lt;path_to_your_model&amp;gt;&lt;/code&gt; , or you can change the &lt;code&gt;.json&lt;/code&gt; configuration file to point to it.&lt;/p&gt;
&lt;h2 id=&#34;author&#34;&gt;Author&lt;/h2&gt;
&lt;p&gt;&lt;a href=&#34;https://www.jorisparet.com/&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Joris Paret&lt;/a&gt;&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Synth Road</title>
      <link>https://jorisparet.github.io/project/synth-road/</link>
      <pubDate>Fri, 28 Jan 2022 00:00:00 +0000</pubDate>
      <guid>https://jorisparet.github.io/project/synth-road/</guid>
      <description>&lt;p&gt;















&lt;figure  &gt;
  &lt;div class=&#34;d-flex justify-content-center&#34;&gt;
    &lt;div class=&#34;w-100&#34; &gt;&lt;img alt=&#34;&#34; srcset=&#34;
               /project/synth-road/logo_hubc7924bf52b605797180a57e07dea06c_474684_8ee3a0519e0d5514617e91764f8db2af.webp 400w,
               /project/synth-road/logo_hubc7924bf52b605797180a57e07dea06c_474684_4f637fca32d2473f216cbfd89eae1a83.webp 760w,
               /project/synth-road/logo_hubc7924bf52b605797180a57e07dea06c_474684_1200x1200_fit_q100_h2_lanczos_3.webp 1200w&#34;
               src=&#34;https://jorisparet.github.io/project/synth-road/logo_hubc7924bf52b605797180a57e07dea06c_474684_8ee3a0519e0d5514617e91764f8db2af.webp&#34;
               width=&#34;760&#34;
               height=&#34;371&#34;
               loading=&#34;lazy&#34; data-zoomable /&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Synth Road&lt;/em&gt; is an arcade mobile game of obstacle course for Android with &lt;a href=&#34;https://en.wikipedia.org/wiki/Synthwave&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;synthwave&lt;/a&gt; vibes. Money generated from the &lt;strong&gt;optional&lt;/strong&gt; advertisement is donated to NGOs.&lt;/p&gt;
&lt;p&gt;















&lt;figure  &gt;
  &lt;div class=&#34;d-flex justify-content-center&#34;&gt;
    &lt;div class=&#34;w-100&#34; &gt;&lt;img alt=&#34;&#34; srcset=&#34;
               /project/synth-road/screenshot_huaf22aa47176846097c1370633a1b7763_167575_9c919d0d28f0bc78df46291cb3815f4d.webp 400w,
               /project/synth-road/screenshot_huaf22aa47176846097c1370633a1b7763_167575_9a948736c494547099dea9803b1f3934.webp 760w,
               /project/synth-road/screenshot_huaf22aa47176846097c1370633a1b7763_167575_1200x1200_fit_q100_h2_lanczos.webp 1200w&#34;
               src=&#34;https://jorisparet.github.io/project/synth-road/screenshot_huaf22aa47176846097c1370633a1b7763_167575_9c919d0d28f0bc78df46291cb3815f4d.webp&#34;
               width=&#34;380&#34;
               height=&#34;760&#34;
               loading=&#34;lazy&#34; data-zoomable /&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 id=&#34;game-rules&#34;&gt;Game rules&lt;/h2&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li&gt;Hold your finger down at the bottom of the screen and move it to slide the player left and right to avoid the obstacles.&lt;/li&gt;
&lt;li&gt;Collect as many blue bonuses as possible to increase the score multiplier.&lt;/li&gt;
&lt;li&gt;Collect gold bonuses to temporarily become invincible: bash through obstacles and collect as many blue bonuses as possible.&lt;/li&gt;
&lt;li&gt;Use the power buttons to temporarily slow time, shrink the player or disintegrate obstacles.&lt;/li&gt;
&lt;li&gt;Publish your highscores on the leaderboard to compare your results with other players.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&#34;about&#34;&gt;About&lt;/h2&gt;
&lt;hr&gt;
&lt;p&gt;Synth Road is made with &lt;a href=&#34;https://unity.com/&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Unity&lt;/a&gt;. Illustrations, music and sound effects are original creations.&lt;/p&gt;
&lt;h2 id=&#34;author&#34;&gt;Author&lt;/h2&gt;
&lt;hr&gt;
&lt;p&gt;&lt;a href=&#34;https://jorisparet.github.io&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Joris Paret&lt;/a&gt;&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>partycls</title>
      <link>https://jorisparet.github.io/project/partycls/</link>
      <pubDate>Tue, 16 Mar 2021 00:00:00 +0000</pubDate>
      <guid>https://jorisparet.github.io/project/partycls/</guid>
      <description>&lt;p&gt;















&lt;figure  &gt;
  &lt;div class=&#34;d-flex justify-content-center&#34;&gt;
    &lt;div class=&#34;w-100&#34; &gt;&lt;img alt=&#34;&#34;
           src=&#34;https://jorisparet.github.io/project/partycls/logo.svg&#34;
           loading=&#34;lazy&#34; data-zoomable /&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 id=&#34;homepage&#34;&gt;Homepage&lt;/h2&gt;
&lt;p&gt;For more details and tutorials, visit the &lt;a href=&#34;https://www.jorisparet.com/partycls&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;homepage&lt;/a&gt; of the project.&lt;/p&gt;
&lt;h2 id=&#34;quick-start&#34;&gt;Quick start&lt;/h2&gt;
&lt;p&gt;This quick example shows how to use partycls to identify grain boundaries in a polycrystalline system. The system configuration is stored in a &lt;a href=&#34;https://en.wikipedia.org/wiki/XYZ_file_format&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;XYZ&lt;/a&gt; trajectory file with a single frame. We use the local distribution of bond angles around each particle as a structural descriptor and perform a clustering using the &lt;a href=&#34;https://en.wikipedia.org/wiki/K-means_clustering&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;K-Means&lt;/a&gt; algorithm.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kn&#34;&gt;from&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;partycls&lt;/span&gt; &lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Trajectory&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Workflow&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;traj&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Trajectory&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;grains.xyz&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;wf&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Workflow&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;traj&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;descriptor&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;ba&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;clustering&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;kmeans&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;wf&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;run&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;traj&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;0&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;show&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;color&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;label&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;backend&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;ovito&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;















&lt;figure  &gt;
  &lt;div class=&#34;d-flex justify-content-center&#34;&gt;
    &lt;div class=&#34;w-100&#34; &gt;&lt;img src=&#34;https://raw.githubusercontent.com/jorisparet/partycls/master/data/snapshots/grains_labels.png&#34; alt=&#34;&#34; loading=&#34;lazy&#34; data-zoomable /&gt;&lt;/div&gt;
  &lt;/div&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p&gt;The results are also written to a set of files including a labeled trajectory file and additional information on the clustering results. The whole workflow can be tuned and customized, check out the &lt;a href=&#34;https://www.jorisparet.com/partycls/tutorials&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;tutorials&lt;/a&gt; to see how and for further examples.&lt;/p&gt;
&lt;p&gt;Thanks to a flexible system of filters, partycls makes it easy to restrict the analysis to a given subset of particles based on arbitrary particle properties. Say we have a binary mixture composed of particles with types A and B, and we are only interested in analyzing the bond angles of B particles in a vertical slice:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kn&#34;&gt;from&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;partycls&lt;/span&gt; &lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Trajectory&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kn&#34;&gt;from&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;partycls.descriptors&lt;/span&gt; &lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;BondAngleDescriptor&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;traj&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;Trajectory&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;trajectory.xyz&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;D&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;BondAngleDescriptor&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;traj&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;D&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;add_filter&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;species == &amp;#39;B&amp;#39;&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;D&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;add_filter&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;x &amp;gt; 0.0&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;D&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;add_filter&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;x &amp;lt; 1.0&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;D&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;compute&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# Angular correlations for the selected particles&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nb&#34;&gt;print&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;D&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;features&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;We can then perform a clustering based on these structural features and ask for 3 clusters:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-python&#34; data-lang=&#34;python&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;kn&#34;&gt;from&lt;/span&gt; &lt;span class=&#34;nn&#34;&gt;partycls&lt;/span&gt; &lt;span class=&#34;kn&#34;&gt;import&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;KMeans&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;clustering&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;KMeans&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;n_clusters&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;3&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;n&#34;&gt;clustering&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;fit&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;D&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;features&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nb&#34;&gt;print&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s1&#34;&gt;&amp;#39;Cluster membership of the particles&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;n&#34;&gt;clustering&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;n&#34;&gt;labels&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;main-features&#34;&gt;Main features&lt;/h2&gt;
&lt;h3 id=&#34;trajectory-formats&#34;&gt;Trajectory formats&lt;/h3&gt;
&lt;p&gt;partycls accepts several trajectory formats (including custom ones) either through its built-in trajectory reader or via third-party packages, such as &lt;a href=&#34;www.mdtraj.org&#34;&gt;MDTraj&lt;/a&gt; and &lt;a href=&#34;https://framagit.org/atooms/atooms&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;atooms&lt;/a&gt;. The code is currently optimized for small and medium system sizes (of order 10⁴ particles). Multiple trajectory frames can be analyzed to extend the structural dataset.&lt;/p&gt;
&lt;h3 id=&#34;structural-descriptors&#34;&gt;Structural descriptors&lt;/h3&gt;
&lt;p&gt;partycls implements various structural descriptors:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://www.jorisparet.com/partycls/tutorials/descriptors/gr.html&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Radial descriptor&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.jorisparet.com/partycls/tutorials/descriptors/tetra.html&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Tetrahedral descriptor&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.jorisparet.com/partycls/tutorials/descriptors/ba.html&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Bond-angle descriptor&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.jorisparet.com/partycls/tutorials/descriptors/sba.html&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Smoothed bond-angle descriptor&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.jorisparet.com/partycls/tutorials/descriptors/bo.html&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Bond-orientational descriptor&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.jorisparet.com/partycls/tutorials/descriptors/sbo.html&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Smoothed bond-orientational descriptor&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.jorisparet.com/partycls/tutorials/descriptors/labo.html&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Locally averaged bond-orientational descriptor&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.jorisparet.com/partycls/tutorials/descriptors/rbo.html&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Radial bond-orientational descriptor&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.jorisparet.com/partycls/tutorials/descriptors/compact.html&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Compactness descriptor&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.jorisparet.com/partycls/tutorials/descriptors/coord.html&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Coordination descriptor&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;machine-learning&#34;&gt;Machine learning&lt;/h3&gt;
&lt;p&gt;partycls performs feature scaling, dimensionality reduction and cluster analysis using the &lt;a href=&#34;https://scikit-learn.org&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;scikit-learn&lt;/a&gt; package and additional built-in algorithms.&lt;/p&gt;
&lt;h2 id=&#34;dependencies&#34;&gt;Dependencies&lt;/h2&gt;
&lt;p&gt;partycls relies on several external packages, most of which only provide additional features and are not necessarily required.&lt;/p&gt;
&lt;h3 id=&#34;required&#34;&gt;Required&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Fortran compiler (&lt;em&gt;e.g.&lt;/em&gt; &lt;a href=&#34;https://gcc.gnu.org/wiki/GFortran&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;gfortran&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://pypi.org/project/numpy/&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;NumPy&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://scikit-learn.org&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;scikit-learn&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;optional&#34;&gt;Optional&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://www.mdtraj.org&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;MDTraj&lt;/a&gt; (additional trajectory formats)&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://framagit.org/atooms/atooms&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;atooms&lt;/a&gt; (additional trajectory formats)&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://singroup.github.io/dscribe&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;DScribe&lt;/a&gt; (additional descriptors)&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://matplotlib.org/&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Matplotlib&lt;/a&gt; (visualization)&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://ovito.org/&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;OVITO&lt;/a&gt; &amp;lt; 3.7.0 (visualization)&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/avirshup/py3dmol&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Py3DMol&lt;/a&gt; (interactive 3D visualization)&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/joe-jordan/pyvoro&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;pyvoro&lt;/a&gt; or its &lt;a href=&#34;https://framagit.org/coslo/pyvoro&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;memory-optimized fork&lt;/a&gt; for large systems (Voronoi neighbors and tessellation)&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://tqdm.github.io/&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;tqdm&lt;/a&gt; (progress bars)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;documentation&#34;&gt;Documentation&lt;/h2&gt;
&lt;p&gt;Check the &lt;a href=&#34;https://www.jorisparet.com/partycls/tutorials&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;tutorials&lt;/a&gt; to see various examples and detailed instructions on how to run the code, as well as an in-depth presentation of the built-in structural descriptors.&lt;/p&gt;
&lt;p&gt;For a more detailed documentation, you can check the &lt;a href=&#34;https://www.jorisparet.com/partycls/api&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;API&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;installation&#34;&gt;Installation&lt;/h2&gt;
&lt;h3 id=&#34;from-pypi&#34;&gt;From PyPI&lt;/h3&gt;
&lt;p&gt;The latest stable release is available on &lt;a href=&#34;https://pypi.org/project/partycls/&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;PyPI&lt;/a&gt;. Install it with &lt;code&gt;pip&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;pip install partycls
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;from-source&#34;&gt;From source&lt;/h3&gt;
&lt;p&gt;To install the latest development version from source, clone the source code from the official &lt;a href=&#34;https://github.com/jorisparet/partycls&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;GitHub repository&lt;/a&gt; and install it with:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;git clone https://github.com/jorisparet/partycls.git
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nb&#34;&gt;cd&lt;/span&gt; partycls
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;make install
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Run the tests using:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;make &lt;span class=&#34;nb&#34;&gt;test&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;or manually compile the Fortran sources and run the tests:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nb&#34;&gt;cd&lt;/span&gt; partycls/
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;f2py -c -m neighbors_wrap neighbors.f90
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nb&#34;&gt;cd&lt;/span&gt; descriptor/
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;f2py -c -m realspace_wrap realspace.f90
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nb&#34;&gt;cd&lt;/span&gt; ../../
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;pytest tests/
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;support-and-contribution&#34;&gt;Support and contribution&lt;/h2&gt;
&lt;p&gt;If you wish to contribute or report an issue, feel free to &lt;a href=&#34;mailto:joris.paret@gmail.com&#34;&gt;contact us&lt;/a&gt; or to use the &lt;a href=&#34;https://github.com/jorisparet/partycls/issues&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;issue tracker&lt;/a&gt; and &lt;a href=&#34;https://github.com/jorisparet/partycls/pulls&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;pull requests&lt;/a&gt; from the &lt;a href=&#34;https://github.com/jorisparet/partycls&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;code repository&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;We largely follow the &lt;a href=&#34;https://guides.github.com/introduction/flow/&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;GitHub flow&lt;/a&gt; to integrate community contributions. In essence:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Fork the repository.&lt;/li&gt;
&lt;li&gt;Create a feature branch from &lt;code&gt;master&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Unleash your creativity.&lt;/li&gt;
&lt;li&gt;Run the tests.&lt;/li&gt;
&lt;li&gt;Open a pull request.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;We also welcome contributions from other platforms, such as GitLab instances. Just let us know where to find your feature branch.&lt;/p&gt;
&lt;h2 id=&#34;citing-partycls&#34;&gt;Citing partycls&lt;/h2&gt;
&lt;p&gt;If you use partycls in a scientific publication, please consider citing the following article:&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&lt;a href=&#34;https://joss.theoj.org/papers/10.21105/joss.03723&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;partycls: A Python package for structural clustering&lt;/a&gt;. Paret et al., (2021). Journal of Open Source Software, 6(67), 3723&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Bibtex entry:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-go&#34; data-lang=&#34;go&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;err&#34;&gt;@&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;article&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;Paret2021&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nx&#34;&gt;doi&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;10.21105&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;/&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;joss&lt;/span&gt;&lt;span class=&#34;mf&#34;&gt;.03723&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nx&#34;&gt;url&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;https&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;//doi.org/10.21105/joss.03723},
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;  &lt;span class=&#34;nx&#34;&gt;year&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;2021&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nx&#34;&gt;publisher&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;The&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;Open&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;Journal&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nx&#34;&gt;volume&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;6&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nx&#34;&gt;number&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;67&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nx&#34;&gt;pages&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;mi&#34;&gt;3723&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nx&#34;&gt;author&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;Joris&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;Paret&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;and&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;Daniele&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;Coslovich&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nx&#34;&gt;title&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;partycls&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;A&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;Python&lt;/span&gt; &lt;span class=&#34;kn&#34;&gt;package&lt;/span&gt; &lt;span class=&#34;k&#34;&gt;for&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;structural&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;clustering&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nx&#34;&gt;journal&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;Journal&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;of&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;Open&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;Source&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;Software&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;authors&#34;&gt;Authors&lt;/h2&gt;
&lt;p&gt;&lt;a href=&#34;https://www.jorisparet.com/&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Joris Paret&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://www.units.it/daniele.coslovich/&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Daniele Coslovich&lt;/a&gt;&lt;/p&gt;
</description>
    </item>
    
  </channel>
</rss>
