Merge branch 'devel'
epsi-builds/msspec_python3/pipeline/head There was a failure building this commit
Details
epsi-builds/msspec_python3/pipeline/head There was a failure building this commit
Details
This commit is contained in:
commit
75784d4c01
22
Dockerfile
22
Dockerfile
|
@ -1,22 +1,24 @@
|
||||||
# Get the base Python image
|
# Get the base Python image
|
||||||
FROM python:latest
|
FROM python:latest
|
||||||
|
|
||||||
|
# Install system dependencies
|
||||||
|
RUN apt-get update && apt-get install -y virtualenv gfortran libgtk-3-dev nano
|
||||||
|
|
||||||
|
# Add a non-privileged user
|
||||||
|
RUN useradd -ms /bin/bash -d /opt/msspec msspec
|
||||||
|
|
||||||
# Set the working directory in the container
|
# Set the working directory in the container
|
||||||
WORKDIR /code
|
USER msspec
|
||||||
|
RUN mkdir -p /opt/msspec/code
|
||||||
|
WORKDIR /opt/msspec/code
|
||||||
|
|
||||||
# Fetch the code
|
# Fetch the code
|
||||||
RUN git clone --branch devel https://git.ipr.univ-rennes1.fr/epsi/msspec_python3.git .
|
RUN git clone --branch devel https://git.ipr.univ-rennes1.fr/epsi/msspec_python3.git .
|
||||||
|
#COPY --chown=msspec:msspec . .
|
||||||
# Install system dependencies
|
|
||||||
RUN apt-get update && apt-get install -y virtualenv gfortran libgtk-3-dev
|
|
||||||
|
|
||||||
# Install msspec
|
# Install msspec
|
||||||
ENV PATH=/opt/bin:$PATH
|
ENV PATH=/opt/msspec/.local/bin:$PATH
|
||||||
RUN make install VERBOSE=1 INSTALL_PREFIX=/opt
|
RUN make install VERBOSE=1
|
||||||
|
|
||||||
# Add a non-privileged user
|
|
||||||
RUN useradd -ms /bin/bash msspec
|
|
||||||
USER msspec
|
|
||||||
|
|
||||||
# Run the msspec frontend command on startup
|
# Run the msspec frontend command on startup
|
||||||
ENTRYPOINT ["msspec"]
|
ENTRYPOINT ["msspec"]
|
||||||
|
|
16
Makefile
16
Makefile
|
@ -11,7 +11,7 @@ pybinding:
|
||||||
venv:
|
venv:
|
||||||
ifeq ($(NO_VENV),0)
|
ifeq ($(NO_VENV),0)
|
||||||
@virtualenv --python=$(PYTHON_EXE) --prompt="(msspec-$(VERSION)) " $(VENV_PATH)
|
@virtualenv --python=$(PYTHON_EXE) --prompt="(msspec-$(VERSION)) " $(VENV_PATH)
|
||||||
@$(INSIDE_VENV) pip install --upgrade pip && pip install -r src/pip.freeze
|
$(INSIDE_VENV) wget https://bootstrap.pypa.io/get-pip.py && python get-pip.py && pip install -r src/pip.freeze && rm -f get-pip.py
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
|
||||||
|
@ -27,7 +27,7 @@ devel: venv pybinding wx
|
||||||
@$(INSIDE_VENV) pip install -e src/
|
@$(INSIDE_VENV) pip install -e src/
|
||||||
|
|
||||||
|
|
||||||
wx:
|
_build_wx/wxPython.target:
|
||||||
@$(INSIDE_VENV) echo "Building wxPython for your `python --version 2>&1` under Linux $(DISTRO_RELEASE)..."
|
@$(INSIDE_VENV) echo "Building wxPython for your `python --version 2>&1` under Linux $(DISTRO_RELEASE)..."
|
||||||
# Create a folder to build wx into
|
# Create a folder to build wx into
|
||||||
@mkdir -p _build_wx
|
@mkdir -p _build_wx
|
||||||
|
@ -40,16 +40,22 @@ wx:
|
||||||
cd `ls -d wxPython*/`; \
|
cd `ls -d wxPython*/`; \
|
||||||
pip install requests; \
|
pip install requests; \
|
||||||
python build.py dox etg --nodoc sip build bdist_wheel; \
|
python build.py dox etg --nodoc sip build bdist_wheel; \
|
||||||
ln -s `readlink -f dist/wxPython*.whl` ../; \
|
ln -sf `readlink -f dist/wxPython*.whl` ../; \
|
||||||
fi;
|
fi;
|
||||||
|
# Finally touch a dummy file to avoid phony target
|
||||||
|
@touch _build_wx/wxPython.target
|
||||||
|
|
||||||
|
|
||||||
|
wx: _build_wx/wxPython.target
|
||||||
# Install the wheel
|
# Install the wheel
|
||||||
@$(INSIDE_VENV) cd _build_wx && pip install wxPython*.whl
|
@$(INSIDE_VENV) cd _build_wx && pip install wxPython*.whl
|
||||||
|
|
||||||
|
|
||||||
doc:
|
doc: VENV_PATH = ./_venv
|
||||||
|
doc: venv
|
||||||
@echo "Building pdf and html documentation..."
|
@echo "Building pdf and html documentation..."
|
||||||
@$(INSIDE_VENV) pip install sphinx
|
@$(INSIDE_VENV) pip install sphinx
|
||||||
@+$(INSIDE_VENV) $(MAKE) -C doc/ latexpdf
|
# @+$(INSIDE_VENV) $(MAKE) -C doc/ latexpdf
|
||||||
@+$(INSIDE_VENV) $(MAKE) -C doc/ html
|
@+$(INSIDE_VENV) $(MAKE) -C doc/ html
|
||||||
|
|
||||||
|
|
||||||
|
|
76
README.md
76
README.md
|
@ -4,8 +4,8 @@ Introduction
|
||||||
This is the Python MsSpec version with support for Python 3.x and dynamic memory allocation for Phagen and Spec
|
This is the Python MsSpec version with support for Python 3.x and dynamic memory allocation for Phagen and Spec
|
||||||
|
|
||||||
|
|
||||||
Installation of the devel package
|
Installation
|
||||||
=================================
|
============
|
||||||
|
|
||||||
Requirements
|
Requirements
|
||||||
------------
|
------------
|
||||||
|
@ -42,13 +42,14 @@ you need to install it.
|
||||||
Fetching the code
|
Fetching the code
|
||||||
-----------------
|
-----------------
|
||||||
|
|
||||||
You first need to clone the devel branch with either 2 commands below:
|
You first need to clone the repository with the command below:
|
||||||
|
|
||||||
```Bash
|
```Bash
|
||||||
git clone https://git.ipr.univ-rennes1.fr/epsi/msspec_python3.git
|
git clone https://git.ipr.univ-rennes1.fr/epsi/msspec_python3.git
|
||||||
git checkout devel
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
If you want to pull the devel branch (unstable):
|
||||||
|
|
||||||
```Bash
|
```Bash
|
||||||
git clone --branch devel https://git.ipr.univ-rennes1.fr/epsi/msspec_python3.git
|
git clone --branch devel https://git.ipr.univ-rennes1.fr/epsi/msspec_python3.git
|
||||||
```
|
```
|
||||||
|
@ -61,21 +62,22 @@ One step install
|
||||||
----------------
|
----------------
|
||||||
|
|
||||||
The command below will do all the stuff to install msspec in its dedicated Python
|
The command below will do all the stuff to install msspec in its dedicated Python
|
||||||
virtual environment provided all the above requirements are fullfilled
|
virtual environment provided all the above requirements are fullfilled:
|
||||||
|
|
||||||
|
|
||||||
```Bash
|
```Bash
|
||||||
cd msspec_python3
|
cd msspec_python3
|
||||||
make devel
|
make install
|
||||||
```
|
```
|
||||||
|
|
||||||
This will:
|
This will:
|
||||||
|
|
||||||
- Create a Python virtual environment in the "\_venv" folder inside the msspec\_python3 folder.
|
- Create a Python virtual environment in your '~/.local/src' folder
|
||||||
- Install all the required Python packages in this virtual environment.
|
- Install all the required Python packages in this virtual environment.
|
||||||
- Install (or even maybe build) wxPython for your OS and Python version in this virtual environment.
|
- Install (or even maybe build) wxPython for your OS and Python version in this virtual environment.
|
||||||
- Build the msspec shared librarires.
|
- Build the msspec shared librarires.
|
||||||
- Install msspec in *edit mode* in this virtual environment.
|
- Install the Python msspec package in this virtual environment.
|
||||||
|
- Install a frontend script called 'msspec' in the '~/.local/bin' folder.
|
||||||
|
|
||||||
You can tweak the process by specifying space separated key=value pairs on the command line.
|
You can tweak the process by specifying space separated key=value pairs on the command line.
|
||||||
Allowed keys are:
|
Allowed keys are:
|
||||||
|
@ -89,35 +91,61 @@ Allowed keys are:
|
||||||
- FC, the Fortran compiler to use (gfortran)
|
- FC, the Fortran compiler to use (gfortran)
|
||||||
- F2PY
|
- F2PY
|
||||||
|
|
||||||
|
To install msspec in developpment mode, use:
|
||||||
Work with msspec
|
|
||||||
----------------
|
|
||||||
|
|
||||||
All you need to do each time you want to work with msspec is activating the virtual environment.
|
|
||||||
|
|
||||||
For example, if *virtualenv* was used to create the virtual environment:
|
|
||||||
|
|
||||||
```Bash
|
```Bash
|
||||||
source msspec_python3/_venv/bin/activate
|
cd msspec_python3
|
||||||
|
make devel
|
||||||
```
|
```
|
||||||
|
|
||||||
Then you can launch your script with
|
This will do the same steps as above except that the virtual environment will be located in
|
||||||
|
the "\_venv" folder inside the "msspec\_python3" folder and the frontend script will not be
|
||||||
|
installed.
|
||||||
|
|
||||||
|
|
||||||
|
Working with msspec
|
||||||
|
-------------------
|
||||||
|
|
||||||
|
Use the frontend command to process a Python script with msspec.
|
||||||
|
|
||||||
```Bash
|
```Bash
|
||||||
python myscript.py
|
msspec -p myscript.py
|
||||||
```
|
```
|
||||||
|
|
||||||
|
This will execute the myscript.py inside the msspec virtual environment.
|
||||||
|
|
||||||
|
You can also load a hdf5 file with the '-l' option:
|
||||||
|
|
||||||
|
```Bash
|
||||||
|
msspec -l results.hdf5
|
||||||
|
```
|
||||||
|
|
||||||
|
You can load an iPython console with "msspec -i". It is a good way to modify the virtual environment
|
||||||
|
of MsSpec since you can add or remove packages withe the "%pip" command.
|
||||||
|
|
||||||
|
If you want to activate the MsSpec virtual environment in your current shell session:
|
||||||
|
|
||||||
|
```Bash
|
||||||
|
eval $(msspec -e)
|
||||||
|
```
|
||||||
|
|
||||||
|
You can then run scripts using the 'python' command directly.
|
||||||
|
Type in 'deactivate' to go back to your standard shell.
|
||||||
|
|
||||||
See the online [tutorials](https://msspec.cnrs.fr/tutorials/index.html) for more information on how to use msspec.
|
See the online [tutorials](https://msspec.cnrs.fr/tutorials/index.html) for more information on how to use msspec.
|
||||||
|
|
||||||
When you're done, you can deactivate the virtual environment with
|
|
||||||
|
|
||||||
```Bash
|
|
||||||
deactivate
|
|
||||||
```
|
|
||||||
|
|
||||||
Uninstall MsSpec
|
Uninstall MsSpec
|
||||||
----------------
|
----------------
|
||||||
|
|
||||||
|
To remove MsSpec, use the command:
|
||||||
|
|
||||||
|
```Bash
|
||||||
|
msspec -u
|
||||||
|
```
|
||||||
|
|
||||||
|
This will simply remove the virtual environment folder in '~/.local/src' and the frontend script in '~/.local/bin'.
|
||||||
|
|
||||||
|
|
||||||
When Installed in "devel mode", nothing is created outside the msspec\_python3 folder, so you just have to remove
|
When Installed in "devel mode", nothing is created outside the msspec\_python3 folder, so you just have to remove
|
||||||
that folder to get rid of msspec on your computer
|
that folder to get rid of msspec on your computer
|
||||||
|
|
||||||
|
|
|
@ -44,7 +44,6 @@ clean:
|
||||||
@rm -f source/spectroscopies/common_parameters.inc
|
@rm -f source/spectroscopies/common_parameters.inc
|
||||||
@rm -f source/spectroscopies/ped/ped_parameters.inc
|
@rm -f source/spectroscopies/ped/ped_parameters.inc
|
||||||
@rm -f source/spectroscopies/eig/eig_parameters.inc
|
@rm -f source/spectroscopies/eig/eig_parameters.inc
|
||||||
@rm -f source/downloads.rst
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -258,7 +258,7 @@ texinfo_documents = [
|
||||||
# How to display URL addresses: 'footnote', 'no', or 'inline'.
|
# How to display URL addresses: 'footnote', 'no', or 'inline'.
|
||||||
#texinfo_show_urls = 'footnote'
|
#texinfo_show_urls = 'footnote'
|
||||||
|
|
||||||
custom.generate_download_page()
|
#custom.generate_download_page()
|
||||||
custom.generate_parameters()
|
custom.generate_parameters()
|
||||||
custom.generate_parameters(spectroscopy='PED')
|
custom.generate_parameters(spectroscopy='PED')
|
||||||
custom.generate_parameters(spectroscopy='EIG')
|
custom.generate_parameters(spectroscopy='EIG')
|
||||||
|
|
|
@ -29,6 +29,9 @@ def generate_download_page():
|
||||||
Download and install notes
|
Download and install notes
|
||||||
##########################
|
##########################
|
||||||
|
|
||||||
|
.. warning::
|
||||||
|
The content of this page is outdated. An updated version will be soon available.
|
||||||
|
|
||||||
click :download:`here <{}>` to download the last version of MsSpec and
|
click :download:`here <{}>` to download the last version of MsSpec and
|
||||||
:download:`here <{}>` for this website as a single pdf file
|
:download:`here <{}>` for this website as a single pdf file
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,150 @@
|
||||||
|
|
||||||
|
.. |LINUXSCRIPT| replace:: https://git.ipr.univ-rennes1.fr/epsi/msspec_python3/raw/branch/devel/utils/dockerized/linux/msspec
|
||||||
|
|
||||||
|
|
||||||
|
##########################
|
||||||
|
Download and install notes
|
||||||
|
##########################
|
||||||
|
|
||||||
|
|
||||||
|
************
|
||||||
|
Installation
|
||||||
|
************
|
||||||
|
|
||||||
|
|
||||||
|
There are 2 ways to install MsSpec. You can either:
|
||||||
|
- Use a Docker image. This is, by far, the most straightforward and easy way to work with MsSpec.
|
||||||
|
- Compile your own version for your system.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
1. Using a Docker image
|
||||||
|
-----------------------
|
||||||
|
|
||||||
|
You first need `Docker <https://www.docker.com>`_ to be installed on your system.
|
||||||
|
This is really straightforward. Please see the `Docker documentation
|
||||||
|
<https://docs.docker.com/engine/install/>`_ for more information depending on
|
||||||
|
your OS.
|
||||||
|
|
||||||
|
|
||||||
|
* **For Linux**,
|
||||||
|
|
||||||
|
* Download :download:`this script <../../utils/dockerized/linux/msspec>` and
|
||||||
|
make it executable (with the *chmod u+x msspec* command)
|
||||||
|
|
||||||
|
* Place it in a location known to your $PATH (or add this location to your $PATH if needed).
|
||||||
|
The *~/.local/bin* folder is a good choice.
|
||||||
|
|
||||||
|
* **For Windows**
|
||||||
|
|
||||||
|
* You need a running X server. Download and install `VcXsrv <https://sourceforge.net/projects/vcxsrv/>`_
|
||||||
|
|
||||||
|
* Install the small :download:`MsSpec frontend <../../utils/dockerized/windows/msspec_setup.exe>`
|
||||||
|
|
||||||
|
* While not necessary, it is also a good idea to use a better terminal application than the default one.
|
||||||
|
`Windows Terminal <https://www.microsoft.com/fr-fr/p/windows-terminal/9n0dx20hk701#activetab=pivot:overviewtab>`_
|
||||||
|
may be a good choice.
|
||||||
|
|
||||||
|
* **For Mac**
|
||||||
|
|
||||||
|
* *To be documented*
|
||||||
|
|
||||||
|
|
||||||
|
Open a terminal in Linux, or a powershell in Windows and type in::
|
||||||
|
|
||||||
|
msspec
|
||||||
|
|
||||||
|
The first time you run the command, it will download the msspec image (it may takes several minutes or half an hour
|
||||||
|
depending on your internet connexion).
|
||||||
|
The command will automatically create a new container and start it.
|
||||||
|
As the command was entered without any argument on the command-line, the help message should be printed on the screen
|
||||||
|
|
||||||
|
.. code-block:: text
|
||||||
|
|
||||||
|
Usage: 1) msspec -p [PYTHON OPTIONS] SCRIPT [ARGUMENTS...]
|
||||||
|
2) msspec [-l FILE | -i | -h]
|
||||||
|
3) msspec [bash | reset]
|
||||||
|
|
||||||
|
Form (1) is used to launch a script
|
||||||
|
Form (2) is used to load a hdf5 data file
|
||||||
|
Form (3) is used to control the Docker container/image.
|
||||||
|
|
||||||
|
List of possible options:
|
||||||
|
-p Pass every arguments after this option to the msspec
|
||||||
|
virtual environment Python interpreter.
|
||||||
|
-i Run the interactive Python interpreter within msspec
|
||||||
|
virtual environment.
|
||||||
|
-l Load and display a *.hdf5 data file in a graphical
|
||||||
|
window.
|
||||||
|
-v Print the version.
|
||||||
|
-h Show this help message.
|
||||||
|
|
||||||
|
bash This command starts an interactive bash shell in the
|
||||||
|
MsSpec container.
|
||||||
|
reset This command removes the MsSpec container (but not the
|
||||||
|
image). Changes made in the container will be lost and
|
||||||
|
any new call to msspec will recreate a new fresh container.
|
||||||
|
|
||||||
|
|
||||||
|
2. Compile your own version
|
||||||
|
---------------------------
|
||||||
|
|
||||||
|
To install MsSpec this way, follow the instructions `here <https://git.ipr.univ-rennes1.fr/epsi/msspec_python3/src/branch/devel>`_
|
||||||
|
|
||||||
|
|
||||||
|
***************************
|
||||||
|
Running your Python scripts
|
||||||
|
***************************
|
||||||
|
|
||||||
|
You can run your MsSpec Python scripts (e.g. *my_script.py*) by typing in::
|
||||||
|
|
||||||
|
msspec -p my_script.py
|
||||||
|
|
||||||
|
This command is equivalent to activating the Python virtual environment MsSpec is intsalled in
|
||||||
|
and to run the Python interpreter of that environment (everything that follows the -p option is
|
||||||
|
passed to the python command).
|
||||||
|
|
||||||
|
You can also launch the Interactive Python (iPython) of MsSpec::
|
||||||
|
|
||||||
|
msspec -i
|
||||||
|
|
||||||
|
Inside this interactive session, you can run a script with the command::
|
||||||
|
|
||||||
|
%run my_script.py
|
||||||
|
|
||||||
|
You can interact with your filesystem with the classical *cd*, *ls*, *cp*, *rm*... commands.
|
||||||
|
and you can edit your script with::
|
||||||
|
|
||||||
|
%ed my_script.py
|
||||||
|
|
||||||
|
|
||||||
|
.. warning::
|
||||||
|
|
||||||
|
**If using the Docker image of MsSpec in Linux**, your home folder on the host machine is bind mounted
|
||||||
|
in the same location in the container and your UID and GID are also set so that creating files within
|
||||||
|
your home file hierarchy is totally transparent.
|
||||||
|
|
||||||
|
**If using the Docker image of MsSpec in Windows**, the drive containing your "My Documents" folder on the
|
||||||
|
host machine is bind mounted on the container at the root of the filesystem. For example, if your
|
||||||
|
"My documents" folder on Windows are in 'D:\\Home\\Bob\\MyDocuments', it will be available in the container as
|
||||||
|
'/D/Home/Bob/MyDocuments'. It has two consequences:
|
||||||
|
|
||||||
|
#. The msspec command will fail if running on another drive than the one where is located "My Documents"
|
||||||
|
|
||||||
|
#. You have to specify filenames with the Unix slashes. For example if you want to run the script located
|
||||||
|
in *.\\results\\my_script.py*, you will have to enter *msspec -p ./results/my_script.py*
|
||||||
|
|
||||||
|
|
||||||
|
**************
|
||||||
|
Uninstallation
|
||||||
|
**************
|
||||||
|
|
||||||
|
* **Under Linux**, type in::
|
||||||
|
|
||||||
|
msspec -u
|
||||||
|
|
||||||
|
* **Under Windows**, simply `uninstall the application from the Settings page
|
||||||
|
<https://support.microsoft.com/en-us/windows/uninstall-or-remove-apps-and-programs-in-windows-10-4b55f974-2cc6-2d2b-d092-5905080eaf98>`_.
|
||||||
|
A command window will pop-up and you will have to answer 'y' to remove MsSpec.
|
||||||
|
|
||||||
|
* **Under Mac OS**, *to be documented.*
|
|
@ -7,4 +7,5 @@ FAQ
|
||||||
.. toctree::
|
.. toctree::
|
||||||
|
|
||||||
hemispherical_cluster/hemispherical_cluster
|
hemispherical_cluster/hemispherical_cluster
|
||||||
coverage_report/coverage_report
|
|
||||||
|
.. coverage_report/coverage_report
|
||||||
|
|
|
@ -135,7 +135,6 @@ Table of Contents
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
.. only:: html
|
.. only:: html
|
||||||
|
|
||||||
##################
|
##################
|
||||||
|
|
|
@ -1,124 +0,0 @@
|
||||||
************
|
|
||||||
Installation
|
|
||||||
************
|
|
||||||
|
|
||||||
.. |logowin| image:: windows_icon.png
|
|
||||||
:height: 96px
|
|
||||||
:target: `win10_install_notes`_
|
|
||||||
|
|
||||||
.. |logolinux| image:: linux_icon.png
|
|
||||||
:height: 96px
|
|
||||||
:target: `linux_install_notes`_
|
|
||||||
|
|
||||||
.. |logomac| image:: apple_icon.png
|
|
||||||
:height: 96px
|
|
||||||
:target: `mac_install_notes`_
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
.. admonition:: Select your Operating System to view specific installation instructions
|
|
||||||
|
|
||||||
|logowin| |logolinux| |logomac|
|
|
||||||
|
|
||||||
|
|
||||||
.. _common_install_notes:
|
|
||||||
|
|
||||||
In a terminal window, execute the setup program you've just downloaded.
|
|
||||||
|
|
||||||
.. code-block:: console
|
|
||||||
|
|
||||||
$ sh ./MsSpec-version.setup
|
|
||||||
|
|
||||||
Once the install process has competed, you can launch the MsSpec environnement by typing::
|
|
||||||
|
|
||||||
msspec
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
.. _win10_install_notes:
|
|
||||||
|
|
||||||
For Windows 10
|
|
||||||
==============
|
|
||||||
|
|
||||||
Windows users can install MsSpec through the Windows Subsystem for Linux
|
|
||||||
(also known as bash Ubuntu).
|
|
||||||
|
|
||||||
Below is a short description of the steps to enable this feature. You can
|
|
||||||
have more details `here <https://docs.microsoft.com/en-us/windows/wsl/install-win10>`_.
|
|
||||||
|
|
||||||
Install the Windows Subsystem for Linux
|
|
||||||
---------------------------------------
|
|
||||||
|
|
||||||
1. Turn on Developer Mode
|
|
||||||
Open **Settings -> Update and Security -> For developers**
|
|
||||||
|
|
||||||
.. figure:: win_step1.png
|
|
||||||
:align: center
|
|
||||||
:width: 70%
|
|
||||||
|
|
||||||
Select the Developer Mode radio button
|
|
||||||
|
|
||||||
2. Open a command prompt. Run::
|
|
||||||
|
|
||||||
bash
|
|
||||||
|
|
||||||
.. figure:: win_step2.png
|
|
||||||
:align: center
|
|
||||||
:width: 70%
|
|
||||||
|
|
||||||
Type "y" to accept the license. An Ubuntu system will be installed.
|
|
||||||
|
|
||||||
|
|
||||||
3. Launch a new Ubuntu shell by running *bash* from the command prompt.
|
|
||||||
If this is the first time that the Windows Subsystem for Linux is installed,
|
|
||||||
you will be prompted to create a UNIX user. Simply follow the instructions.
|
|
||||||
This UNIX username and password may be different from your Windows username
|
|
||||||
and password.
|
|
||||||
|
|
||||||
Install an X server
|
|
||||||
-------------------
|
|
||||||
|
|
||||||
To allow graphical windows to popup in this Linux environnement, you need to install
|
|
||||||
an X server. **Xming** is a good choice. Go to `this website <http://www.straightrunning.com/XmingNotes/>`_
|
|
||||||
and download and install the public version 6.9.0.31.
|
|
||||||
|
|
||||||
Don't forget to start the server after the install. You can configure it to always run automatically at
|
|
||||||
the startup.
|
|
||||||
|
|
||||||
Install MsSpec
|
|
||||||
--------------
|
|
||||||
|
|
||||||
Open a Windows command prompt and launch *bash*. For the Xming server to work, you need to modify
|
|
||||||
the DISPLAY environnement variable. Enter this command::
|
|
||||||
|
|
||||||
echo "export DISPLAY=:0" >> ~/.bashrc && source ~/.bashrc
|
|
||||||
|
|
||||||
Then you can launch the setup program::
|
|
||||||
|
|
||||||
cd /where/the/setup/program/was/downloaded
|
|
||||||
sh ./MsSpec-version.setup
|
|
||||||
|
|
||||||
where *version* is the actual version number
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
.. _linux_install_notes:
|
|
||||||
|
|
||||||
For Linux
|
|
||||||
=========
|
|
||||||
|
|
||||||
Ubuntu and Mageia based dstributions are supported by the installer, but any Linux
|
|
||||||
flavour should be able to run MsSpec as long as you have permissions to install
|
|
||||||
all requirements.
|
|
||||||
|
|
||||||
You just need to open a terminal window and execute the setup program.
|
|
||||||
|
|
||||||
|
|
||||||
.. _mac_install_notes:
|
|
||||||
|
|
||||||
For Mac 0S
|
|
||||||
==========
|
|
||||||
|
|
||||||
.. note::
|
|
||||||
to be written...
|
|
|
@ -1,6 +0,0 @@
|
||||||
:orphan:
|
|
||||||
|
|
||||||
.. automodule:: config
|
|
||||||
:members:
|
|
||||||
:undoc-members:
|
|
||||||
:show-inheritance:
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
:orphan:
|
||||||
|
|
||||||
|
.. automodule:: looper
|
||||||
|
:members:
|
||||||
|
:undoc-members:
|
||||||
|
:show-inheritance:
|
|
@ -0,0 +1,6 @@
|
||||||
|
:orphan:
|
||||||
|
|
||||||
|
.. automodule:: version
|
||||||
|
:members:
|
||||||
|
:undoc-members:
|
||||||
|
:show-inheritance:
|
|
@ -1,181 +1,130 @@
|
||||||
# coding: utf-8
|
# coding: utf8
|
||||||
|
|
||||||
from msspec.utils import *
|
|
||||||
from ase.build import bulk
|
from ase.build import bulk
|
||||||
from ase.visualize import view
|
|
||||||
import numpy as np
|
import numpy as np
|
||||||
from msspec.calculator import MSSPEC, XRaySource
|
from msspec.calculator import MSSPEC, XRaySource
|
||||||
from msspec.iodata import Data
|
from msspec.utils import hemispherical_cluster, get_atom_index
|
||||||
from itertools import product
|
|
||||||
|
|
||||||
DATA = None
|
def create_clusters(nplanes=6):
|
||||||
|
def get_AlN_tags_planes(side, emitter):
|
||||||
|
AlN = bulk('AlN', crystalstructure='wurtzite', a=3.11, c=4.975)
|
||||||
|
[atom.set('tag', i) for i, atom in enumerate(AlN)]
|
||||||
|
if side == 'Al':
|
||||||
|
AlN.rotate([0,0,1],[0,0,-1])
|
||||||
|
Al_planes = range(0, nplanes, 2)
|
||||||
|
N_planes = range(1, nplanes, 2)
|
||||||
|
else:
|
||||||
|
N_planes = range(0, nplanes, 2)
|
||||||
|
Al_planes = range(1, nplanes, 2)
|
||||||
|
if emitter == 'Al':
|
||||||
|
tags = [0, 2]
|
||||||
|
planes = Al_planes
|
||||||
|
else:
|
||||||
|
tags = [1, 3]
|
||||||
|
planes = N_planes
|
||||||
|
return AlN, tags, planes
|
||||||
|
|
||||||
def AlN_cluster(emitter_tag, emitter_plane, diameter=0, planes=0, term_anion=True, tetra_down=True):
|
|
||||||
"""
|
|
||||||
This function is a kind of overload of the hemispherical_cluster function with specific attributes
|
|
||||||
to the AlN structure
|
|
||||||
|
|
||||||
:param emitter_tag: An integer that allows to identify the kind of atom to use as the emitter
|
|
||||||
:param emitter_plane: The plane where the emitter is. 0 means the surface.
|
|
||||||
:param diameter: The diameter of the cluster (in Angstroms).
|
|
||||||
:param planes: The total number of planes.
|
|
||||||
:param term_anion: True if the surface plane is anion terminated, False otherwise
|
|
||||||
:param tetra_down: The orientation of the tetrahedral
|
|
||||||
:return:
|
|
||||||
"""
|
|
||||||
|
|
||||||
# create the initial cluster of AlN
|
|
||||||
cluster = bulk('AlN', crystalstructure='wurtzite', a=3.11, c=4.975)
|
|
||||||
|
|
||||||
# tag each atom in the unit cell because they are all in a different chemical/geometrical environment
|
|
||||||
# (0 and 2 for Aluminum's atoms and 1 and 3 for Nitride's atoms)
|
|
||||||
[atom.set('tag', i) for i, atom in enumerate(cluster)]
|
|
||||||
|
|
||||||
# change the orientation of the tetrahedron
|
|
||||||
if not tetra_down:
|
|
||||||
cluster.rotate(180, 'y')
|
|
||||||
|
|
||||||
# From this base pattern, creat an hemispherically shaped cluster
|
|
||||||
cluster = hemispherical_cluster(cluster, emitter_tag=emitter_tag, emitter_plane=emitter_plane, diameter=diameter,
|
|
||||||
planes=planes)
|
|
||||||
|
|
||||||
# Depending on the number of planes above the emitter, the termination may not be the one you wish,
|
|
||||||
# we test this and raise an exception in such a case
|
|
||||||
|
|
||||||
# Get the termination by finding the kind of one atom located at the topmost z coordinate
|
|
||||||
termination = cluster[np.argsort(cluster.get_positions()[:, 2])[-1]].symbol
|
|
||||||
|
|
||||||
# test if the combination of parameters is possible
|
|
||||||
assert (termination == 'N' and term_anion) or (termination == 'Al' and not term_anion), (
|
|
||||||
"This termination isn't compatible with your others parameters, you must change the tag of "
|
|
||||||
"your emitter, the plane of your emitter or your termination")
|
|
||||||
|
|
||||||
return cluster
|
|
||||||
|
|
||||||
def create_clusters(side='Al', emitter='Al', diameter=15, planes=6):
|
|
||||||
clusters = []
|
clusters = []
|
||||||
if side == 'Al':
|
for side in ('Al', 'N'):
|
||||||
term_anion = tetra_down = False
|
for emitter in ('Al', 'N'):
|
||||||
elif side == 'N':
|
AlN, tags, planes = get_AlN_tags_planes(side, emitter)
|
||||||
term_anion = tetra_down = True
|
for emitter_tag in tags:
|
||||||
|
for emitter_plane in planes:
|
||||||
if emitter == 'Al':
|
cluster = hemispherical_cluster(AlN,
|
||||||
tags = (0, 2)
|
emitter_tag=emitter_tag,
|
||||||
level = '2p'
|
emitter_plane=emitter_plane,
|
||||||
ke = 1407.
|
planes=emitter_plane+2)
|
||||||
elif emitter == 'N':
|
cluster.absorber = get_atom_index(cluster, 0, 0, 0)
|
||||||
tags = (1, 3)
|
cluster.info.update({
|
||||||
level = '1s'
|
'emitter_plane': emitter_plane,
|
||||||
ke = 1083.
|
'emitter_tag' : emitter_tag,
|
||||||
|
'emitter' : emitter,
|
||||||
for emitter_tag, emitter_plane in product(tags, range(0, planes)):
|
'side' : side,
|
||||||
nplanes = emitter_plane + 2
|
})
|
||||||
try:
|
clusters.append(cluster)
|
||||||
cluster = AlN_cluster(emitter_tag, emitter_plane, diameter=diameter, planes=nplanes, term_anion=term_anion,
|
print("Added cluster {}-side, emitter {}(tag {:d}) in "
|
||||||
tetra_down=tetra_down)
|
"plane #{:d}".format(side, emitter, emitter_tag,
|
||||||
except AssertionError:
|
emitter_plane))
|
||||||
continue
|
|
||||||
cluster.absorber = get_atom_index(cluster, 0, 0, 0)
|
|
||||||
cluster.info.update({'emitter_plane': emitter_plane,
|
|
||||||
'emitter_tag': emitter_tag,
|
|
||||||
'emitter': emitter,
|
|
||||||
'side': side,
|
|
||||||
'level': level,
|
|
||||||
'ke': ke})
|
|
||||||
clusters.append(cluster)
|
|
||||||
|
|
||||||
return clusters
|
return clusters
|
||||||
|
|
||||||
def compute_polar_scans(clusters, theta=np.arange(-20., 80., 1.), phi=0., data=DATA):
|
|
||||||
|
def compute(clusters, theta=np.arange(-20., 80., 1.), phi=0.):
|
||||||
|
data = None
|
||||||
for ic, cluster in enumerate(clusters):
|
for ic, cluster in enumerate(clusters):
|
||||||
# select the spectroscopy of the calculation and create a new folder for each calculation
|
# Retrieve info from cluster object
|
||||||
side, emitter, tag, plane, level, ke = [cluster.info[k] for k in ('side', 'emitter', 'emitter_tag',
|
side = cluster.info['side']
|
||||||
'emitter_plane', 'level', 'ke')]
|
emitter = cluster.info['emitter']
|
||||||
calc = MSSPEC(spectroscopy='PED', folder='calc{:0>3d}_S{}_E{}_T{:d}_P{:d}'.format(ic, side, emitter, tag,
|
plane = cluster.info['emitter_plane']
|
||||||
plane))
|
tag = cluster.info['emitter_tag']
|
||||||
calc.calculation_parameters.scattering_order = max(1, min(4, plane))
|
|
||||||
|
# Set the level and the kinetic energy
|
||||||
|
if emitter == 'Al':
|
||||||
|
level = '2p'
|
||||||
|
ke = 1407.
|
||||||
|
elif emitter == 'N':
|
||||||
|
level = '1s'
|
||||||
|
ke = 1083.
|
||||||
|
|
||||||
|
calc = MSSPEC(spectroscopy='PED', algorithm='expansion')
|
||||||
|
|
||||||
calc.source_parameters.energy = XRaySource.AL_KALPHA
|
calc.source_parameters.energy = XRaySource.AL_KALPHA
|
||||||
calc.source_parameters.theta = -35
|
calc.source_parameters.theta = -35
|
||||||
|
|
||||||
calc.detector_parameters.angular_acceptance = 4.
|
calc.detector_parameters.angular_acceptance = 4.
|
||||||
calc.detector_parameters.average_sampling = 'medium'
|
calc.detector_parameters.average_sampling = 'medium'
|
||||||
calc.calculation_parameters.path_filtering = 'forward_scattering'
|
|
||||||
|
calc.calculation_parameters.scattering_order = max(1, min(4, plane))
|
||||||
|
calc.calculation_parameters.path_filtering = 'forward_scattering'
|
||||||
calc.calculation_parameters.off_cone_events = 1
|
calc.calculation_parameters.off_cone_events = 1
|
||||||
[a.set('forward_angle', 30.) for a in cluster]
|
[a.set('forward_angle', 30.) for a in cluster]
|
||||||
calc.calculation_parameters.vibrational_damping = 'averaged_tl'
|
|
||||||
[a.set('mean_square_vibration', 0.006) for a in cluster]
|
|
||||||
calc.set_atoms(cluster)
|
calc.set_atoms(cluster)
|
||||||
|
|
||||||
data = calc.get_theta_scan(level=level, theta=theta, phi=phi, kinetic_energy=ke, data=data)
|
data = calc.get_theta_scan(level=level, theta=theta, phi=phi,
|
||||||
|
kinetic_energy=ke, data=data)
|
||||||
dset = data[-1]
|
dset = data[-1]
|
||||||
dset.title = 'Polar scan {emitter:s}({level:s} tag {tag:d}) in plane #{plane:d}'.format(emitter=emitter,
|
dset.title = "\'{}\' side - {}({}) tag #{:d}, plane #{:d}".format(
|
||||||
level=level, tag=tag,
|
side, emitter, level, tag, plane)
|
||||||
plane=plane)
|
|
||||||
for name, value in cluster.info.items():
|
|
||||||
dset.add_parameter(group='AlnTuto', name=name, value=str(value), unit="")
|
|
||||||
#data.save('all_polar_scans.hdf5', append=True)
|
|
||||||
data.save('all_polar_scans.hdf5')
|
|
||||||
|
|
||||||
def analysis(filename='all_polar_scans.hdf5'):
|
return data
|
||||||
data=Data.load(filename)
|
|
||||||
# create datasets to store the sum of all emitter
|
|
||||||
|
def analysis(data):
|
||||||
tmp_data = {}
|
tmp_data = {}
|
||||||
for dset in data:
|
for dset in data:
|
||||||
# retrieve some info
|
info = dset.get_cluster().info
|
||||||
side = dset.get_parameter(group='AlnTuto', name='side')['value']
|
side = info['side']
|
||||||
emitter = dset.get_parameter(group='AlnTuto', name='emitter')['value']
|
emitter = info['emitter']
|
||||||
try:
|
try:
|
||||||
key = '{}_{}'.format(side, emitter)
|
key = '{}_{}'.format(side, emitter)
|
||||||
tmp_data[key] += dset.cross_section
|
tmp_data[key] += dset.cross_section
|
||||||
except KeyError:
|
except KeyError:
|
||||||
tmp_data[key] = dset.cross_section.copy()
|
tmp_data[key] = dset.cross_section.copy()
|
||||||
|
|
||||||
# get the index of theta = 0;
|
tmp_data['theta'] = dset.theta.copy()
|
||||||
it0 = np.where(dset.theta == 0)[0][0]
|
tmp_data['Al_side'] = tmp_data['Al_Al'] / tmp_data['Al_N']
|
||||||
for key, cs in tmp_data.items():
|
tmp_data['N_side'] = tmp_data['N_Al'] / tmp_data['N_N']
|
||||||
tmp_data[key + '_norm'] = cs / cs[it0]
|
|
||||||
|
|
||||||
tmp_data['Al_side'] = tmp_data['Al_Al_norm'] / tmp_data['Al_N_norm']
|
|
||||||
tmp_data['N_side'] = tmp_data['N_Al_norm'] / tmp_data['N_N_norm']
|
|
||||||
|
|
||||||
# now add all columns
|
# now add all columns
|
||||||
substrate_dset = data.add_dset('Total substrate signal')
|
substrate_dset = data.add_dset('Total substrate signal')
|
||||||
substrate_dset.add_columns(theta=dset.theta.copy())
|
|
||||||
substrate_dset.add_columns(**tmp_data)
|
substrate_dset.add_columns(**tmp_data)
|
||||||
|
|
||||||
view = substrate_dset.add_view('Al side',
|
|
||||||
title=r'AlN Polar scan in the (10$\bar{1}$0) azimuthal plane - Al side polarity',
|
|
||||||
xlabel=r'$\Theta (\degree$)',
|
|
||||||
ylabel='Signal (a.u.)')
|
|
||||||
view.select('theta', 'Al_Al_norm', legend='Al 2p')
|
|
||||||
view.select('theta', 'Al_N_norm', legend='N 1s')
|
|
||||||
view.set_plot_options(autoscale=True)
|
|
||||||
|
|
||||||
view = substrate_dset.add_view('N side',
|
|
||||||
title=r'AlN Polar scan in the (10$\bar{1}$0) azimuthal plane - N side polarity',
|
|
||||||
xlabel=r'$\Theta (\degree$)',
|
|
||||||
ylabel='Signal (a.u.)')
|
|
||||||
view.select('theta', 'N_Al_norm', legend='Al 2p')
|
|
||||||
view.select('theta', 'N_N_norm', legend='N 1s')
|
|
||||||
view.set_plot_options(autoscale=True)
|
|
||||||
|
|
||||||
view = substrate_dset.add_view('Ratios',
|
view = substrate_dset.add_view('Ratios',
|
||||||
title=r'Al(2p)/N(1s) ratios on both polar sides of AlN in the (10$\bar{1}$0) '
|
title=r'Al(2p)/N(1s) ratios on both polar '
|
||||||
|
r'sides of AlN in the (10$\bar{1}$0) '
|
||||||
r'azimuthal plane',
|
r'azimuthal plane',
|
||||||
xlabel=r'$\Theta (\degree$)',
|
xlabel=r'$\Theta (\degree$)',
|
||||||
ylabel='Intenisty ratio')
|
ylabel='Intenisty ratio')
|
||||||
view.select('theta', 'Al_side', legend='Al side', where="theta >= 0 and theta <=70")
|
view.select('theta', 'Al_side', legend='Al side',
|
||||||
view.select('theta', 'N_side', legend='N side', where="theta >= 0 and theta <=70")
|
where="theta >= 0 and theta <=70")
|
||||||
|
view.select('theta', 'N_side', legend='N side',
|
||||||
|
where="theta >= 0 and theta <=70")
|
||||||
view.set_plot_options(autoscale=True)
|
view.set_plot_options(autoscale=True)
|
||||||
|
|
||||||
data.save('analysis.hdf5')
|
return data
|
||||||
data.view()
|
|
||||||
|
|
||||||
|
|
||||||
DIAMETER = 10
|
clusters = create_clusters()
|
||||||
PLANES = 4
|
data = compute(clusters)
|
||||||
clusters = create_clusters(side='Al', emitter='Al', diameter=DIAMETER, planes=PLANES) + \
|
data = analysis(data)
|
||||||
create_clusters(side='Al', emitter='N', diameter=DIAMETER, planes=PLANES) + \
|
data.view()
|
||||||
create_clusters(side='N', emitter='Al', diameter=DIAMETER, planes=PLANES) + \
|
|
||||||
create_clusters(side='N', emitter='N', diameter=DIAMETER, planes=PLANES)
|
|
||||||
compute_polar_scans(clusters, phi=0.)
|
|
||||||
analysis()
|
|
||||||
|
|
|
@ -1,54 +1,25 @@
|
||||||
# -*- encoding: utf-8 -*-
|
# coding: utf8
|
||||||
# vim: set fdm=indent ts=4 sw=4 sts=4 et ai tw=80 cc=+0 mouse=a nu : #
|
|
||||||
|
|
||||||
from msspec.calculator import MSSPEC, XRaySource
|
|
||||||
from msspec.utils import *
|
|
||||||
|
|
||||||
|
from msspec.calculator import MSSPEC
|
||||||
from ase.build import fcc111, add_adsorbate
|
from ase.build import fcc111, add_adsorbate
|
||||||
from ase.visualize import view
|
|
||||||
from msspec.iodata import cols2matrix
|
|
||||||
|
|
||||||
from matplotlib import pyplot as plt
|
|
||||||
import numpy as np
|
import numpy as np
|
||||||
import sys
|
|
||||||
|
|
||||||
data = None
|
data = None
|
||||||
all_z = np.arange(1.10, 1.50, 0.02)
|
all_z = np.arange(1.10, 1.65, 0.05)
|
||||||
all_z=(1.1,)
|
|
||||||
for zi, z0 in enumerate(all_z):
|
for zi, z0 in enumerate(all_z):
|
||||||
# construct the cluster
|
# construct the cluster
|
||||||
cluster = fcc111('Rh', size = (2,2,1))
|
cluster = fcc111('Rh', size = (2,2,1))
|
||||||
add_adsorbate(cluster, 'O', z0, position = 'fcc')
|
|
||||||
cluster.pop(3)
|
cluster.pop(3)
|
||||||
#cluster.rotate('z',np.pi/3.)
|
add_adsorbate(cluster, 'O', z0, position = 'fcc')
|
||||||
#view(cluster)
|
|
||||||
|
|
||||||
cluster.absorber = len(cluster) - 1
|
cluster.absorber = len(cluster) - 1
|
||||||
|
|
||||||
calc = MSSPEC(spectroscopy = 'PED', folder = './RhO_z')
|
# Define a calculator
|
||||||
|
calc = MSSPEC(spectroscopy='PED', algorithm='inversion')
|
||||||
calc.set_atoms(cluster)
|
calc.set_atoms(cluster)
|
||||||
calc.calculation_parameters.scattering_order = 3
|
|
||||||
calc.calculation_parameters.RA_cutoff = 1
|
|
||||||
calc.source_parameters.energy = XRaySource.AL_KALPHA
|
|
||||||
|
|
||||||
# compute
|
# Compute
|
||||||
level = '1s'
|
data = calc.get_theta_phi_scan(level='1s', kinetic_energy=723, data=data)
|
||||||
ke = 723.
|
|
||||||
|
|
||||||
|
|
||||||
data = calc.get_theta_phi_scan(level=level, kinetic_energy=ke, data=data)
|
|
||||||
|
|
||||||
# OPTIONAL, this will create an image of the data that you can combine
|
|
||||||
# in an animated gif
|
|
||||||
dset = data[-1]
|
dset = data[-1]
|
||||||
theta, phi, Xsec = cols2matrix(dset.theta, dset.phi, dset.cross_section)
|
dset.title = "{:d}) z = {:.2f} angstroms".format(zi, z0)
|
||||||
X, Y = np.meshgrid(np.radians(phi), 2*np.tan(np.radians(theta/2.)))
|
|
||||||
fig = plt.figure()
|
|
||||||
ax = fig.add_subplot(111, projection='polar')
|
|
||||||
im = ax.pcolormesh(X, Y, Xsec)
|
|
||||||
theta_ticks = np.arange(0, 91, 15)
|
|
||||||
plt.yticks(2 * np.tan(np.radians(theta_ticks/2.)), theta_ticks)
|
|
||||||
plt.title(r"$z_0 = {:.2f} \AA$".format(z0))
|
|
||||||
plt.savefig('image{:03d}.png'.format(zi))
|
|
||||||
|
|
||||||
data.view()
|
data.view()
|
||||||
|
|
|
@ -1,31 +1,17 @@
|
||||||
# -*- encoding: utf-8 -*-
|
# coding: utf8
|
||||||
# vim: set fdm=indent ts=4 sw=4 sts=4 et ai tw=80 cc=+0 mouse=a nu : #
|
|
||||||
|
|
||||||
from msspec.calculator import MSSPEC, XRaySource
|
|
||||||
from msspec.utils import *
|
|
||||||
|
|
||||||
|
from msspec.calculator import MSSPEC
|
||||||
from ase import Atoms
|
from ase import Atoms
|
||||||
|
|
||||||
import numpy as np
|
# Create an atomic chain O-Rh
|
||||||
|
cluster = Atoms(['O', 'Rh'], positions = [(0,0,0), (0,0,4.)])
|
||||||
|
|
||||||
# Defining global variables
|
# Create the calculator
|
||||||
a0 = 6.0
|
calc = MSSPEC(spectroscopy = 'PED')
|
||||||
symbols = ('Rh', 'O')
|
calc.set_atoms(cluster)
|
||||||
ke = 723.
|
cluster.absorber = 0
|
||||||
level = '1s'
|
|
||||||
|
|
||||||
data = None
|
# compute
|
||||||
for symbol in symbols:
|
data = calc.get_scattering_factors(level='1s', kinetic_energy=723)
|
||||||
cluster = Atoms(symbol*2, positions = [(0,0,0), (0,0,a0)])
|
|
||||||
[a.set('mt_radius', 1.5) for a in cluster]
|
|
||||||
|
|
||||||
# Create the calculator
|
|
||||||
calc = MSSPEC(spectroscopy = 'PED')
|
|
||||||
calc.source_parameters.energy = XRaySource.AL_KALPHA
|
|
||||||
calc.set_atoms(cluster)
|
|
||||||
cluster.absorber = 0
|
|
||||||
|
|
||||||
# compute
|
|
||||||
data = calc.get_scattering_factors(level=level, kinetic_energy=ke, data=data)
|
|
||||||
|
|
||||||
data.view()
|
data.view()
|
||||||
|
|
|
@ -82,13 +82,13 @@ Here is the script for the computation. (:download:`download <RhO.py>`)
|
||||||
.. literalinclude:: RhO.py
|
.. literalinclude:: RhO.py
|
||||||
:linenos:
|
:linenos:
|
||||||
|
|
||||||
.. note::
|
.. .. note::
|
||||||
After runing this script, you will get 20 images in your folder. You can merge them in one animated gif image
|
.. After runing this script, you will get 20 images in your folder. You can merge them in one animated gif image
|
||||||
like this:
|
.. like this:
|
||||||
|
..
|
||||||
.. code-block:: bash
|
.. .. code-block:: bash
|
||||||
|
..
|
||||||
convert -delay 50 -loop 0 image*.png animation.gif
|
.. convert -delay 50 -loop 0 image*.png animation.gif
|
||||||
|
|
||||||
.. seealso::
|
.. seealso::
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
# coding: utf-8
|
# coding: utf8
|
||||||
|
|
||||||
from msspec.calculator import MSSPEC
|
from msspec.calculator import MSSPEC
|
||||||
from msspec.utils import *
|
from msspec.utils import hemispherical_cluster, get_atom_index
|
||||||
|
|
||||||
from ase.build import bulk
|
from ase.build import bulk
|
||||||
from ase.visualize import view
|
from ase.visualize import view
|
||||||
|
@ -9,20 +9,15 @@ from ase.visualize import view
|
||||||
a0 = 3.6 # The lattice parameter in angstroms
|
a0 = 3.6 # The lattice parameter in angstroms
|
||||||
|
|
||||||
# Create the copper cubic cell
|
# Create the copper cubic cell
|
||||||
cluster = bulk('Cu', a=a0, cubic=True)
|
copper = bulk('Cu', a=a0, cubic=True)
|
||||||
# Repeat the cell many times along x, y and z
|
cluster = hemispherical_cluster(copper, planes=3, emitter_plane=2)
|
||||||
cluster = cluster.repeat((4, 4, 4))
|
|
||||||
# Put the center of the structure at the origin
|
|
||||||
center_cluster(cluster)
|
|
||||||
# Keep atoms inside a given radius
|
|
||||||
cluster = cut_sphere(cluster, radius=a0 + .01)
|
|
||||||
# Keep only atoms below the plane z <= 0
|
|
||||||
cluster = cut_plane(cluster, z=0.1)
|
|
||||||
|
|
||||||
# Set the absorber (the deepest atom centered in the xy-plane)
|
# Set the absorber (the deepest atom centered in the xy-plane)
|
||||||
cluster.absorber = get_atom_index(cluster, 0, 0, -a0)
|
cluster.absorber = get_atom_index(cluster, 0, 0, 0)
|
||||||
|
|
||||||
# Create a calculator for the PhotoElectron Diffration
|
# Create a calculator for the PhotoElectron Diffration
|
||||||
calc = MSSPEC(spectroscopy='PED')
|
calc = MSSPEC(spectroscopy='PED')
|
||||||
|
|
||||||
# Set the cluster to use for the calculation
|
# Set the cluster to use for the calculation
|
||||||
calc.set_atoms(cluster)
|
calc.set_atoms(cluster)
|
||||||
|
|
||||||
|
@ -31,4 +26,6 @@ data = calc.get_theta_scan(level='2p3/2')
|
||||||
|
|
||||||
# Show the results
|
# Show the results
|
||||||
data.view()
|
data.view()
|
||||||
#calc.shutdown()
|
|
||||||
|
# Clean temporary files
|
||||||
|
calc.shutdown()
|
|
@ -16,7 +16,7 @@ Begin by typing:
|
||||||
:linenos:
|
:linenos:
|
||||||
:lineno-start: 1
|
:lineno-start: 1
|
||||||
|
|
||||||
# coding: utf-8
|
# coding: utf8
|
||||||
|
|
||||||
from msspec.calculator import MSSPEC
|
from msspec.calculator import MSSPEC
|
||||||
from msspec.utils import *
|
from msspec.utils import *
|
||||||
|
@ -45,27 +45,37 @@ This is the job of the *ase* module, so load the module
|
||||||
from ase.build import bulk
|
from ase.build import bulk
|
||||||
from ase.visualize import view
|
from ase.visualize import view
|
||||||
|
|
||||||
a0 = 3.6
|
a0 = 3.6 # The lattice parameter in angstroms
|
||||||
cluster = bulk('Cu', a = a0, cubic = True)
|
|
||||||
|
# Create the copper cubic cell
|
||||||
|
copper = bulk('Cu', a=a0, cubic=True)
|
||||||
view(cluster)
|
view(cluster)
|
||||||
|
|
||||||
In line 6 we load the :py:func:`bulk` function to create our atomic object and,
|
In line 6 we load the :py:func:`bulk` function to create our atomic object and,
|
||||||
in line 7, we load the :py:func:`view` function to actually view our cluster.
|
in line 7, we load the :py:func:`view` function to actually view our cluster.
|
||||||
|
|
||||||
The creation of the cluster is done line 10. The :py:func:`bulk` needs one
|
The creation of the cluster starts on line 12. We create first the copper cubic
|
||||||
argument which are the chemical species ('Cu' in our example). We also pass 2
|
cell with the The :py:func:`bulk` function. It needs one argument which are the
|
||||||
keyword (optional) arguments here:
|
chemical species ('Cu' in our example). We also pass 2 keyword (optional) arguments
|
||||||
|
here:
|
||||||
|
|
||||||
* The lattice parameter *a* in units of angströms.
|
* The lattice parameter *a* in units of angströms.
|
||||||
* The *cubic* keyword, to obtain a cubic cell rather than the fully
|
* The *cubic* keyword, to obtain a cubic cell rather than the fully
|
||||||
reduced one which is not cubic
|
reduced one which is not cubic
|
||||||
|
|
||||||
From now on, you can save your script as 'Cu.py' and open a terminal window in
|
From now on, you can save your script as 'Cu.py' and open a terminal window in
|
||||||
the same directory as this file. Launch your script using python:
|
the same directory as this file. Launch your script using 'python' or 'msspec -p'
|
||||||
|
(depending on your installation):
|
||||||
|
|
||||||
.. code-block:: bash
|
.. code-block:: bash
|
||||||
|
|
||||||
python2 Cu.py
|
python Cu.py
|
||||||
|
|
||||||
|
or
|
||||||
|
|
||||||
|
.. code-block:: bash
|
||||||
|
|
||||||
|
msspec -p Cu.py
|
||||||
|
|
||||||
and a graphical window (the ase-gui) should open with a cubic cell of copper
|
and a graphical window (the ase-gui) should open with a cubic cell of copper
|
||||||
like this one:
|
like this one:
|
||||||
|
@ -80,34 +90,38 @@ like this one:
|
||||||
Obviously, multiple scattering calculations need more atoms to be accurate. Due
|
Obviously, multiple scattering calculations need more atoms to be accurate. Due
|
||||||
to the forward focusing effect in photo-electron diffraction, the best suited
|
to the forward focusing effect in photo-electron diffraction, the best suited
|
||||||
geometry for the cluster is hemispherical. Obtaining such a cluster is a
|
geometry for the cluster is hemispherical. Obtaining such a cluster is a
|
||||||
straightforward process:
|
straightforward process thanks to the :py:func:`utils.hemispherical_cluster` function.
|
||||||
|
This function will basically create a cluster based on a pattern (the cubic copper
|
||||||
1. Repeat the previous cell in all 3 directions
|
cell here).
|
||||||
2. center the structure
|
|
||||||
3. Keep only atoms within a given radius from center
|
|
||||||
4. Keep only atoms within one halh of the sphere.
|
|
||||||
|
|
||||||
Modify your script like this and run it again.
|
Modify your script like this and run it again.
|
||||||
|
|
||||||
.. literalinclude:: Cu_simple.py
|
.. literalinclude:: Cu.py
|
||||||
:linenos:
|
:linenos:
|
||||||
:lineno-start: 1
|
:lineno-start: 1
|
||||||
:lines: 1-21
|
:lines: 1-13
|
||||||
|
|
||||||
|
|
||||||
Don't forget to add the line to view the cluster at the end of the script and run
|
Don't forget to add the line to view the cluster at the end of the script and run
|
||||||
the script again.
|
the script again. The :py:func:`hemispherical_cluster` works in 3 simple steps:
|
||||||
|
|
||||||
|
#. Repeat the given *pattern* in all 3 directions
|
||||||
|
#. Center this new set of atoms and cut a sphere from the center
|
||||||
|
#. Remove the upper half of the created 'sphere'.
|
||||||
|
|
||||||
|
To get more information about how to use this function, have a look at the :ref:`hemispherical_cluster_faq` section in the :ref:`faq`.
|
||||||
|
|
||||||
.. figure:: Cu_fig2.png
|
.. figure:: Cu_fig2.png
|
||||||
:align: center
|
:align: center
|
||||||
:width: 60%
|
:width: 60%
|
||||||
|
|
||||||
Figure 2. The different steps to output a cluster.
|
Figure 2. The different steps to output a cluster.
|
||||||
a) After repeat, b) after cut_sphere, c) after cut_plane
|
a) After repeat, b) after cutting a sphere, c) final cluster
|
||||||
|
|
||||||
|
|
||||||
Once you a cluster is built the next step is to define which atom in the cluster
|
Once your cluster is built the next step is to define which atom in the cluster
|
||||||
will absorbe the light. This atom is called the *absorber*.
|
will absorb the light. This atom is called the *absorber* (or the *emitter* since
|
||||||
|
it emits the photoelectron).
|
||||||
|
|
||||||
To specify which atom is the absorber, you need to understand that the cluster
|
To specify which atom is the absorber, you need to understand that the cluster
|
||||||
object is like a list of atoms. Each member of this list is an atom with its
|
object is like a list of atoms. Each member of this list is an atom with its
|
||||||
|
@ -115,7 +129,7 @@ own position. You need to locate the index of the atom in the list that you want
|
||||||
it to be the absorber. Then, put that number in the *cluster.absorber* attribute
|
it to be the absorber. Then, put that number in the *cluster.absorber* attribute
|
||||||
|
|
||||||
For example, suppose that you want the first atom of the list to be the
|
For example, suppose that you want the first atom of the list to be the
|
||||||
absorber. You should write:
|
absorber. You would write:
|
||||||
|
|
||||||
.. code-block:: python
|
.. code-block:: python
|
||||||
|
|
||||||
|
@ -123,24 +137,27 @@ absorber. You should write:
|
||||||
|
|
||||||
To find what is the index of the atom you'd like to be the absorber, you can
|
To find what is the index of the atom you'd like to be the absorber, you can
|
||||||
either get it while you are visualizing the structure within the ase-gui
|
either get it while you are visualizing the structure within the ase-gui
|
||||||
program. Or, you can use :py:func:`get_atom_index` function. This function takes
|
program (select an atom with the left mouse button and look at its index in the
|
||||||
4 arguments: the cluster to look the index for, and the x, y and z coordinates.
|
status line). Or, you can use :py:func:`utils.get_atom_index` function. This function
|
||||||
|
takes 4 arguments: the cluster to look the index for, and the x, y and z coordinates.
|
||||||
It will return the index of the closest atom to these coordinates. In our
|
It will return the index of the closest atom to these coordinates. In our
|
||||||
example, to get the deepest atom centered in the xy-plane, we write:
|
example, as we used the :py:func:`utils.hemispherical_cluster` function to create our
|
||||||
|
cluster, the *emitter* (*absorber*) is always located at the origin, so defining it
|
||||||
|
is straightforward:
|
||||||
|
|
||||||
.. literalinclude:: Cu_simple.py
|
.. literalinclude:: Cu.py
|
||||||
:linenos:
|
:linenos:
|
||||||
:lineno-start: 22
|
:lineno-start: 15
|
||||||
:lines: 22-23
|
:lines: 15-16
|
||||||
|
|
||||||
|
|
||||||
That's all for the cluster part. We now need to create a calculator for that
|
That's all for the cluster part. We now need to create a calculator for that
|
||||||
object. This is a 2 lines procedure:
|
object. This is a 2 lines procedure:
|
||||||
|
|
||||||
.. literalinclude:: Cu_simple.py
|
.. literalinclude:: Cu.py
|
||||||
:linenos:
|
:linenos:
|
||||||
:lineno-start: 24
|
:lineno-start: 18
|
||||||
:lines: 24-28
|
:lines: 18-22
|
||||||
|
|
||||||
When creating a new calculator, you must choose the kind of spectroscopy you
|
When creating a new calculator, you must choose the kind of spectroscopy you
|
||||||
will work with. In this example we choose 'PED' for *PhotoElectron Diffraction*.
|
will work with. In this example we choose 'PED' for *PhotoElectron Diffraction*.
|
||||||
|
@ -153,14 +170,14 @@ Other types of spectroscopies are:
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Now that everything is ready you can actually perform a calculation. The 2 lines
|
Now that everything is ready you can actually perform a calculation. The lines
|
||||||
below will produce a polar scan of the Cu(2p3/2) level with default parameters,
|
below will produce a polar scan of the Cu(2p3/2) level with default parameters,
|
||||||
store the results in the data object and display it in a graphical window.
|
store the results in the data object and display it in a graphical window.
|
||||||
|
|
||||||
.. literalinclude:: Cu_simple.py
|
.. literalinclude:: Cu.py
|
||||||
:linenos:
|
:linenos:
|
||||||
:lineno-start: 29
|
:lineno-start: 24
|
||||||
:lines: 29-33
|
:lines: 24-28
|
||||||
|
|
||||||
running this script will produce the following output
|
running this script will produce the following output
|
||||||
|
|
||||||
|
@ -177,7 +194,6 @@ By default, the program computes for :math:`\theta` angles in the -70°..+70°
|
||||||
range. This can be changed by using the *angles* keyword.
|
range. This can be changed by using the *angles* keyword.
|
||||||
|
|
||||||
.. code-block:: python
|
.. code-block:: python
|
||||||
:linenos:
|
|
||||||
|
|
||||||
#For a polar scan between 0° and 60° with 100 points
|
#For a polar scan between 0° and 60° with 100 points
|
||||||
import numpy as np
|
import numpy as np
|
||||||
|
@ -201,7 +217,6 @@ work function of the sample, arbitrary set to 4.5 eV.
|
||||||
Of course, you can choose any kinetic energy you'd like:
|
Of course, you can choose any kinetic energy you'd like:
|
||||||
|
|
||||||
.. code-block:: python
|
.. code-block:: python
|
||||||
:linenos:
|
|
||||||
|
|
||||||
# To set the kinetic energy...
|
# To set the kinetic energy...
|
||||||
data = calc.get_theta_scan(level = '2p3/2', kinetic_energy = 300)
|
data = calc.get_theta_scan(level = '2p3/2', kinetic_energy = 300)
|
||||||
|
@ -209,9 +224,9 @@ Of course, you can choose any kinetic energy you'd like:
|
||||||
|
|
||||||
|
|
||||||
Below is the full code of this example. You can download it :download:`here
|
Below is the full code of this example. You can download it :download:`here
|
||||||
<Cu_simple.py>`
|
<Cu.py>`
|
||||||
|
|
||||||
.. literalinclude:: Cu_simple.py
|
.. literalinclude:: Cu.py
|
||||||
:linenos:
|
:linenos:
|
||||||
|
|
||||||
.. seealso::
|
.. seealso::
|
||||||
|
|
|
@ -10,12 +10,12 @@ from ase import Atom, Atoms
|
||||||
import numpy as np
|
import numpy as np
|
||||||
|
|
||||||
|
|
||||||
symbol = 'Ni' # The kind of atom for the chain
|
symbol = 'Ni' # The kind of atom for the chain
|
||||||
orders = (1, 5) # We will run the calculation for single scattering
|
orders = (1, 5) # We will run the calculation for single scattering
|
||||||
# and multiple scattering (5th diffusion order)
|
# and multiple scattering (5th diffusion order)
|
||||||
chain_lengths = (2,3,5) # We will run the calculation for differnt lengths
|
chain_lengths = (2,3,5) # We will run the calculation for differnt lengths
|
||||||
# of the atomic chain
|
# of the atomic chain
|
||||||
a = 3.5 # The distance bewteen 2 atoms
|
a = 3.499 * np.sqrt(2)/2 # The distance bewteen 2 atoms
|
||||||
|
|
||||||
# Define an empty variable to store all the results
|
# Define an empty variable to store all the results
|
||||||
all_data = None
|
all_data = None
|
||||||
|
@ -28,11 +28,12 @@ for chain_length in chain_lengths:
|
||||||
chain = Atoms([Atom(symbol, position = (0., 0., i*a)) for i in
|
chain = Atoms([Atom(symbol, position = (0., 0., i*a)) for i in
|
||||||
range(chain_length)])
|
range(chain_length)])
|
||||||
# 2- rotating the chain by 45 degrees with respect to the y axis
|
# 2- rotating the chain by 45 degrees with respect to the y axis
|
||||||
chain.rotate('y', np.radians(45.))
|
#chain.rotate('y', np.radians(45.))
|
||||||
|
chain.rotate(45., 'y')
|
||||||
# 3- setting a custom Muffin-tin radius of 1.5 angstroms for all
|
# 3- setting a custom Muffin-tin radius of 1.5 angstroms for all
|
||||||
# atoms (needed if you want to enlarge the distance between
|
# atoms (needed if you want to enlarge the distance between
|
||||||
# the atoms while keeping the radius constant)
|
# the atoms while keeping the radius constant)
|
||||||
[atom.set('mt_radius', 1.5) for atom in chain]
|
#[atom.set('mt_radius', 1.5) for atom in chain]
|
||||||
# 4- defining the absorber to be the first atom in the chain at
|
# 4- defining the absorber to be the first atom in the chain at
|
||||||
# x = y = z = 0
|
# x = y = z = 0
|
||||||
chain.absorber = 0
|
chain.absorber = 0
|
||||||
|
@ -43,7 +44,7 @@ for chain_length in chain_lengths:
|
||||||
# Here is how to tweak the scattering order
|
# Here is how to tweak the scattering order
|
||||||
calc.calculation_parameters.scattering_order = order
|
calc.calculation_parameters.scattering_order = order
|
||||||
# This line below is where we actually run the calculation
|
# This line below is where we actually run the calculation
|
||||||
all_data = calc.get_theta_scan(level='3s', kinetic_energy=1000.,
|
all_data = calc.get_theta_scan(level='3s', #kinetic_energy=1000.,
|
||||||
theta=np.arange(0., 80.), data=all_data)
|
theta=np.arange(0., 80.), data=all_data)
|
||||||
|
|
||||||
# OPTIONAL, to improve the display of the data we will change the dataset
|
# OPTIONAL, to improve the display of the data we will change the dataset
|
||||||
|
|
|
@ -30,7 +30,7 @@ trajectory for this electron which in turn lowers the signal.
|
||||||
:align: center
|
:align: center
|
||||||
:width: 80%
|
:width: 80%
|
||||||
|
|
||||||
Figure 4. Polar scan of a Ni chain of 2-5 atoms for single and mutliple (5th order)
|
Figure 1. Polar scan of a Ni chain of 2-5 atoms for single and mutliple (5th order)
|
||||||
scattering.
|
scattering.
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,153 +1,129 @@
|
||||||
# coding: utf-8
|
# coding: utf8
|
||||||
|
|
||||||
from msspec.calculator import MSSPEC, XRaySource
|
|
||||||
from msspec.utils import *
|
|
||||||
from msspec.iodata import Data
|
|
||||||
from ase.build import bulk
|
|
||||||
|
|
||||||
|
from ase.build import bulk
|
||||||
import numpy as np
|
import numpy as np
|
||||||
import sys
|
from msspec.calculator import MSSPEC, XRaySource
|
||||||
|
from msspec.utils import hemispherical_cluster, get_atom_index
|
||||||
a0 = 3.6 # The lattice parameter in angstroms
|
|
||||||
phi = np.arange(0, 100) # An array of phi angles
|
|
||||||
all_T = np.arange(300, 1000, 100) # All temperatures used for the calculation
|
|
||||||
all_theta = np.array([45, 83]) # 2 polar angles, 83° is grazing detection
|
|
||||||
eps = 0.01 # a useful small value
|
|
||||||
|
|
||||||
DATA_FNAME = 'all_data.hdf5' # Where to store all the data
|
|
||||||
ANALYSIS_FNAME = 'analysis.hdf5'
|
|
||||||
|
|
||||||
|
|
||||||
def compute(filename):
|
def create_clusters(nplanes=3):
|
||||||
"""Will compute a phi scan for an emitter in the first, second and third plane
|
copper = bulk('Cu', a=3.6, cubic=True)
|
||||||
of a copper substrate for various polar angles and temperatures.
|
clusters = []
|
||||||
In a second step (outside this function), intensities from all these emitters
|
for emitter_plane in range(nplanes):
|
||||||
are added to get the signal of a substrate."""
|
cluster = hemispherical_cluster(copper,
|
||||||
calc = MSSPEC(spectroscopy='PED')
|
emitter_plane=emitter_plane,
|
||||||
calc.source_parameters.energy = XRaySource.AL_KALPHA
|
planes=emitter_plane+2,
|
||||||
calc.muffintin_parameters.interstitial_potential = 14.1
|
shape='cylindrical')
|
||||||
|
cluster.absorber = get_atom_index(cluster, 0, 0, 0)
|
||||||
|
cluster.info.update({
|
||||||
|
'emitter_plane': emitter_plane,
|
||||||
|
})
|
||||||
|
clusters.append(cluster)
|
||||||
|
return clusters
|
||||||
|
|
||||||
calc.calculation_parameters.vibrational_damping = 'averaged_tl'
|
def compute(clusters, all_theta=[45., 83.],
|
||||||
calc.calculation_parameters.use_debye_model = True
|
all_T=np.arange(300., 1000., 400.)):
|
||||||
calc.calculation_parameters.debye_temperature = 343
|
data = None
|
||||||
calc.calculation_parameters.vibration_scaling = 1.2
|
for ic, cluster in enumerate(clusters):
|
||||||
|
# Retrieve info from cluster object
|
||||||
|
plane = cluster.info['emitter_plane']
|
||||||
|
|
||||||
calc.detector_parameters.average_sampling = 'high'
|
calc = MSSPEC(spectroscopy='PED', algorithm='expansion')
|
||||||
calc.detector_parameters.angular_acceptance = 5.7
|
calc.source_parameters.energy = XRaySource.AL_KALPHA
|
||||||
|
calc.muffintin_parameters.interstitial_potential = 14.1
|
||||||
|
|
||||||
filters = ['forward_scattering', 'backward_scattering']
|
calc.calculation_parameters.vibrational_damping = 'averaged_tl'
|
||||||
calc.calculation_parameters.path_filtering = filters
|
calc.calculation_parameters.use_debye_model = True
|
||||||
|
calc.calculation_parameters.debye_temperature = 343
|
||||||
|
calc.calculation_parameters.vibration_scaling = 1.2
|
||||||
|
|
||||||
calc.calculation_parameters.RA_cutoff = 3
|
calc.detector_parameters.average_sampling = 'high'
|
||||||
|
calc.detector_parameters.angular_acceptance = 5.7
|
||||||
|
|
||||||
# You can also choose a real potential and manually define the
|
for atom in cluster:
|
||||||
# electron mean free path
|
atom.set('forward_angle', 30)
|
||||||
#
|
atom.set('backward_angle', 30)
|
||||||
# calc.tmatrix_parameters.exchange_correlation = 'hedin_lundqvist_real'
|
filters = ['forward_scattering', 'backward_scattering']
|
||||||
# calc.calculation_parameters.mean_free_path = 10.
|
calc.calculation_parameters.path_filtering = filters
|
||||||
|
|
||||||
data = None # init an empty data object
|
calc.calculation_parameters.RA_cutoff = 2
|
||||||
for temperature in all_T:
|
|
||||||
for plane in range(3):
|
|
||||||
# We create a cylindrical cluster here with one plane below the emitter
|
|
||||||
# and 0, 1 or to planes above the emitter
|
|
||||||
cluster = bulk('Cu', a=a0, cubic=True)
|
|
||||||
cluster = cluster.repeat((20, 20, 8))
|
|
||||||
center_cluster(cluster)
|
|
||||||
cluster = cut_cylinder(cluster, radius=1.5 * a0 + eps)
|
|
||||||
cluster = cut_plane(cluster, z=-( a0/2 + eps))
|
|
||||||
cluster = cut_plane(cluster, z=(plane) * a0 / 2 + eps)
|
|
||||||
cluster.absorber = get_atom_index(cluster, 0, 0, 0)
|
|
||||||
|
|
||||||
calc.calculation_parameters.temperature = temperature
|
for T in all_T:
|
||||||
# the scattering order depends on the number of planes above
|
for theta in all_theta:
|
||||||
# the emitter to speed up calculations
|
calc.calculation_parameters.temperature = T
|
||||||
calc.calculation_parameters.scattering_order = 1 + plane
|
calc.calculation_parameters.scattering_order = min(1 + plane, 3)
|
||||||
|
calc.set_atoms(cluster)
|
||||||
|
data = calc.get_phi_scan(level='2p3/2', theta=theta,
|
||||||
|
phi=np.linspace(0, 100),
|
||||||
|
kinetic_energy=560, data=data)
|
||||||
|
dset = data[-1]
|
||||||
|
dset.title = "plane #{:d}, T={:f}K, theta={:f}°".format(plane,
|
||||||
|
T,
|
||||||
|
theta)
|
||||||
|
|
||||||
calc.set_atoms(cluster)
|
dset.add_parameter(group='misc', name='plane', value=plane, unit='')
|
||||||
# Here starts the calculation
|
dset.add_parameter(group='misc', name='T', value=T, unit='')
|
||||||
data = calc.get_phi_scan(level='2p3/2', theta=all_theta, phi=phi,
|
dset.add_parameter(group='misc', name='theta', value=theta, unit='')
|
||||||
kinetic_energy=560, data=data)
|
return data
|
||||||
|
|
||||||
data.save(filename)
|
|
||||||
|
|
||||||
def process_data(datafile, outputfile):
|
def analysis(data):
|
||||||
"""Will create another Data file with some phi-scans corresponding to 3
|
all_plane = []
|
||||||
planes at different temperatures and the anisotropy curve for 45° and
|
all_T = []
|
||||||
grazing detection.
|
all_theta = []
|
||||||
"""
|
for dset in data:
|
||||||
def get_signal(datafile, T=300, theta=45):
|
plane = dset.get_parameter('misc', 'plane')['value']
|
||||||
data = Data.load(datafile)
|
T = dset.get_parameter('misc', 'T')['value']
|
||||||
total = None
|
theta = dset.get_parameter('misc', 'theta')['value']
|
||||||
|
cs = dset.cross_section.copy()
|
||||||
|
phi = dset.phi.copy()
|
||||||
|
|
||||||
|
if plane not in all_plane: all_plane.append(plane)
|
||||||
|
if T not in all_T: all_T.append(T)
|
||||||
|
if theta not in all_theta: all_theta.append(theta)
|
||||||
|
|
||||||
|
def get_anisotropy(theta, T):
|
||||||
|
cs = None
|
||||||
for dset in data:
|
for dset in data:
|
||||||
p = {_['group'] + '.' + _['name']: _['value'] for _ in dset.parameters()}
|
|
||||||
temperature = np.float(p['CalculationParameters.temperature'])
|
|
||||||
if temperature != T: continue
|
|
||||||
i = np.where(dset.plane == -1)
|
|
||||||
j = np.where(dset.theta[i] == theta)
|
|
||||||
signal = dset.cross_section[i][j]
|
|
||||||
try:
|
try:
|
||||||
total += signal
|
_T = dset.get_parameter('misc', 'T')['value']
|
||||||
|
_theta = dset.get_parameter('misc', 'theta')['value']
|
||||||
|
_cs = dset.cross_section.copy()
|
||||||
|
phi = dset.phi.copy()
|
||||||
except:
|
except:
|
||||||
total = signal
|
continue
|
||||||
phi = dset.phi[i][j]
|
if _theta == theta and _T == T:
|
||||||
return phi, total
|
try:
|
||||||
|
cs += _cs
|
||||||
|
except:
|
||||||
|
cs = _cs
|
||||||
|
Imax = np.max(cs)
|
||||||
|
Imin = np.min(cs)
|
||||||
|
return (Imax - Imin)/Imax
|
||||||
|
|
||||||
|
# create a substrate dataset for each T and theta
|
||||||
|
anisotropy_dset = data.add_dset("all")
|
||||||
|
anisotropy_view = anisotropy_dset.add_view('Anisotropies',
|
||||||
|
title='Relative anisotropies for Cu(2p)',
|
||||||
|
marker='o',
|
||||||
|
xlabel='T (K)',
|
||||||
|
ylabel=r'$\frac{\Delta I / I_{max}(T)}{\Delta I_{300}'
|
||||||
|
r'/ I_{max}(300)} (\%)$')
|
||||||
|
|
||||||
analysis = Data('Temperature tutorial')
|
|
||||||
scans_dset = analysis.add_dset('Phi scans')
|
|
||||||
scans_view = scans_dset.add_view('Figure 1',
|
|
||||||
title=r'Cu(2p) Azimuthal scan for $\theta = 83\degree$',
|
|
||||||
xlabel=r'$\Phi (\degree$)',
|
|
||||||
ylabel='Signal (a.u.)')
|
|
||||||
anisotropy_dset = analysis.add_dset('Anisotropies')
|
|
||||||
anisotropy_view = anisotropy_dset.add_view('Figure 2',
|
|
||||||
title='Relative anisotropies for Cu(2p)',
|
|
||||||
marker='o',
|
|
||||||
xlabel='T (K)',
|
|
||||||
ylabel=r'$\frac{\Delta I / I_{max}(T)}{\Delta I_{300} / I_{max}(300)} (\%)$')
|
|
||||||
for theta in all_theta:
|
for theta in all_theta:
|
||||||
for T in all_T:
|
for T in all_T:
|
||||||
PHI, SIGNAL = get_signal(datafile, T=T, theta=theta)
|
A = get_anisotropy(theta, T)
|
||||||
for phi, signal in zip(PHI, SIGNAL):
|
A0 = get_anisotropy(theta, np.min(all_T))
|
||||||
scans_dset.add_row(phi=phi, signal=signal, theta=theta, temperature=T)
|
|
||||||
|
|
||||||
middleT = all_T[np.abs(all_T - np.mean(all_T)).argmin()]
|
anisotropy_dset.add_row(temperature=T, theta=theta, anisotropy=A/A0)
|
||||||
if theta == 83 and T in [np.min(all_T), middleT, np.max(all_T)]:
|
|
||||||
scans_view.select('phi', 'signal',
|
|
||||||
where='temperature == {:f} and theta == {:f}'.format(T, theta),
|
|
||||||
legend='{:.0f} K'.format(T))
|
|
||||||
|
|
||||||
PHI, SIGNAL0 = get_signal(datafile, T=np.min(all_T), theta=theta)
|
|
||||||
Imax = np.max(SIGNAL)
|
|
||||||
Imax0 = np.max(SIGNAL0)
|
|
||||||
dI = Imax - np.min(SIGNAL)
|
|
||||||
dI0 = Imax0 - np.min(SIGNAL0)
|
|
||||||
ani = (dI / Imax) / (dI0 / Imax0)
|
|
||||||
anisotropy_dset.add_row(temperature=T, anisotropy=ani, theta=theta)
|
|
||||||
|
|
||||||
anisotropy_view.select('temperature', 'anisotropy',
|
anisotropy_view.select('temperature', 'anisotropy',
|
||||||
where='theta == {:f}'.format(theta),
|
where='theta == {:f}'.format(theta),
|
||||||
legend=r'$\theta = {:.0f} \degree$'.format(theta))
|
legend=r'$\theta = {:.0f} \degree$'.format(theta))
|
||||||
|
return data
|
||||||
analysis.save(outputfile)
|
|
||||||
|
|
||||||
|
|
||||||
# A convenient way to run the script, just specify one or more of these calc, analyse or
|
|
||||||
# view keywords as arguments
|
|
||||||
# ... to calculate all the data, analyse the data and view the results, run
|
|
||||||
# python Cu_temperature.py calc analyse view
|
|
||||||
# ... to just view the results, simply run
|
|
||||||
# python Cu_temperature.py view
|
|
||||||
|
|
||||||
if 'calc' in sys.argv:
|
|
||||||
compute(DATA_FNAME)
|
|
||||||
if 'analyse' in sys.argv:
|
|
||||||
process_data(DATA_FNAME, ANALYSIS_FNAME)
|
|
||||||
if 'view' in sys.argv:
|
|
||||||
data = Data.load(ANALYSIS_FNAME)
|
|
||||||
data.view()
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
clusters = create_clusters()
|
||||||
|
data = compute(clusters)
|
||||||
|
data = analysis(data)
|
||||||
|
data.view()
|
||||||
|
|
|
@ -12,7 +12,7 @@ if ! [ -d "$VENV_PATH" ]; then
|
||||||
fi
|
fi
|
||||||
|
|
||||||
launch_script() {
|
launch_script() {
|
||||||
. "$VENV_PATH/bin/activate" && python $@
|
. "$VENV_PATH/bin/activate" && python "$@"
|
||||||
}
|
}
|
||||||
|
|
||||||
show_help () {
|
show_help () {
|
||||||
|
|
|
@ -747,15 +747,30 @@ class _PED(_MSCALCULATOR):
|
||||||
proto_index = i+1
|
proto_index = i+1
|
||||||
title = 'Scattering factor at {:.3f} eV'.format(kinetic_energy)
|
title = 'Scattering factor at {:.3f} eV'.format(kinetic_energy)
|
||||||
|
|
||||||
|
mini = min(map(np.min, [dset.sf_real, dset.sf_imag, dset.sf_module]))
|
||||||
|
maxi = max(map(np.max, [dset.sf_real, dset.sf_imag, dset.sf_module]))
|
||||||
view = dset.add_view("Proto. atom #{:d}".format(proto_index),
|
view = dset.add_view("Proto. atom #{:d}".format(proto_index),
|
||||||
title=title, projection='polar')
|
title=title, projection='polar',
|
||||||
|
ylim=[mini, maxi])
|
||||||
where = "proto_index=={:d}".format(proto_index)
|
where = "proto_index=={:d}".format(proto_index)
|
||||||
view.select('theta', 'sf_module', where=where,
|
view.select('theta', 'sf_module', where=where,
|
||||||
legend=r'$|f(\theta)|$')
|
legend=r'$|f(\theta)|$')
|
||||||
view.select('theta', 'sf_real', where=where,
|
view.select('theta', 'sf_real', where=where,
|
||||||
legend=r'$\Im(f(\theta))$')
|
|
||||||
view.select('theta', 'sf_imag', where=where,
|
|
||||||
legend=r'$\Re(f(\theta))$')
|
legend=r'$\Re(f(\theta))$')
|
||||||
|
view.select('theta', 'sf_imag', where=where,
|
||||||
|
legend=r'$\Im(f(\theta))$')
|
||||||
|
|
||||||
|
if scan_type == 'energy':
|
||||||
|
absorber_symbol = self.atoms[self.atoms.absorber].symbol
|
||||||
|
title = (r'Energy scan of {}({}) at $\theta$={:.2f}$\degree$ and '
|
||||||
|
'$\phi$={:.2f}$\degree$').format(
|
||||||
|
absorber_symbol, level, theta, phi)
|
||||||
|
xlabel = r'Photoelectron kinetic energy (eV)'
|
||||||
|
ylabel = r'Signal (a. u.)'
|
||||||
|
|
||||||
|
view = dset.add_view("EnergyScan".format(ke), title=title,
|
||||||
|
xlabel=xlabel, ylabel=ylabel)
|
||||||
|
view.select('energy', 'cross_section')
|
||||||
|
|
||||||
# save the cluster
|
# save the cluster
|
||||||
#clusbuf = StringIO()
|
#clusbuf = StringIO()
|
||||||
|
@ -922,6 +937,27 @@ class _PED(_MSCALCULATOR):
|
||||||
malloc={'NPH_M': 8000})
|
malloc={'NPH_M': 8000})
|
||||||
return data
|
return data
|
||||||
|
|
||||||
|
def get_energy_scan(self, phi=0, theta=0,
|
||||||
|
level=None, kinetic_energy=None, data=None):
|
||||||
|
"""Computes an energy scan of the emitted photoelectrons.
|
||||||
|
|
||||||
|
:param phi: All the values of the azimuthal angle to be computed. See
|
||||||
|
:ref:`scanparameters-phi`.
|
||||||
|
:param theta: The polar angle in degrees. See
|
||||||
|
:ref:`scanparameters-theta`.
|
||||||
|
:param level: The electronic level. See :ref:`pedparameters-level`.
|
||||||
|
:param kinetic_energy: see :ref:`scanparameters-kinetic_energy`.
|
||||||
|
:param data: a :py:class:`iodata.Data` object to append the results to
|
||||||
|
or None.
|
||||||
|
|
||||||
|
:returns: The modified :py:class:`iodata.Data` object passed as an
|
||||||
|
argument or a new :py:class:`iodata.Data` object.
|
||||||
|
|
||||||
|
"""
|
||||||
|
data = self._get_scan(scan_type='energy', level=level, theta=theta,
|
||||||
|
phi=phi, kinetic_energy=kinetic_energy, data=data)
|
||||||
|
return data
|
||||||
|
|
||||||
|
|
||||||
class _EIG(_MSCALCULATOR):
|
class _EIG(_MSCALCULATOR):
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -12,7 +12,6 @@ import pandas as pd
|
||||||
import time
|
import time
|
||||||
|
|
||||||
|
|
||||||
logging.basicConfig(level=logging.DEBUG)
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
@ -236,7 +235,22 @@ class Looper:
|
||||||
df = pd.DataFrame(dfdata, columns=columns)
|
df = pd.DataFrame(dfdata, columns=columns)
|
||||||
|
|
||||||
self.data = df
|
self.data = df
|
||||||
return df
|
|
||||||
|
#return df
|
||||||
|
# return a list of [x0, y0, x1, y1,...xn, yn] and a list
|
||||||
|
# of corresponding dict of parameters {'keyA': [val0,...valn],
|
||||||
|
# 'keyB': [val0,...valn], ...}
|
||||||
|
|
||||||
|
all_xy = []
|
||||||
|
for irow, row in df.iterrows():
|
||||||
|
all_xy.append(row.output[0])
|
||||||
|
all_xy.append(row.output[1])
|
||||||
|
parameters = df.to_dict()
|
||||||
|
parameters.pop('output')
|
||||||
|
|
||||||
|
return all_xy, parameters
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -282,7 +296,7 @@ if __name__ == "__main__":
|
||||||
|
|
||||||
looper = Looper()
|
looper = Looper()
|
||||||
looper.pipeline = bar
|
looper.pipeline = bar
|
||||||
data = looper.run(emitter, emitter_plane, uij, theta, levels, ncpu=1,
|
data = looper.run(emitter, emitter_plane, uij, theta, levels, ncpu=4,
|
||||||
passindex=True)
|
passindex=True)
|
||||||
|
print(data)
|
||||||
print(data[data.emitter_plane.eq(0)].theta.unique())
|
#print(data[data.emitter_plane.eq(0)].theta.unique())
|
||||||
|
|
|
@ -853,8 +853,8 @@ class MuffintinParameters(BaseParameters):
|
||||||
def __init__(self, phagen_parameters, spec_parameters):
|
def __init__(self, phagen_parameters, spec_parameters):
|
||||||
parameters = (
|
parameters = (
|
||||||
Parameter('charge_relaxation', types=bool, default=True, doc="""
|
Parameter('charge_relaxation', types=bool, default=True, doc="""
|
||||||
Used to specify wether the charge density of the photoabsorbing atom, which is used
|
Used to specify whether the charge density of the photoabsorbing atom, which is used
|
||||||
to construct the potential, is allowaed to relax around the core hole or not.
|
to construct the potential, is allowed to relax around the core hole or not.
|
||||||
"""),
|
"""),
|
||||||
Parameter('ionicity', types=dict, default={}, doc="""
|
Parameter('ionicity', types=dict, default={}, doc="""
|
||||||
A dictionary to specify the ionicity of each kind of atoms. If empty, the atoms are considered to be
|
A dictionary to specify the ionicity of each kind of atoms. If empty, the atoms are considered to be
|
||||||
|
|
|
@ -17,7 +17,7 @@ c
|
||||||
c Local variables
|
c Local variables
|
||||||
c
|
c
|
||||||
integer :: lwork
|
integer :: lwork
|
||||||
complex*16 :: wquery
|
complex*16 :: wquery(1)
|
||||||
complex*16 :: vl(1,1), vr(1,1)
|
complex*16 :: vl(1,1), vr(1,1)
|
||||||
c
|
c
|
||||||
real*8, allocatable :: rwork(:)
|
real*8, allocatable :: rwork(:)
|
||||||
|
@ -39,7 +39,7 @@ c
|
||||||
write(iuo1,*) ' '
|
write(iuo1,*) ' '
|
||||||
end if
|
end if
|
||||||
c
|
c
|
||||||
lwork = int(wquery)
|
lwork = int(wquery(1))
|
||||||
allocate(work(lwork))
|
allocate(work(lwork))
|
||||||
c
|
c
|
||||||
call zgeev('n','n',n,a,lda,w,vl,1,vr,1,work,lwork,rwork,info)
|
call zgeev('n','n',n,a,lda,w,vl,1,vr,1,work,lwork,rwork,info)
|
||||||
|
|
|
@ -113,7 +113,7 @@ C
|
||||||
CST PROGRAM COMP_CURVE
|
CST PROGRAM COMP_CURVE
|
||||||
SUBROUTINE COMP_CURVES()
|
SUBROUTINE COMP_CURVES()
|
||||||
C
|
C
|
||||||
PARAMETER (N_SIZE=1000,N_FILES=100,NMAX=9999)
|
PARAMETER (N_SIZE=1000,N_FILES=1000,NMAX=9999)
|
||||||
C
|
C
|
||||||
INTEGER CC_EXP(N_SIZE),CC_CAL(N_SIZE),VALUE,NVALUE
|
INTEGER CC_EXP(N_SIZE),CC_CAL(N_SIZE),VALUE,NVALUE
|
||||||
C
|
C
|
||||||
|
@ -1634,7 +1634,7 @@ C Author : D. Sébilleau
|
||||||
C
|
C
|
||||||
C Last modified : 9 Sep 2014
|
C Last modified : 9 Sep 2014
|
||||||
C
|
C
|
||||||
PARAMETER (N_SIZE=1000,N_FILES=100)
|
PARAMETER (N_SIZE=1000,N_FILES=1000)
|
||||||
C
|
C
|
||||||
REAL*4 X_CAL(N_SIZE),I_CAL,X,Y
|
REAL*4 X_CAL(N_SIZE),I_CAL,X,Y
|
||||||
REAL*4 DIFF,STEP1,STEP2
|
REAL*4 DIFF,STEP1,STEP2
|
||||||
|
@ -2955,7 +2955,7 @@ C Author : D. Sébilleau
|
||||||
C
|
C
|
||||||
C Last modified : 5 Sep 2014
|
C Last modified : 5 Sep 2014
|
||||||
C
|
C
|
||||||
PARAMETER (N_SIZE=1000,N_FILES=100)
|
PARAMETER (N_SIZE=1000,N_FILES=1000)
|
||||||
C
|
C
|
||||||
REAL*4 EXPE(N_SIZE),CALCULATION(N_SIZE,N_FILES)
|
REAL*4 EXPE(N_SIZE),CALCULATION(N_SIZE,N_FILES)
|
||||||
REAL*4 MIN_EXP,MIN_CAL,MINIMUM,SHIFT
|
REAL*4 MIN_EXP,MIN_CAL,MINIMUM,SHIFT
|
||||||
|
@ -9748,7 +9748,7 @@ C Author : D. Sébilleau
|
||||||
C
|
C
|
||||||
C Last modified : 19 Aug 2014
|
C Last modified : 19 Aug 2014
|
||||||
C
|
C
|
||||||
PARAMETER (N_SIZE=1000,N_FILES=100)
|
PARAMETER (N_SIZE=1000,N_FILES=1000)
|
||||||
C
|
C
|
||||||
REAL*4 EXPE(N_SIZE),CALC(N_SIZE),Y_MEAN(N_SIZE)
|
REAL*4 EXPE(N_SIZE),CALC(N_SIZE),Y_MEAN(N_SIZE)
|
||||||
real*4 x(N_SIZE)
|
real*4 x(N_SIZE)
|
||||||
|
|
|
@ -3,7 +3,7 @@ PYMAJ = 3
|
||||||
PYMIN = 6
|
PYMIN = 6
|
||||||
|
|
||||||
FC = gfortran
|
FC = gfortran
|
||||||
F2PY = f2py3
|
F2PY = f2py3 --f77exec=$(FC) --f90exec=$(FC)
|
||||||
|
|
||||||
NO_VENV = 0
|
NO_VENV = 0
|
||||||
DEBUG = 0
|
DEBUG = 0
|
||||||
|
|
|
@ -5,6 +5,7 @@ lxml
|
||||||
matplotlib
|
matplotlib
|
||||||
numpy
|
numpy
|
||||||
Pint
|
Pint
|
||||||
|
pandas
|
||||||
pycairo
|
pycairo
|
||||||
scipy
|
scipy
|
||||||
setuptools-scm
|
setuptools-scm
|
||||||
|
|
|
@ -0,0 +1,163 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
#
|
||||||
|
# Copyright © 2016-2021 - Rennes Physics Institute
|
||||||
|
#
|
||||||
|
# This file is part of msspec.
|
||||||
|
#
|
||||||
|
# msspec is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
# msspec is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this msspec. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
#
|
||||||
|
# Source file : utils/dockerized/linux/msspec
|
||||||
|
# Last modified: Thu, 23 Sep 2021 16:55:16 +0200
|
||||||
|
# Committed by : sylvain tricot <sylvain.tricot@univ-rennes1.fr>
|
||||||
|
|
||||||
|
THIS_SCRIPT="$0"
|
||||||
|
IMAGE_NAME="iprcnrs/msspec:latest"
|
||||||
|
|
||||||
|
Logln () {
|
||||||
|
echo "$1" >&2
|
||||||
|
}
|
||||||
|
|
||||||
|
Log () {
|
||||||
|
echo -n "$1" >&2
|
||||||
|
}
|
||||||
|
|
||||||
|
Read_YesNo () {
|
||||||
|
PROMPT="$1"
|
||||||
|
DEFAULT="$2"
|
||||||
|
|
||||||
|
ANSWER=""
|
||||||
|
RESPONSE=""
|
||||||
|
|
||||||
|
VALID=1
|
||||||
|
while test $VALID -ne 0; do
|
||||||
|
read -p "${PROMPT} (y/n) [${DEFAULT}]? " "RESPONSE"
|
||||||
|
ANSWER="${RESPONSE:-${DEFAULT}}"
|
||||||
|
case "${ANSWER}" in
|
||||||
|
y|n) VALID=0 ;;
|
||||||
|
*) echo "Invalid choice, please answer \"y\" or \"n\"."; VALID=1 ;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
Get_MsSpecContainerID () {
|
||||||
|
CID=$(docker ps -a -q --filter ancestor=$IMAGE_NAME)
|
||||||
|
echo $CID
|
||||||
|
}
|
||||||
|
|
||||||
|
Get_MsSpecImageID () {
|
||||||
|
IID=$(docker images -q $IMAGE_NAME)
|
||||||
|
echo $IID
|
||||||
|
}
|
||||||
|
|
||||||
|
Add_MsSpecImage () {
|
||||||
|
docker pull $IMAGE_NAME 1>&2
|
||||||
|
}
|
||||||
|
|
||||||
|
Add_MsSpecContainer () {
|
||||||
|
CID=$(Get_MsSpecContainerID)
|
||||||
|
if [ -z "$CID" ]; then
|
||||||
|
IID=$(Get_MsSpecImageID)
|
||||||
|
if [ -z "$IID" ]; then
|
||||||
|
Logln "Pulling MsSpec image..."
|
||||||
|
Add_MsSpecImage
|
||||||
|
fi
|
||||||
|
Log "Creating the MsSpec container... "
|
||||||
|
USERNAME=$(whoami)
|
||||||
|
USERID=$(id -u $USERNAME)
|
||||||
|
GROUPID=$(id -g $USERNAME)
|
||||||
|
CID=$(docker create -i --net=host -e DISPLAY=$DISPLAY -v $HOME:$HOME -u ${USERID}:${GROUPID} --entrypoint /bin/bash $IMAGE_NAME)
|
||||||
|
Logln "done."
|
||||||
|
fi
|
||||||
|
echo $CID
|
||||||
|
}
|
||||||
|
|
||||||
|
Start_MsSpecContainer () {
|
||||||
|
CID=$(Add_MsSpecContainer)
|
||||||
|
status=$(docker container inspect -f '{{.State.Status}}' $CID)
|
||||||
|
if [ $status != "running" ]; then
|
||||||
|
Log "Starting MsSpec container... "
|
||||||
|
# Start the container
|
||||||
|
CID=$(docker start $CID)
|
||||||
|
Logln "done."
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
Remove_MsSpecContainer () {
|
||||||
|
Log "Removing MsSpec container... "
|
||||||
|
CID=$(Get_MsSpecContainerID)
|
||||||
|
docker stop -t 1 $CID >/dev/null 2>&1
|
||||||
|
docker rm $CID >/dev/null 2>&1
|
||||||
|
Logln "done."
|
||||||
|
}
|
||||||
|
|
||||||
|
Run_MsSpec () {
|
||||||
|
# Run msspec command
|
||||||
|
CID=$(Get_MsSpecContainerID)
|
||||||
|
xhost +localhost >/dev/null 2>&1
|
||||||
|
docker exec -i -t -w "$PWD" $CID msspec "$@"
|
||||||
|
}
|
||||||
|
|
||||||
|
Run_Bash () {
|
||||||
|
# Run msspec command
|
||||||
|
CID=$(Get_MsSpecContainerID)
|
||||||
|
xhost +localhost >/dev/null 2>&1
|
||||||
|
docker exec -i -t -w "$PWD" -e HOME=$HOME -e PS1="MsSpec:\w> " $CID /bin/bash --norc --noprofile
|
||||||
|
}
|
||||||
|
|
||||||
|
Uninstall_MsSpecImage () {
|
||||||
|
Read_YesNo "You are about to remove the MsSpec Docker image, its container and this script. Are you sure" "n"
|
||||||
|
case $ANSWER in
|
||||||
|
y) Remove_MsSpecContainer;
|
||||||
|
Log "Removing ${IMAGE_NAME}...";
|
||||||
|
docker rmi $IMAGE_NAME >/dev/null 2>&1;
|
||||||
|
Logln "done.";
|
||||||
|
Log "Removing ${THIS_SCRIPT}...";
|
||||||
|
rm -f $THIS_SCRIPT;
|
||||||
|
Logln "done.";
|
||||||
|
;;
|
||||||
|
n) echo "Uninstallation aborted."
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
|
Show_Help () {
|
||||||
|
echo "Usage: 1) msspec -p [PYTHON OPTIONS] SCRIPT [ARGUMENTS...]"
|
||||||
|
echo " 2) msspec [-l FILE | -i | -h]"
|
||||||
|
echo " 3) msspec [bash | reset]"
|
||||||
|
echo ""
|
||||||
|
echo "Form (1) is used to launch a script"
|
||||||
|
echo "Form (2) is used to load a hdf5 data file"
|
||||||
|
echo "Form (3) is used to control the Docker container/image."
|
||||||
|
echo ""
|
||||||
|
echo "List of possible options:"
|
||||||
|
echo " -p Pass every arguments after this option to the msspec"
|
||||||
|
echo " virtual environment Python interpreter."
|
||||||
|
echo " -i Run the interactive Python interpreter within msspec"
|
||||||
|
echo " virtual environment."
|
||||||
|
echo " -l Load and display a *.hdf5 data file in a graphical"
|
||||||
|
echo " window."
|
||||||
|
echo " -v Print the version."
|
||||||
|
echo " -h Show this help message."
|
||||||
|
echo ""
|
||||||
|
echo " bash This command starts an interactive bash shell in the"
|
||||||
|
echo " MsSpec container."
|
||||||
|
echo " reset This command removes the MsSpec container (but not the"
|
||||||
|
echo " image). Changes made in the container will be lost and"
|
||||||
|
echo " any new call to msspec will recreate a new fresh container."
|
||||||
|
}
|
||||||
|
|
||||||
|
case $1 in
|
||||||
|
reset) Remove_MsSpecContainer ;;
|
||||||
|
bash) Start_MsSpecContainer; Run_Bash ;;
|
||||||
|
"-u") Uninstall_MsSpecImage ;;
|
||||||
|
"-h"|"") Start_MsSpecContainer; Show_Help ;;
|
||||||
|
*) Start_MsSpecContainer; Run_MsSpec "$@" ;;
|
||||||
|
esac
|
|
@ -0,0 +1,219 @@
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// Inno Setup Ver: 5.4.2
|
||||||
|
// Script Version: 1.4.2
|
||||||
|
// Author: Jared Breland <jbreland@legroom.net>
|
||||||
|
// Homepage: http://www.legroom.net/software
|
||||||
|
// License: GNU Lesser General Public License (LGPL), version 3
|
||||||
|
// http://www.gnu.org/licenses/lgpl.html
|
||||||
|
//
|
||||||
|
// Script Function:
|
||||||
|
// Allow modification of environmental path directly from Inno Setup installers
|
||||||
|
//
|
||||||
|
// Instructions:
|
||||||
|
// Copy modpath.iss to the same directory as your setup script
|
||||||
|
//
|
||||||
|
// Add this statement to your [Setup] section
|
||||||
|
// ChangesEnvironment=true
|
||||||
|
//
|
||||||
|
// Add this statement to your [Tasks] section
|
||||||
|
// You can change the Description or Flags
|
||||||
|
// You can change the Name, but it must match the ModPathName setting below
|
||||||
|
// Name: modifypath; Description: &Add application directory to your environmental path; Flags: unchecked
|
||||||
|
//
|
||||||
|
// Add the following to the end of your [Code] section
|
||||||
|
// ModPathName defines the name of the task defined above
|
||||||
|
// ModPathType defines whether the 'user' or 'system' path will be modified;
|
||||||
|
// this will default to user if anything other than system is set
|
||||||
|
// setArrayLength must specify the total number of dirs to be added
|
||||||
|
// Result[0] contains first directory, Result[1] contains second, etc.
|
||||||
|
// const
|
||||||
|
// ModPathName = 'modifypath';
|
||||||
|
// ModPathType = 'user';
|
||||||
|
//
|
||||||
|
// function ModPathDir(): TArrayOfString;
|
||||||
|
// begin
|
||||||
|
// setArrayLength(Result, 1);
|
||||||
|
// Result[0] := ExpandConstant('{app}');
|
||||||
|
// end;
|
||||||
|
// #include "modpath.iss"
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
procedure ModPath();
|
||||||
|
var
|
||||||
|
oldpath: String;
|
||||||
|
newpath: String;
|
||||||
|
updatepath: Boolean;
|
||||||
|
pathArr: TArrayOfString;
|
||||||
|
aExecFile: String;
|
||||||
|
aExecArr: TArrayOfString;
|
||||||
|
i, d: Integer;
|
||||||
|
pathdir: TArrayOfString;
|
||||||
|
regroot: Integer;
|
||||||
|
regpath: String;
|
||||||
|
|
||||||
|
begin
|
||||||
|
// Get constants from main script and adjust behavior accordingly
|
||||||
|
// ModPathType MUST be 'system' or 'user'; force 'user' if invalid
|
||||||
|
if ModPathType = 'system' then begin
|
||||||
|
regroot := HKEY_LOCAL_MACHINE;
|
||||||
|
regpath := 'SYSTEM\CurrentControlSet\Control\Session Manager\Environment';
|
||||||
|
end else begin
|
||||||
|
regroot := HKEY_CURRENT_USER;
|
||||||
|
regpath := 'Environment';
|
||||||
|
end;
|
||||||
|
|
||||||
|
// Get array of new directories and act on each individually
|
||||||
|
pathdir := ModPathDir();
|
||||||
|
for d := 0 to GetArrayLength(pathdir)-1 do begin
|
||||||
|
updatepath := true;
|
||||||
|
|
||||||
|
// Modify WinNT path
|
||||||
|
if UsingWinNT() = true then begin
|
||||||
|
|
||||||
|
// Get current path, split into an array
|
||||||
|
RegQueryStringValue(regroot, regpath, 'Path', oldpath);
|
||||||
|
oldpath := oldpath + ';';
|
||||||
|
i := 0;
|
||||||
|
|
||||||
|
while (Pos(';', oldpath) > 0) do begin
|
||||||
|
SetArrayLength(pathArr, i+1);
|
||||||
|
pathArr[i] := Copy(oldpath, 0, Pos(';', oldpath)-1);
|
||||||
|
oldpath := Copy(oldpath, Pos(';', oldpath)+1, Length(oldpath));
|
||||||
|
i := i + 1;
|
||||||
|
|
||||||
|
// Check if current directory matches app dir
|
||||||
|
if pathdir[d] = pathArr[i-1] then begin
|
||||||
|
// if uninstalling, remove dir from path
|
||||||
|
if IsUninstaller() = true then begin
|
||||||
|
continue;
|
||||||
|
// if installing, flag that dir already exists in path
|
||||||
|
end else begin
|
||||||
|
updatepath := false;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
// Add current directory to new path
|
||||||
|
if i = 1 then begin
|
||||||
|
newpath := pathArr[i-1];
|
||||||
|
end else begin
|
||||||
|
newpath := newpath + ';' + pathArr[i-1];
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
// Append app dir to path if not already included
|
||||||
|
if (IsUninstaller() = false) AND (updatepath = true) then
|
||||||
|
newpath := newpath + ';' + pathdir[d];
|
||||||
|
|
||||||
|
// Write new path
|
||||||
|
RegWriteStringValue(regroot, regpath, 'Path', newpath);
|
||||||
|
|
||||||
|
// Modify Win9x path
|
||||||
|
end else begin
|
||||||
|
|
||||||
|
// Convert to shortened dirname
|
||||||
|
pathdir[d] := GetShortName(pathdir[d]);
|
||||||
|
|
||||||
|
// If autoexec.bat exists, check if app dir already exists in path
|
||||||
|
aExecFile := 'C:\AUTOEXEC.BAT';
|
||||||
|
if FileExists(aExecFile) then begin
|
||||||
|
LoadStringsFromFile(aExecFile, aExecArr);
|
||||||
|
for i := 0 to GetArrayLength(aExecArr)-1 do begin
|
||||||
|
if IsUninstaller() = false then begin
|
||||||
|
// If app dir already exists while installing, skip add
|
||||||
|
if (Pos(pathdir[d], aExecArr[i]) > 0) then
|
||||||
|
updatepath := false;
|
||||||
|
break;
|
||||||
|
end else begin
|
||||||
|
// If app dir exists and = what we originally set, then delete at uninstall
|
||||||
|
if aExecArr[i] = 'SET PATH=%PATH%;' + pathdir[d] then
|
||||||
|
aExecArr[i] := '';
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
// If app dir not found, or autoexec.bat didn't exist, then (create and) append to current path
|
||||||
|
if (IsUninstaller() = false) AND (updatepath = true) then begin
|
||||||
|
SaveStringToFile(aExecFile, #13#10 + 'SET PATH=%PATH%;' + pathdir[d], True);
|
||||||
|
|
||||||
|
// If uninstalling, write the full autoexec out
|
||||||
|
end else begin
|
||||||
|
SaveStringsToFile(aExecFile, aExecArr, False);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
// Split a string into an array using passed delimeter
|
||||||
|
procedure MPExplode(var Dest: TArrayOfString; Text: String; Separator: String);
|
||||||
|
var
|
||||||
|
i: Integer;
|
||||||
|
begin
|
||||||
|
i := 0;
|
||||||
|
repeat
|
||||||
|
SetArrayLength(Dest, i+1);
|
||||||
|
if Pos(Separator,Text) > 0 then begin
|
||||||
|
Dest[i] := Copy(Text, 1, Pos(Separator, Text)-1);
|
||||||
|
Text := Copy(Text, Pos(Separator,Text) + Length(Separator), Length(Text));
|
||||||
|
i := i + 1;
|
||||||
|
end else begin
|
||||||
|
Dest[i] := Text;
|
||||||
|
Text := '';
|
||||||
|
end;
|
||||||
|
until Length(Text)=0;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure CurStepChanged(CurStep: TSetupStep);
|
||||||
|
var
|
||||||
|
taskname: String;
|
||||||
|
begin
|
||||||
|
taskname := ModPathName;
|
||||||
|
if CurStep = ssPostInstall then
|
||||||
|
if WizardIsTaskSelected(taskname) then
|
||||||
|
ModPath();
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure CurUninstallStepChanged(CurUninstallStep: TUninstallStep);
|
||||||
|
var
|
||||||
|
aSelectedTasks: TArrayOfString;
|
||||||
|
i: Integer;
|
||||||
|
taskname: String;
|
||||||
|
regpath: String;
|
||||||
|
regstring: String;
|
||||||
|
appid: String;
|
||||||
|
begin
|
||||||
|
// only run during actual uninstall
|
||||||
|
if CurUninstallStep = usUninstall then begin
|
||||||
|
// get list of selected tasks saved in registry at install time
|
||||||
|
appid := '{#emit SetupSetting("AppId")}';
|
||||||
|
if appid = '' then appid := '{#emit SetupSetting("AppName")}';
|
||||||
|
regpath := ExpandConstant('Software\Microsoft\Windows\CurrentVersion\Uninstall\'+appid+'_is1');
|
||||||
|
RegQueryStringValue(HKLM, regpath, 'Inno Setup: Selected Tasks', regstring);
|
||||||
|
if regstring = '' then RegQueryStringValue(HKCU, regpath, 'Inno Setup: Selected Tasks', regstring);
|
||||||
|
|
||||||
|
// check each task; if matches modpath taskname, trigger patch removal
|
||||||
|
if regstring <> '' then begin
|
||||||
|
taskname := ModPathName;
|
||||||
|
MPExplode(aSelectedTasks, regstring, ',');
|
||||||
|
if GetArrayLength(aSelectedTasks) > 0 then begin
|
||||||
|
for i := 0 to GetArrayLength(aSelectedTasks)-1 do begin
|
||||||
|
if comparetext(aSelectedTasks[i], taskname) = 0 then
|
||||||
|
ModPath();
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function NeedRestart(): Boolean;
|
||||||
|
var
|
||||||
|
taskname: String;
|
||||||
|
begin
|
||||||
|
taskname := ModPathName;
|
||||||
|
if WizardIsTaskSelected(taskname) and not UsingWinNT() then begin
|
||||||
|
Result := True;
|
||||||
|
end else begin
|
||||||
|
Result := False;
|
||||||
|
end;
|
||||||
|
end;
|
Binary file not shown.
|
@ -0,0 +1,69 @@
|
||||||
|
; Script generated by the Inno Setup Script Wizard.
|
||||||
|
; SEE THE DOCUMENTATION FOR DETAILS ON CREATING INNO SETUP SCRIPT FILES!
|
||||||
|
|
||||||
|
#define MyAppName "MsSpec"
|
||||||
|
#define MyAppVersion ""
|
||||||
|
#define MyAppPublisher "IPR"
|
||||||
|
#define MyAppURL "https://msspec.cnrs.fr"
|
||||||
|
#define MyAppExeName "msspec.exe"
|
||||||
|
#define MyAppInstallerName "msspec_setup"
|
||||||
|
|
||||||
|
[Setup]
|
||||||
|
; NOTE: The value of AppId uniquely identifies this application. Do not use the same AppId value in installers for other applications.
|
||||||
|
; (To generate a new GUID, click Tools | Generate GUID inside the IDE.)
|
||||||
|
AppId={{BB2F7A31-BDDF-4D22-BDBD-C77BEB6D3780}}
|
||||||
|
AppName={#MyAppName}
|
||||||
|
;AppVersion={#MyAppVersion}
|
||||||
|
AppVerName={#MyAppName} {#MyAppVersion}
|
||||||
|
AppPublisher={#MyAppPublisher}
|
||||||
|
AppPublisherURL={#MyAppURL}
|
||||||
|
AppSupportURL={#MyAppURL}
|
||||||
|
AppUpdatesURL={#MyAppURL}
|
||||||
|
DefaultDirName={autopf}\{#MyAppName}
|
||||||
|
DefaultGroupName={#MyAppName}
|
||||||
|
DisableProgramGroupPage=yes
|
||||||
|
; Uncomment the following line to run in non administrative install mode (install for current user only.)
|
||||||
|
;PrivilegesRequired=lowest
|
||||||
|
PrivilegesRequiredOverridesAllowed=dialog
|
||||||
|
OutputBaseFilename={#MyAppInstallerName}
|
||||||
|
Compression=lzma
|
||||||
|
SolidCompression=yes
|
||||||
|
WizardStyle=modern
|
||||||
|
ChangesEnvironment=true
|
||||||
|
|
||||||
|
[Languages]
|
||||||
|
Name: "english"; MessagesFile: "compiler:Default.isl"
|
||||||
|
|
||||||
|
[Files]
|
||||||
|
Source: ".\{#MyAppExeName}"; DestDir: "{app}"; Flags: ignoreversion
|
||||||
|
;Source: "D:\Home\stricot\Documents\WindowsPowerShell\Scripts\{#MyAppExeName}"; DestDir: "{app}"; Flags: ignoreversion
|
||||||
|
; NOTE: Don't use "Flags: ignoreversion" on any shared system files
|
||||||
|
|
||||||
|
;[Icons]
|
||||||
|
;Name: "{group}\{#MyAppName}"; Filename: "{app}\{#MyAppExeName}"
|
||||||
|
|
||||||
|
;[Run]
|
||||||
|
;Filename: "{app}\{#MyAppExeName}"; Description: "{cm:LaunchProgram,{#StringChange(MyAppName, '&', '&&')}}"; Flags: nowait postinstall skipifsilent
|
||||||
|
|
||||||
|
[Tasks]
|
||||||
|
Name: modifypath; Description: Add application directory to your environmental path;
|
||||||
|
;Flags: unchecked
|
||||||
|
|
||||||
|
[UninstallRun]
|
||||||
|
Filename: "{app}\{#MyAppExeName}"; Parameters: "-u";
|
||||||
|
|
||||||
|
[Messages]
|
||||||
|
FinishedLabelNoIcons=Setup has finished installing [name] on your computer. To launch MsSpec, open a terminal window and enter 'msspec'.
|
||||||
|
|
||||||
|
[Code]
|
||||||
|
const
|
||||||
|
ModPathName = 'modifypath';
|
||||||
|
ModPathType = 'user';
|
||||||
|
|
||||||
|
function ModPathDir(): TArrayOfString;
|
||||||
|
begin
|
||||||
|
setArrayLength(Result, 1)
|
||||||
|
Result[0] := ExpandConstant('{app}');
|
||||||
|
end;
|
||||||
|
#include "modpath.iss"
|
||||||
|
|
|
@ -0,0 +1,171 @@
|
||||||
|
##[Ps1 To Exe]
|
||||||
|
##
|
||||||
|
##Kd3HDZOFADWE8uK1
|
||||||
|
##Nc3NCtDXThU=
|
||||||
|
##Kd3HFJGZHWLWoLaVvnQnhQ==
|
||||||
|
##LM/RF4eFHHGZ7/K1
|
||||||
|
##K8rLFtDXTiW5
|
||||||
|
##OsHQCZGeTiiZ4tI=
|
||||||
|
##OcrLFtDXTiW5
|
||||||
|
##LM/BD5WYTiiZ4tI=
|
||||||
|
##McvWDJ+OTiiZ4tI=
|
||||||
|
##OMvOC56PFnzN8u+Vs1Q=
|
||||||
|
##M9jHFoeYB2Hc8u+Vs1Q=
|
||||||
|
##PdrWFpmIG2HcofKIo2QX
|
||||||
|
##OMfRFJyLFzWE8uK1
|
||||||
|
##KsfMAp/KUzWJ0g==
|
||||||
|
##OsfOAYaPHGbQvbyVvnQX
|
||||||
|
##LNzNAIWJGmPcoKHc7Do3uAuO
|
||||||
|
##LNzNAIWJGnvYv7eVvnQX
|
||||||
|
##M9zLA5mED3nfu77Q7TV64AuzAgg=
|
||||||
|
##NcDWAYKED3nfu77Q7TV64AuzAgg=
|
||||||
|
##OMvRB4KDHmHQvbyVvnQX
|
||||||
|
##P8HPFJGEFzWE8tI=
|
||||||
|
##KNzDAJWHD2fS8u+Vgw==
|
||||||
|
##P8HSHYKDCX3N8u+Vgw==
|
||||||
|
##LNzLEpGeC3fMu77Ro2k3hQ==
|
||||||
|
##L97HB5mLAnfMu77Ro2k3hQ==
|
||||||
|
##P8HPCZWEGmaZ7/K1
|
||||||
|
##L8/UAdDXTlGDjpra7jFL9l/8S2skevm/trWyyYSy6/nQjCzXTZUDWmR4gSzuN0O4Vf4uZvYHvcEFRiEnPOEb57GeHv+sJQ==
|
||||||
|
##Kc/BRM3KXhU=
|
||||||
|
##
|
||||||
|
##
|
||||||
|
##fd6a9f26a06ea3bc99616d4851b372ba
|
||||||
|
# PowerShell
|
||||||
|
|
||||||
|
$SCRIPT_PATH = $MyInvocation.MyCommand.Path
|
||||||
|
$IMAGE_NAME = "iprcnrs/msspec:latest"
|
||||||
|
|
||||||
|
Function Read-YesNo($PROMPT, $DEFAULT) {
|
||||||
|
$VALID = 1
|
||||||
|
While($VALID -ne 0) {
|
||||||
|
$ANSWER = Read-Host "$PROMPT (y/n) [$DEFAULT]? "
|
||||||
|
Switch($ANSWER) {
|
||||||
|
"" {$ANSWER=$DEFAULT; $VALID=0; Break}
|
||||||
|
"y" {$VALID=0; Break}
|
||||||
|
"n" {$VALID=0; Break}
|
||||||
|
Default {Write-Host "Invalid choice, please answer 'y' or 'n'."; $VALID=1; Break}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Return $ANSWER
|
||||||
|
}
|
||||||
|
|
||||||
|
Function Get-MsSpecContainerID {
|
||||||
|
Return docker ps -a -q --filter ancestor=$IMAGE_NAME
|
||||||
|
}
|
||||||
|
|
||||||
|
Function Get-MsSpecImageID {
|
||||||
|
Return docker images -q $IMAGE_NAME
|
||||||
|
}
|
||||||
|
|
||||||
|
Function Add-MsSpecImage {
|
||||||
|
Write-Host "Pulling MsSpec image...";
|
||||||
|
docker pull $IMAGE_NAME;
|
||||||
|
Write-Host "done."
|
||||||
|
$IID = Get-MsSpecImageID;
|
||||||
|
Return $IID;
|
||||||
|
}
|
||||||
|
|
||||||
|
Function Add-MsSpecContainer {
|
||||||
|
$CID = Get-MsSpecContainerID
|
||||||
|
If($CID -eq $NULL) {
|
||||||
|
$IID = Get-MsSpecImageID
|
||||||
|
If($IID -eq $NULL) {
|
||||||
|
#Add-MsSpecImage;
|
||||||
|
}
|
||||||
|
Write-Host -nonewline "Creating the MsSpec container... "
|
||||||
|
$mydocuments = [environment]::GetFolderPath("mydocuments")
|
||||||
|
$drive = ($mydocuments -split ":",2)[0]
|
||||||
|
docker create -i -v ${drive}:\:/$drive --entrypoint /bin/bash $IMAGE_NAME >$NULL
|
||||||
|
$CID = Get-MsSpecContainerID
|
||||||
|
Write-Host "done."
|
||||||
|
}
|
||||||
|
Return $CID
|
||||||
|
}
|
||||||
|
|
||||||
|
Function Start-MsSpecContainer {
|
||||||
|
$CID = Add-MsSpecContainer;
|
||||||
|
$status = docker container inspect -f '{{.State.Status}}' $CID;
|
||||||
|
IF($status -ne "running") {
|
||||||
|
Write-Host -nonewline "Starting MsSpec container...";
|
||||||
|
$CID = docker start $CID;
|
||||||
|
Write-Host "done.";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Function Remove-MsSpecContainer {
|
||||||
|
Write-Host -nonewline "Removing MsSpec container...";
|
||||||
|
$CID = Get-MsSpecContainerID;
|
||||||
|
IF($CID -ne $NULL) {
|
||||||
|
docker stop -t 1 $CID >$NULL;
|
||||||
|
docker rm $CID >$NULL;
|
||||||
|
}
|
||||||
|
Write-Host "done."
|
||||||
|
}
|
||||||
|
|
||||||
|
Function Run-MsSpec($opts) {
|
||||||
|
# Run msspec command
|
||||||
|
$CID = Get-MsSpecContainerID;
|
||||||
|
$nixPath = "/" + (${PWD} -replace "\\","/") -replace ":",""
|
||||||
|
docker exec -i -t -e DISPLAY=host.docker.internal:0 -w $nixPath $CID msspec $opts
|
||||||
|
}
|
||||||
|
|
||||||
|
Function Run-Bash {
|
||||||
|
# Run bash
|
||||||
|
$CID = Get-MsSpecContainerID;
|
||||||
|
$nixPath = "/" + (${PWD} -replace "\\","/") -replace ":",""
|
||||||
|
docker exec -i -t -w $nixPath -e DISPLAY=host.docker.internal:0 $CID /bin/bash
|
||||||
|
}
|
||||||
|
|
||||||
|
Function Uninstall-MsSpecImage {
|
||||||
|
$ANSWER = Read-YesNo "You are about to remove the MsSpec Docker image, its container and this script. Are you sure" "n"
|
||||||
|
Switch($ANSWER) {
|
||||||
|
"y" {Remove-MsSpecContainer;
|
||||||
|
Write-Host -nonewline "Removing $IMAGE_NAME...";
|
||||||
|
$IID = Get-MsSpecImageID;
|
||||||
|
If($IID -ne $NULL) {
|
||||||
|
docker rmi $IMAGE_NAME >$NULL;
|
||||||
|
}
|
||||||
|
Write-Host "done.";
|
||||||
|
# Remove-Item $THIS_SCRIPT;
|
||||||
|
Break;
|
||||||
|
}
|
||||||
|
"n" {Write-Host "Uninstallation aborted."; Break}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Function Show-Help {
|
||||||
|
Write-Host "Usage: 1) msspec -p [PYTHON OPTIONS] SCRIPT [ARGUMENTS...]"
|
||||||
|
Write-Host " 2) msspec [-l FILE | -i | -h]"
|
||||||
|
Write-Host " 3) msspec [bash | reset]"
|
||||||
|
Write-Host ""
|
||||||
|
Write-Host "Form (1) is used to launch a script"
|
||||||
|
Write-Host "Form (2) is used to load a hdf5 data file"
|
||||||
|
Write-Host "Form (3) is used to control the Docker container/image."
|
||||||
|
Write-Host ""
|
||||||
|
Write-Host "List of possible options:"
|
||||||
|
Write-Host " -p Pass every arguments after this option to the msspec"
|
||||||
|
Write-Host " virtual environment Python interpreter."
|
||||||
|
Write-Host " -i Run the interactive Python interpreter within msspec"
|
||||||
|
Write-Host " virtual environment."
|
||||||
|
Write-Host " -l Load and display a *.hdf5 data file in a graphical"
|
||||||
|
Write-Host " window."
|
||||||
|
Write-Host " -v Print the version."
|
||||||
|
Write-Host " -h Show this help message."
|
||||||
|
Write-Host ""
|
||||||
|
Write-Host " bash This command starts an interactive bash shell in the"
|
||||||
|
Write-Host " MsSpec container."
|
||||||
|
Write-Host " reset This command removes the MsSpec container (but not the"
|
||||||
|
Write-Host " image). Changes made in the container will be lost and"
|
||||||
|
Write-Host " any new call to msspec will recreate a new fresh container."
|
||||||
|
}
|
||||||
|
|
||||||
|
Switch($args[0]) {
|
||||||
|
"reset" {Remove-MsSpecContainer; Break}
|
||||||
|
"bash" {Start-MsSpecContainer; Run-Bash; Break}
|
||||||
|
"-u" {Uninstall-MsSpecImage; Break}
|
||||||
|
"-h" {Start-MsSpecContainer; Show-Help; Break}
|
||||||
|
"" {Start-MsSpecContainer; Show-Help; Break}
|
||||||
|
Default {Start-MsSpecContainer; Run-MsSpec $args; Break}
|
||||||
|
pull {Add-MsSpecImage; Break}
|
||||||
|
}
|
Binary file not shown.
Loading…
Reference in New Issue