diff options
-rw-r--r-- | .gitlab-ci.yml | 17 | ||||
-rw-r--r-- | AUTHORS | 4 | ||||
-rw-r--r-- | CONTRIBUTING.md | 4 | ||||
-rw-r--r-- | ChangeLog | 4 | ||||
-rw-r--r-- | INSTALL.md | 151 | ||||
-rw-r--r-- | README.md | 8 | ||||
-rw-r--r-- | crystfel.rb | 4 | ||||
-rw-r--r-- | doc/man/align_detector.1.md | 4 | ||||
-rw-r--r-- | doc/man/crystfel.7 | 50 | ||||
-rw-r--r-- | libcrystfel/src/datatemplate.c | 10 | ||||
-rw-r--r-- | meson.build | 4 | ||||
-rw-r--r-- | relnotes-0.10.2.md | 161 | ||||
-rw-r--r-- | relnotes-0.11.0.md | 172 | ||||
-rw-r--r-- | scripts/turbo-index-lsf | 2 | ||||
-rwxr-xr-x | scripts/turbo-index-slurm | 2 | ||||
-rw-r--r-- | src/align_detector.c | 1 | ||||
-rw-r--r-- | src/gui_align.c | 80 | ||||
-rw-r--r-- | src/gui_backend_slurm.c | 2 | ||||
-rw-r--r-- | src/im-asapo.c | 17 | ||||
-rwxr-xr-x | tests/geom_roundtrip | 64 |
20 files changed, 454 insertions, 307 deletions
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index e267cf25..4d1d1038 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,9 +1,8 @@ stages: - test - - test_brew - - build_container - deploy - + - build_container + .build-and-test: image: fedora:32 script: @@ -90,6 +89,8 @@ build_container_image: tags: - kubernetes + when: manual + build_container_image_tag: stage: build_container image: @@ -117,16 +118,17 @@ build_container_image_tag: rules: - if: $CI_COMMIT_TAG + when: manual -build-native-macos: +.build-native-macos: tags: - macOS variables: GIT_STRATEGY: clone script: - brew update - - brew upgrade - - brew install gsl hdf5 flex bison argp-standalone pkg-config doxygen gtk+3 cairo pango gdk-pixbuf fftw meson ninja python python-tk + - brew upgrade -f + - brew install gsl hdf5 flex bison argp-standalone pkg-config doxygen gtk+3 cairo pango gdk-pixbuf fftw meson ninja - export PATH="$(brew --prefix)/opt/bison/bin:$(brew --prefix)/opt/flex/bin:$PATH" - export LDFLAGS="-L$(brew --prefix)/opt/bison/lib -L$(brew --prefix)/opt/flex/lib -L$(brew --prefix)/opt/argp-standalone/lib -largp $LDFLAGS" - export CFLAGS="-I$(brew --prefix)/opt/flex/include -I$(brew --prefix)/opt/argp-standalone/include/ $CFLAGS" @@ -141,7 +143,6 @@ build-native-macos: junit: build/meson-logs/testlog.junit.xml build-brew-macos: - stage: test_brew dependencies: [] tags: - macOS @@ -149,7 +150,7 @@ build-brew-macos: GIT_STRATEGY: clone script: - brew update - - brew upgrade + - brew upgrade -f - brew uninstall -v -f crystfel - brew install -v -s ./crystfel.rb --HEAD - brew test crystfel @@ -106,9 +106,13 @@ * Philipp Middendorf <philipp.middendorf@desy.de> Gitlab continuous integration + General bug fixes * Nicholas Devenish <ndevenish@gmail.com> Build system bug fixing * Silvan Schön <silvan.schoen@cfel.de> Container images and CI + +* Parthasarathy Tirumalai <parthasarathy.tirumalai@desy.de> + Deployment, CI, MacOS testing diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 50cab3b5..66d1ea62 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -13,8 +13,8 @@ The easiest way to ensure the future of CrystFEL is to use it and cite it in you You can also cite CrystFEL directly using one of the following DOIs: -* All versions: [10.5281/zenodo.8183384](https://zenodo.org/record/8183384). -* Version 0.10.2: [10.5281/zenodo.8183385](https://zenodo.org/record/8183385). +* All versions: [10.5281/zenodo.8183384](https://doi.org/10.5281/zenodo.8183384). +* This version (0.11.0): [10.5281/zenodo.10984700](https://doi.org/zenodo.10984700). Getting started @@ -1,5 +1,5 @@ -Changes in this development version ------------------------------------ +CrystFEL version 0.11.0, 17 April 2024 +-------------------------------------- - New detector geometry refinement system, using Millepede-II - New Homebrew formula and better build/test support for Mac OS @@ -1,10 +1,8 @@ Installation instructions ========================= -CrystFEL installation is easiest on GNU/Linux. Installation on Mac OS X is -supported, but more difficult because you have to get all the dependencies -from a third-party repository. Installation in Windows via -[Windows Subsystem for Linux](https://docs.microsoft.com/en-us/windows/wsl/) +CrystFEL installation is supported on GNU/Linux and Mac OS X. Installation in +Windows via [Windows Subsystem for Linux](https://docs.microsoft.com/en-us/windows/wsl/) is also possible. @@ -16,11 +14,11 @@ to find out if there's already a CrystFEL installation available at your site. If you want to use CrystFEL on a facility computer system, we recommend leaving the installation to facility IT staff. This means that a single installation -can be shared and maintained. In addition, installing software from source, on -a system where you don't have administrative access, can be quite difficult. -Please feel free to tell the IT staff to get in touch with us for assistance, -and also to make sure that the installation is documented on the list of -supported facility installations. +can be shared and maintained centrally. In addition, installing software from +source, on a system where you don't have administrative access, can be quite +difficult. Please feel free to tell the IT staff to get in touch with us for +assistance, and also to make sure that the installation is documented on the +list of supported facility installations. Installation via container registry @@ -58,7 +56,7 @@ CrystFEL is available through <a href="https://nixos.org/">NixOS</a> since 22.05, for x86_64, Darwin and aarch64. Two packages are available. Package `crystfel` contains all tools including the GUI, whereas `crystfel-headless` excludes the GUI, making it easier to -install and more suitable for (e.g.) backend data processing servers. +install and more suitable for backend data processing servers. To install via NixOS, simply add the package globally to your `environment.systemPackages`, or enter a temporary shell via `nix shell @@ -67,17 +65,58 @@ nixpkgs#crystfel` to have all CrystFEL tools in your `PATH`. ### Homebrew To install the development version of CrystFEL using -<a href="https://brew.sh/">Homebrew</a>, run the following: +[Homebrew](https://brew.sh/), download the latest version of +[crystfel.rb](https://gitlab.desy.de/thomas.white/crystfel/-/blob/master/crystfel.rb) +from the Git repository, and use `brew install`: ``` -$ git clone https://gitlab.desy.de/thomas.white/crystfel.git -$ cd crystfel +$ wget https://gitlab.desy.de/thomas.white/crystfel/-/raw/master/crystfel.rb $ brew install -v -s ./crystfel.rb --HEAD ``` +Omit `--HEAD` to install the latest stable version. + +Note that the Homebrew formulae included in the "tarball" release files always +refer to the *previous* release. This is because the formula has to contain +the SHA256 hash of the downloaded tarball, which is not known until after the +tarball has been created! We hope to contribute the Homebrew formula to the main repository soon, so that you can install CrystFEL with a simple `brew install crystfel`. +Installation from source +------------------------ + +CrystFEL is compiled and installed using [Meson](https://mesonbuild.com/). +First, download the latest Git version or unpack the package from the +[downloads page](https://desy.de/~twhite/crystfel/download.html): +``` +$ git clone https://gitlab.desy.de/thomas.white/crystfel.git +$ cd crystfel + or +$ tar -xzf crystfel-0.11.0.tar.gz # or whichever other version +$ cd crystfel-0.11.0 +``` +Then, simply: +``` +$ meson setup build +$ meson compile -C build +$ meson install -C build +``` +The `meson setup` command will report if dependencies are missing - see the +next section for details. If necessary, the `meson install` command will ask +for your password to gain administrative privileges. + +Run `indexamajig` for a basic check that the installation has succeeded. A +healthy newborn CrystFEL should complain that `You need to provide the input +filename (use -i)` when run with no other command-line options. + +Alternatively, run `crystfel` to start the graphical user interface, provided +that the dependencies for the GUI were met (see above). + +Refer to the [tutorial](doc/articles/tutorial.rst) to see where to go from +here! + + Dependencies ------------ @@ -116,8 +155,8 @@ distribution's package manager, or from [Homebrew](https://brew.sh/) on Mac OS. We emphatically recommend against trying to install GTK, Cairo, Pango or gdk-pixbuf from source. -If you compile using Meson, dependencies marked with \[\*\] above will be -downloaded and compiled automatically if they are not available on the system. +Dependencies marked with \[\*\] above will be downloaded and compiled +automatically by Meson if they are not available on the system. If you don't want this, add option `--wrap-mode=nofallback` when invoking Meson. See the Meson manual for other possibilities, such as using locally-provided files instead of downloading them. @@ -136,14 +175,19 @@ environment. Don't even "source" the Conda setup file before installing CrystFEL - keep it completely separate. A Conda recipe for CrystFEL might be coming soon, though, if development resources allow for it. + Installing the indexing engines ------------------------------- -Processing data relies on indexing 'engines'. By default, you will have access -to the [TakeTwo](https://journals.iucr.org/d/issues/2016/08/00/rr5128/) -indexing algorithm. Some of the optional dependencies listed above, if found, -will add more indexing algorithms. In addition, the following programs will be -used for indexing if they are available: +Processing data relies on indexing 'engines'. At the absolute minimum, you +will have access to the [TakeTwo](https://journals.iucr.org/d/issues/2016/08/00/rr5128/) +indexing algorithm, since this is built into CrystFEL and does not have any +other dependencies. [Xgandalf](https://journals.iucr.org/a/issues/2019/05/00/ae5071/), +[PinkIndexer](https://journals.iucr.org/a/issues/2020/02/00/ae5078/) and +`asdf` will very likely be available as well - they have some dependencies +(see above), but the required packages are quite common. Still more indexing +methods can be enabled by installing one or more of the following external +programs: * [Mosflm](https://www.mrc-lmb.cam.ac.uk/mosflm/mosflm/) * [DirAx](http://www.crystal.chem.uu.nl/distr/dirax/) @@ -154,7 +198,7 @@ You can install these at any time before or after installing CrystFEL. Note that you only need the Mosflm binary, not the full `iMosflm` user interface. [Download it here](https://www.mrc-lmb.cam.ac.uk/mosflm/mosflm/ver740/pre-built/mosflm-linux-64-noX11.zip). -You probably have CCP4 installed already, with its own copy of `mosflm`. +You probably have CCP4 installed already, which comes with its own copy of `mosflm`. However, you should keep your CCP4 installation separate from CrystFEL. The reason is that CCP4 comes with its own private copies of all its dependencies, and it becomes very difficult to make the build process for CrystFEL (or @@ -167,6 +211,20 @@ The script `install-indexers`, found in the `scripts` directory of the CrystFEL source code, can help you to install Mosflm, DirAx and XDS. Run `scripts/install-indexers --help` for information. + +Finding syminfo.lib +------------------- + +The CCP4 libraries need to refer to symmetry information in a file called +`syminfo.lib`. Unfortunately, they can only find this file if either `CLIBD` +or `SYMINFO` are set in the environment. The CrystFEL GUI (`crystfel`), +`get_hkl` and `mosflm` therefore all need this variable to be set. You could +set this variable in your shell setup file (e.g. as part of a `module load`), +or create wrapper scripts for these three programs. The `install-indexers` +script, which assists with installing indexing engines, creates such a wrapper +for Mosflm already. + + Compiling without HDF5 ---------------------- @@ -179,6 +237,7 @@ as follows, replacing the `meson build` step: meson build -Dhdf5=disabled ``` + Fedora 22 or later ------------------ @@ -290,56 +349,6 @@ $ sudo ninja -C build install $ sudo ldconfig ``` -Mac OS X --------- - -First install [Homebrew](https://brew.sh/), which will also cause -[Xcode](https://developer.apple.com/xcode/) to be installed. Then: - -``` -$ brew install gsl hdf5 flex bison argp-standalone pkg-config doxygen gtk+3 cairo pango gdk-pixbuf fftw meson -$ export PATH="$(brew --prefix)/opt/bison/bin:$(brew --prefix)/opt/flex/bin:$PATH" -$ export LDFLAGS="-L$(brew --prefix)/opt/bison/lib -L$(brew --prefix)/opt/flex/lib -L$(brew --prefix)/opt/argp-standalone/lib -largp $LDFLAGS" -$ export CFLAGS="-I$(brew --prefix)/opt/flex/include -I$(brew --prefix)/opt/argp-standalone/include/ $CFLAGS" -$ cd /home/user/downloads/crystfel -$ meson build -$ ninja -C build -$ ninja -C build install -``` - -The `export` commands ensure that the libraries installed via Homebrew can be -found by CrystFEL's build system. - -CrystFEL itself is compatible with M1 Macs, but some of the dependencies have -problems. Meson will try to build the dependencies anyway, resulting in a -failure. If this happens to you, add `--wrap-mode=nofallback` (as mentioned -above) to disable automatic building of dependencies. - - -Starting up ------------ - -Run `indexamajig` for a basic check that the installation has succeeded. A -healthy newborn CrystFEL should complain that `You need to provide the input -filename (use -i)` when run with no other command-line options. - -Alternatively, run `crystfel` to start the graphical user interface, provided -that the dependencies for the GUI were met (see above). - -Refer to the tutorial to see where to go from here! - - -Finding syminfo.lib -------------------- -The CCP4 libraries need to refer to symmetry information in a file called -`syminfo.lib`. Unfortunately, they can only find this file if either `CLIBD` -or `SYMINFO` are set in the environment. The CrystFEL GUI (`crystfel`), -`get_hkl` and `mosflm` therefore all need this variable to be set. You could -set this variable in your shell setup file (e.g. as part of a `module load`), -or create wrapper scripts for these three programs. The `install-indexers` -script, which assists with installing indexing engines, creates such a wrapper -for Mosflm already. - Installation problems and solutions ----------------------------------- @@ -95,7 +95,11 @@ Development of CrystFEL is primarily funded by the [Helmholtz Association](https://www.helmholtz.de/) via [DESY](https://www.desy.de/). -Partial funding for CrystFEL has previously been provided by: +Partial funding for CrystFEL has been provided by: + +* The consortium DAPHNE4NFDI in the context of the work of the NFDI e.V. The + consortium is funded by the Deutsche Forschungsgemeinschaft (DFG, German + Research Foundation) - project number 460248799 (2022-). * European Union’s Horizon 2020 research and innovation programme under grant agreement No 857641 ([ExPaNDS](https://expands.eu/)) (2019-2023). @@ -114,7 +118,7 @@ Partial funding for CrystFEL has previously been provided by: Licence ------- -Copyright © 2012-2023 Deutsches Elektronen-Synchrotron DESY, a research centre +Copyright © 2012-2024 Deutsches Elektronen-Synchrotron DESY, a research centre of the Helmholtz Association. See [AUTHORS](AUTHORS) as well as individual source code files for full details diff --git a/crystfel.rb b/crystfel.rb index 4a537ffa..3a132d39 100644 --- a/crystfel.rb +++ b/crystfel.rb @@ -6,8 +6,8 @@ class Crystfel < Formula homepage 'https://www.desy.de/~twhite/crystfel/index.html' stable do - url 'https://www.desy.de/~twhite/crystfel/crystfel-0.10.2.tar.gz' - sha256 '9c23bd9dd0ca4b9e1b54df48845062095373aa4ec1b029635c5ace9a5c7eb0fe' + url 'https://www.desy.de/~twhite/crystfel/crystfel-0.11.0.tar.gz' + sha256 'a203475987dbc51981e5374af0ad09a5c0a760e3b25daa501923e1f267e9f937' end head do diff --git a/doc/man/align_detector.1.md b/doc/man/align_detector.1.md index f5991641..ec16f87b 100644 --- a/doc/man/align_detector.1.md +++ b/doc/man/align_detector.1.md @@ -31,7 +31,9 @@ Next, run **indexamajig** as usual, but with option **--mille**. This will produce several files named **mille-data-0.bin**, **mille-data-1.bin**, **mille-data-2.bin** and so on - as many files as there were indexamajig subprocesses (set with **indexamajig -j**). Use option **--mille-dir** to -put these files in a useful location. +put these files in a useful location. If you are splitting the indexamajig +processing across a cluster, be aware that each sub-task needs to have its +own directory for **--mille-dir**. See scripts/turbo-index-slurm for details. Finally, run **align_detector**, giving it the input geometry file, the "Mille" files, a refinement level and a filename for the updated geometry file. The diff --git a/doc/man/crystfel.7 b/doc/man/crystfel.7 index 3ff25c16..a03ea0bc 100644 --- a/doc/man/crystfel.7 +++ b/doc/man/crystfel.7 @@ -1,7 +1,7 @@ .\" .\" CrystFEL main man page .\" -.\" Copyright © 2012-2023 Deutsches Elektronen-Synchrotron DESY, +.\" Copyright © 2012-2024 Deutsches Elektronen-Synchrotron DESY, .\" a research centre of the Helmholtz Association. .\" .\" Part of CrystFEL - crystallography with a FEL @@ -9,23 +9,14 @@ .TH CRYSTFEL 7 .SH NAME -CrystFEL \- data processing for FEL crystallography +CrystFEL \- data processing for serial crystallography .SH DESCRIPTION -CrystFEL is a suite of programs for processing Bragg diffraction data acquired with a free electron laser in a "serial" manner. Some of the particular characteristics of such data which call for a specialised software suite are: +CrystFEL is a suite of programs for processing data from serial crystallography +experiments, performed at synchrotron and X-ray free-electron laser facilities, +as well as in your home lab using an electron microscope. -.RS -Each crystal is used for only one exposure, and there is no oscillation, rotation nor a large bandwidth or divergence. Therefore, many or all reflections are partially integrated. -.PP -The crystals might be very small and the illumination highly coherent, leading to significant Fourier truncation effects on the detector. -.PP -Many patterns, numbering tens of thousands or more, are required, so high throughput automated processing is important. -.PP -The crystal orientations in each pattern are random and uncorrelated, which leads to special considerations during scaling and merging. -.RE - -CrystFEL includes programs processing patterns subject to the above -characteristics. The programs are: +The programs in the suite are: .IP \fBindexamajig\fR Batch indexing, integration and data reduction program, which produces a "stream" containing the indexing and integration results for each diffraction pattern. @@ -54,7 +45,7 @@ Tools for calculating figures of merit, such as completeness and R-factors. .IP \fBrender_hkl\fR A tool for rendering slices of reciprocal space in two dimensions. -.IP \fBgeoptimiser\fR +.IP \fBalign_detector\fR A program to refine and optimize detector geometry. .IP \fBlist_events\fR @@ -64,7 +55,10 @@ A tool for creating lists of events from multi-event data files. A tool for locating runs of crystals with similar orientations, e.g. from 'mini rotation series' arising from the use of a slow extrusion sample injector. .IP \fBmake_pixelmap\fR -A tool for for creating pixel maps for Cheetah, OnDA etc. +A tool for creating pixel maps for Cheetah, OnDA etc. + +.IP \fBadjust_detector\fR +A tool to alter detector geometry. .PP There is also a folder full of scripts for achieving many related tasks. @@ -123,13 +117,24 @@ to this list if you experience difficulty with "-y" at any time. \fB23\fR, \fBm-3\fR, \fB432\fR, \fB-43m\fR, \fBm-3m\fR. .SH FUNDING ACKNOWLEDGEMENTS -Development of CrystFEL is primarily funded by the Helmholtz Association via programme-oriented funds. +Development of CrystFEL is primarily funded by the Helmholtz Association via DESY. + +Partial funding for CrystFEL has been provided by: + +* The consortium DAPHNE4NFDI in the context of the work of the NFDI e.V. The + consortium is funded by the Deutsche Forschungsgemeinschaft (DFG, German + Research Foundation) - project number 460248799 (2022-). + +* European Union’s Horizon 2020 research and innovation programme under grant + agreement No 857641 (ExPaNDS) (2019-2023). -Additional funding for CrystFEL is provided by "X-Probe", a project of the European Union's 2020 Research and Innovation Program Under the Marie Skłodowska-Curie grant agreement 637295 (2015-2018). +* X-Probe, a project of the European Union's 2020 Research and Innovation + Program Under the Marie Skłodowska-Curie grant agreement 637295 (2015-2018). -Additional funding for CrystFEL is provided by the BMBF German-Russian Cooperation "SyncFELMed", grant 05K14CHA (2014-2017). +* The BMBF German-Russian Cooperation SyncFELMed, grant 05K14CHA (2014-2017). -Past funding for CrystFEL has been received from BioStruct-X, a project funded by the Seventh Framework Programme (FP7) of the European Commission. +* BioStruct-X, a project funded by the Seventh Framework Programme (FP7) of the + European Commission (2011-2016). .SH AUTHOR This page was written by Thomas White and Valerio Mariani. @@ -139,7 +144,7 @@ Report bugs to <taw@physics.org>, or visit <http://www.desy.de/~twhite/crystfel> .SH COPYRIGHT AND DISCLAIMER .PD 0 -Copyright © 2012-2023 Deutsches Elektronen-Synchrotron DESY, a research centre of the Helmholtz Association. +Copyright © 2012-2024 Deutsches Elektronen-Synchrotron DESY, a research centre of the Helmholtz Association. .PD .PP Please read the AUTHORS file in the CrystFEL source code distribution for a full list of contributions and contributors. @@ -159,7 +164,6 @@ You should have received a copy of the GNU General Public License along with Cry .BR render_hkl (1), .BR get_hkl (1), .BR cell_tool (1), -.BR geoptimiser (1), .BR whirligig (1), .BR list_events (1), .BR make_pixelmap (1), diff --git a/libcrystfel/src/datatemplate.c b/libcrystfel/src/datatemplate.c index 9c992c70..df0ad343 100644 --- a/libcrystfel/src/datatemplate.c +++ b/libcrystfel/src/datatemplate.c @@ -390,8 +390,8 @@ static int dir_conv(const char *a, double *sx, double *sy, double *sz) } -int set_dim(struct panel_template *panel, int dimension, - const char *val) +static int set_dim(struct panel_template *panel, int dimension, + const char *val, int def) { if ( dimension >= MAX_DIMS ) { ERROR("Too many dimensions!\n"); @@ -400,10 +400,13 @@ int set_dim(struct panel_template *panel, int dimension, if ( strcmp(val, "fs") == 0 ) { panel->dims[dimension] = DIM_FS; + panel->dims_default[dimension] = def; } else if ( strcmp(val, "ss") == 0 ) { panel->dims[dimension] = DIM_SS; + panel->dims_default[dimension] = def; } else if ( strcmp(val, "%") == 0 ) { panel->dims[dimension] = DIM_PLACEHOLDER; + panel->dims_default[dimension] = def; } else { char *endptr; unsigned long int fix_val = strtoul(val, &endptr, 10); @@ -412,6 +415,7 @@ int set_dim(struct panel_template *panel, int dimension, return 1; } else { panel->dims[dimension] = fix_val; + panel->dims_default[dimension] = def; } } return 0; @@ -623,7 +627,7 @@ static int parse_field_for_panel(struct panel_template *panel, const char *key, ERROR("Invalid dimension number %s\n", key+3); } else { - if ( set_dim(panel, dim_entry, val) ) { + if ( set_dim(panel, dim_entry, val, def) ) { ERROR("Failed to set dim structure entry\n"); } } diff --git a/meson.build b/meson.build index 1d6a0130..4717bb2a 100644 --- a/meson.build +++ b/meson.build @@ -1,11 +1,11 @@ # Meson file for CrystFEL project('crystfel', 'c', - version: '0.10.2', + version: '0.11.0', license: 'GPL3+', meson_version: '>=0.55.0', default_options: ['buildtype=debugoptimized']) -libcrystfel_api_version = 16 +libcrystfel_api_version = 17 crystfel_rpath = '$ORIGIN/../lib64/:$ORIGIN/../lib:$ORIGIN/../../asapo-libraries/lib:$ORIGIN/../../asapo-libraries/lib64' add_project_arguments('-DHAVE_CONFIG_H', language: 'c') diff --git a/relnotes-0.10.2.md b/relnotes-0.10.2.md deleted file mode 100644 index 00bbad03..00000000 --- a/relnotes-0.10.2.md +++ /dev/null @@ -1,161 +0,0 @@ -Release notes for CrystFEL version 0.10.2 -========================================= - -Copyright © 2012-2023 Deutsches Elektronen-Synchrotron DESY, - a research centre of the Helmholtz Association. - -See AUTHORS as well as the individual source code files for full contributor details. - -CrystFEL 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. - -CrystFEL 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 -CrystFEL. If not, see <http://www.gnu.org/licenses/>. - - -Overview --------- - -This release is primarily a bug-fixing update to CrystFEL, and there have been -improvements around the entire suite. The most important changes are detailed -below. See the ChangeLog or the Git history for a comprehensive list of all -changes. - - -Graphical user interface (GUI) ------------------------------- - -This version adds a colour scale widget to the GUI, which can be used to -manually adjust the colours used to display the image. The colour scale is -found directly to the right of the image. Click and drag to move -the histogram of image values relative to the colour scale, and use the scroll -wheel to compress and expand the range. - -Resolution rings can now be added to the image. Enable them in the "View" menu. -There are also menu items for running `detector-shift` and `peakogram`, found -under the "Tools" menu. - -The figure of merit calculation tool has been improved, and now displays the -results as a graph. The graph values can be exported as a CSV file for further -processing. - -This release also adds specially-designed icons to the GUI, which fixes -problems with "broken" icons on some systems. - - -Performance ------------ - -Speed has been improved in many areas of CrystFEL. The profiling option -(`--profile`) of `indexamajig` has been re-implemented and can help you to find -bottlenecks in processing on your data. In addition, some new options were -added to `indexamajig`: - -New option `--peakfinder8-fast` tells peakfinder8 to calculate some values in -advance, approximately halving the time taken by the peak search. - -Another new option `--asdf-fast` slightly alters some thresholds within asdf, -resulting in a large speedup. Since this changes the behaviour from before, we -decided to make it optional. - -Finally, `--cell-parameters-only` completely circumvents the spot prediction and -integration calculations, which can make a very large speedup as long as you're -not interested in spot positions. Note that this isn't the same as the -existing option ``--integration=none``, where the spot positions are predicted -but the intensity integration is skipped. For very large unit cells, which are -often produced by unconstrained indexing (e.g. for online monitoring), the spot -prediction can take signficant time. - -For advice about making CrystFEL faster, see this page: -<https://gitlab.desy.de/thomas.white/crystfel/-/blob/master/doc/articles/speed.rst> - - -Documentation improvements --------------------------- - -Two long-form documentation articles have been added, on top of the other two -mentioned in other sections of this page. - -A completely new tutorial has been added, describing how to process data using -the graphical user interface: -<https://gitlab.desy.de/thomas.white/crystfel/-/blob/master/doc/articles/tutorial.rst> - -The following new article has been added, to help with the common question of -choosing the correct point group for merging data: -<https://gitlab.desy.de/thomas.white/crystfel/-/blob/master/doc/articles/pointgroup.rst> - - -Streaming interfaces --------------------- - -ZeroMQ and ASAP::O interfaces have been added, to allow data to be streamed -directly to CrystFEL without any intermediate file storage. For some -information on how to get started, read the following document: -<https://gitlab.desy.de/thomas.white/crystfel/-/blob/master/doc/articles/online.rst> - - -Refuses to overwrite stream ---------------------------- - -Starting from this version, `indexamajig` and other CrystFEL tools will refuse to -create a new stream if a file already exists with the same name. This is meant -to avoid the possibility of losing valuable results by (e.g.) re-running a -processing script. This becomes particularly important in a streaming data -situation, where the original data might no longer be available. If you really -want to overwrite the results, you'll need to move or delete the old file -yourself. - - -Installation ------------- - -CrystFEL has become easier to install because of several developments. First, -the Slurm API headers are no longer needed for the GUI to submit Slurm jobs. -In this version, it uses the Slurm commands directly -(`sbatch/scontrol/scancel`). - -For environments based totally on CBFs or other types of files, it's now -possible to compile CrystFEL without any reference to the HDF5 library, -avoiding a lot of possible complications. - -There is a new script (`scripts/install-indexers`) which helps with installing -Mosflm, DirAx and XDS. After downloading CrystFEL, run the script with -`--help` to get started. - -Finally, Docker images are now available. These can be used with various -container tools (not just Docker). For example, using Apptainer (the new name -for Singularity): -``` -$ apptainer pull docker://gitlab.desy.de:5555/thomas.white/crystfel/crystfel:latest -$ apptainer run -B /path/to/data crystfel_latest.sif -``` - -More details can be found on the installation page: -<https://www.desy.de/~twhite/crystfel/install.html> - - -API changes ------------ - -Added routines: -* `data_template_slabby_file_to_panel_coords` -* `data_template_get_2d_detgeom_if_possible` -* `data_template_get_clen_if_possible` -* `image_create_dp_bad_sat` -* `profile_{init,start,end,print_and_reset}` - -Removed routines: -* `image_set_zero_mask` - -Changed routine prototypes: -* `default_method_options` - addition of `asdf_opts` -* `peakfinder8` - addition of `fast_mode` and `private_data` - -Changed enumerations: -* `DataSourceType` - addition of `DATA_SOURCE_TYPE_SEEDEE` diff --git a/relnotes-0.11.0.md b/relnotes-0.11.0.md new file mode 100644 index 00000000..2691695b --- /dev/null +++ b/relnotes-0.11.0.md @@ -0,0 +1,172 @@ +Release notes for CrystFEL version 0.11.0 +========================================= + +Copyright © 2012-2024 Deutsches Elektronen-Synchrotron DESY, + a research centre of the Helmholtz Association. + +See AUTHORS as well as the individual source code files for full contributor details. + +CrystFEL 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. + +CrystFEL 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 +CrystFEL. If not, see <http://www.gnu.org/licenses/>. + + +Overview +-------- + +This CrystFEL release adds a totally new system for detector geometry +refinement, as well as better support for compiling on Mac OS. The old CMake +build system has been removed in favour of Meson. The simulation tools +`pattern_sim` and `partial_sim`, which were not well maintained nor widely used, +have been removed. + +These changes are detailed below. In addition, there were many smaller fixes +and improvements. See the ChangeLog or the Git history for a comprehensive +list of all changes. + + +New system for detector geometry refinement +------------------------------------------- + +The new detector geometry system is based on the Millepede-II program, the same +software used for high energy physics experiments including the CMS. It +allows us to do a full refinement including all of the inter-dependencies +between crystal orientations, cell parameters and the detector geometry. +Previously, the refined updates to the detector positions would be biased +because they were based on biased crystal parameters, which were in turn biased +because of the incorrect detector geometry. To break this circular dependency, +we have to refine the individual parameters for each crystal at the same time +as we refine the geometry. Normally, doing this would result in an enormous +and computationally prohibitive least squares calculation, even with +specialised sparse matrix solvers. However, the Millepede algorithm reduces +the calculation to one with a sized based only on the number of geometrical +parameters for the detector. + +To get started with the new geometry refinement, read the manual for the new +`align_detector` program by running `man align_detector` or visiting +<https://gitlab.desy.de/thomas.white/crystfel/-/blob/master/doc/man/align_detector.1.md>. +An update of the geometry file will be necessary to add information about the +hierarchy of detector panels, but example files are available. The refinement +can also be performed using the CrystFEL GUI. + +A side-effect of this change is that the beam center is no longer refined +after indexing for each pattern individually. This should make the prediction +refinement more stable. + +Future CrystFEL versions will look at improving the stability and precision of +this method, in particular for three-dimensional and fine-grained refinement +tasks. + + +Homebrew formula and improved Mac OS support +-------------------------------------------- + +This release adds a Homebrew formula for CrystFEL. If you're running on a Mac, +you can now install CrystFEL with a single `brew install` command. See +`INSTALL.md` for more details. Eventually we hope to submit this formula to +the main Homebrew repository to make it even easier to install. + +In addition, we are now regularly testing CrystFEL on Mac OS as part of our +continuous integration pipeline. + + +Removal of simulation tools and CMake build system +-------------------------------------------------- + +Due mostly to a insufficient development resources, the simulation tools +`pattern_sim` and `partial_sim` have been removed from the CrystFEL suite +starting from this version. For more detailed discussion of the rationale for +this, see https://gitlab.desy.de/thomas.white/crystfel/-/issues/81 + +If you need quantitative image simulations, there are several better options +including [nanoBragg]<https://bl831.als.lbl.gov/~jamesh/nanoBragg/>. For +relative-scale geometry-only simulations of the kind done by `partial_sim`, +a better option is expected in a future CrystFEL version - watch this space! + +The CMake-based build system, which was barely maintained and lacked many +features compared to the Meson-based system, has now been removed altogether. + + +API changes +----------- + +Removed routines: +* `data_template_get_rigid_groups` +* `r_gradient` +* `x_gradient` +* `y_gradient` +* `image_hdf5_write` + +Added routines: +* `crystfel_mille_new` +* `crystfel_mille_free` +* `crystfel_mille_delete_last_record` +* `crystfel_mille_write_record` +* `mille_label` +* `mille_unlabel` +* `write_mille` +* `data_template_show_hierarchy` +* `data_template_translate_group_px` +* `data_template_translate_group_m` +* `data_template_rotate_group` +* `data_template_write_to_fh` +* `data_template_write_to_file` +* `data_template_group_info` +* `detgeom_find_panel` +* `detgeom_show_hierarchy` +* `detgeom_translate_detector_m` +* `detgeom_group_center` +* `make_panel_minvs` +* `is_cbf_file` +* `is_cbfgz_file` +* `is_hdf5_file` +* `image_data_arrays_new` +* `image_data_arrays_free` +* `image_create_dp_bad` +* `image_set_zero_data` +* `index_pattern_4` +* `r_dev` +* `fs_dev` +* `ss_dev` +* `r_gradient` +* `fs_ss_gradient` +* `read_reflections_3` +* `stream_write_data_template` +* `show_vector` +* `matrix_mult2` +* `matrix_mult3` +* `matrix_invert` +* `sq` +* `rotate2d` +* `is_dir` + +Added type definitions: +* `Mille` +* `struct dg_group_info` +* `struct detgeom_panel_group` +* `ImageDataArrays` +* `struct peak_params` +* `struct reflpeak` + +Removed type definitions: +* `struct rigid_group` +* `struct rg_collection` + +Changed structure definitions: +* `detgeom_panel` - addition of `group` +* `detgeom` - addition of `top_group` +* `image` - addition of `ida` +* `enum gparam` - changed values, moved from geometry.h to predict-refine.h + +Changed routine prototypes: +* `image_read` - addition of `ida` +* `image_read_data_block` - addition of `ida` +* `refine_prediction` - addition of `mille` and `max_mille_level` diff --git a/scripts/turbo-index-lsf b/scripts/turbo-index-lsf index f7635de4..d82ccbf8 100644 --- a/scripts/turbo-index-lsf +++ b/scripts/turbo-index-lsf @@ -67,6 +67,8 @@ for FILE in split-events-${RUN}.lst*; do command="indexamajig -i $FILE -o $STREAMDIR/$STREAM --serial-start=$POS" command="$command -j \`nproc\` -g $GEOM" #command="$command --peaks=zaef" # Indexing parameters here + # Note: if using --mille, each indexamajig job needs its own directory: + # --mille-dir=mille-data-$NUMBER echo $command >> $SLURMFILE diff --git a/scripts/turbo-index-slurm b/scripts/turbo-index-slurm index 86da315f..d976851e 100755 --- a/scripts/turbo-index-slurm +++ b/scripts/turbo-index-slurm @@ -81,6 +81,8 @@ for FILE in split-events-${RUN}.lst*; do command="indexamajig -i $FILE -o $STREAMDIR/$STREAM --serial-start=$POS" command="$command -j \`nproc\` -g $GEOM" #command="$command --peaks=zaef" # Indexing parameters here + # Note: if using --mille, each indexamajig job needs its own directory: + # --mille-dir=mille-data-{$NUMBER} echo $command >> $SLURMFILE diff --git a/src/align_detector.c b/src/align_detector.c index bb2eb029..8e6d2fcb 100644 --- a/src/align_detector.c +++ b/src/align_detector.c @@ -420,6 +420,7 @@ int main(int argc, char *argv[]) if ( make_zero_sum(fh, groups, n_groups, "all", level, out_of_plane) ) return 1; fprintf(fh, "method inversion 5 0.1\n"); + fprintf(fh, "closeandreopen\n"); fprintf(fh, "end\n"); fclose(fh); diff --git a/src/gui_align.c b/src/gui_align.c index b712681b..b6c88379 100644 --- a/src/gui_align.c +++ b/src/gui_align.c @@ -59,15 +59,18 @@ static int run_align(const char *input_name, int level, int out_of_plane, GSubprocess *sp; struct gui_indexing_result *res; GError *error; - const char *cmdline[16]; + const char *cmdline[1024]; + char *freeme[1024]; + int nfree = 0; char level_str[64]; GFile *gstream; GFile *gworkdir; GFile *ggeom; - GFile *gmilledir; char *input_geom; int i; - char *mille_dir; + int ncmd = 0; + int mdstart; + GFileEnumerator *fenum; res = find_indexing_result_by_name(proj, input_name); if ( res == NULL ) { @@ -84,15 +87,6 @@ static int run_align(const char *input_name, int level, int out_of_plane, gworkdir = g_file_get_parent(gstream); g_object_unref(gstream); - /* Look for Millepede files */ - gmilledir = g_file_get_child(gworkdir, "mille-data"); - if ( !g_file_query_exists(gmilledir, NULL) ) { - ERROR("No detector alignment data found for indexing run '%s'\n", input_name); - return 1; - } - mille_dir = g_file_get_path(gmilledir); - g_object_unref(gmilledir); - /* Input geometry file */ ggeom = g_file_get_child(gworkdir, "detector.geom"); input_geom = g_file_get_path(ggeom); @@ -100,22 +94,54 @@ static int run_align(const char *input_name, int level, int out_of_plane, /* Build command line */ snprintf(level_str, 63, "%i", level); - cmdline[0] = "align_detector"; - cmdline[1] = "-g"; - cmdline[2] = input_geom; - cmdline[3] = "--level"; - cmdline[4] = level_str; - cmdline[5] = "-o"; - cmdline[6] = out_geom; + cmdline[ncmd++] = "align_detector"; + cmdline[ncmd++] = "-g"; + cmdline[ncmd++] = input_geom; + cmdline[ncmd++] = "--level"; + cmdline[ncmd++] = level_str; + cmdline[ncmd++] = "-o"; + cmdline[ncmd++] = out_geom; if ( out_of_plane ) { - cmdline[7] = "--out-of-plane"; - cmdline[8] = mille_dir; - cmdline[9] = NULL; - } else { - cmdline[7] = mille_dir; - cmdline[8] = NULL; + cmdline[ncmd++] = "--out-of-plane"; + } + mdstart = ncmd; + + /* Look for Millepede files */ + error = NULL; + fenum = g_file_enumerate_children(gworkdir, + G_FILE_ATTRIBUTE_STANDARD_NAME, + G_FILE_QUERY_INFO_NONE, + NULL, &error); + if ( fenum == NULL ) { + ERROR("Failed to search alignment data\n"); + return 1; } + while ( 1 ) { + GFileInfo *finfo; + const char *n; + if ( !g_file_enumerator_iterate(fenum, &finfo, NULL, NULL, &error) ) goto out; + if ( !finfo ) break; + if ( ncmd >= 1023 ) { + ERROR("Too many Millepede directories! Run align_detector manually.\n"); + return 1; + } + n = g_file_info_get_name(finfo); + if ( strncmp(n, "mille-data", 10) != 0 ) continue; + char *ffs = relative_to_cwd(gworkdir, n); + cmdline[ncmd++] = ffs; + freeme[nfree++] = ffs; + } +out: + g_object_unref(fenum); + + if ( ncmd == mdstart ) { + ERROR("No detector alignment data found for indexing run '%s'\n", input_name); + return 1; + } + + cmdline[ncmd++] = NULL; + STATUS("Running program: "); i = 0; while ( cmdline[i] != NULL ) { @@ -131,8 +157,10 @@ static int run_align(const char *input_name, int level, int out_of_plane, return 1; } + for ( i=0; i<nfree; i++ ) { + g_free(freeme[i]); + } g_object_unref(gworkdir); - g_free(mille_dir); g_free(input_geom); return 0; diff --git a/src/gui_backend_slurm.c b/src/gui_backend_slurm.c index f5ad31c5..1b384dca 100644 --- a/src/gui_backend_slurm.c +++ b/src/gui_backend_slurm.c @@ -843,7 +843,7 @@ static void *run_indexing(const char *job_title, stdout_rel_filename = relative_to_cwd(workdir, "stdout-%a.log"); stderr_rel_filename = relative_to_cwd(workdir, "stderr-%a.log"); harvest_rel_filename = relative_to_cwd(workdir, "parameters.json"); - mille_rel_filename = relative_to_cwd(workdir, "mille-data"); + mille_rel_filename = relative_to_cwd(workdir, "mille-data-${SLURM_ARRAY_TASK_ID}"); slurm_prologue = sbatch_bits(&opts->common, job_title, array_inx, stdout_rel_filename, stderr_rel_filename); diff --git a/src/im-asapo.c b/src/im-asapo.c index d891dc1d..07666d97 100644 --- a/src/im-asapo.c +++ b/src/im-asapo.c @@ -277,6 +277,8 @@ static void send_callback(void *a, AsapoRequestCallbackPayloadHandle payload, if ( asapo_is_error(err) ) { show_asapo_error("ASAP::O send error", err); } + + free(a); } @@ -299,7 +301,9 @@ static void send_real(struct im_asapo *a, struct image *image) struct timeval tv; gettimeofday(&tv,NULL); - STATUS("sent %s at %lli . %lli\n", filename, tv.tv_sec, tv.tv_usec); + STATUS("sent %s (%p, %lli bytes) at %lli . %lli\n", filename, + image->data_block, image->data_block_size, + tv.tv_sec, tv.tv_usec); err = asapo_new_handle(); asapo_producer_send(a->producer, header, image->data_block, @@ -312,6 +316,11 @@ static void send_real(struct im_asapo *a, struct image *image) return; } + /* Blank out the data block pointer, to avoid it being freed by + * image_free shortly after we return. Instead, it will be freed + * by send_callback. */ + image->data_block = NULL; + asapo_free_handle(&header); asapo_free_handle(&err); } @@ -322,6 +331,7 @@ static void send_placeholder(struct im_asapo *a, struct image *image) AsapoMessageHeaderHandle header; AsapoErrorHandle err; char filename[1024]; + char *dummy; snprintf(filename, 1024, "processed/%s_hits/%s-%i.placeholder", a->stream, a->stream, image->serial); @@ -338,9 +348,10 @@ static void send_placeholder(struct im_asapo *a, struct image *image) 0, 0); /* Auto ID */ + dummy = strdup("SKIPPED"); err = asapo_new_handle(); - asapo_producer_send(a->producer, header, "SKIPPED", - kDefaultIngestMode, a->stream, + asapo_producer_send(a->producer, header, dummy, + kTransferData | kStoreInDatabase, a->stream, send_callback, &err); if ( asapo_is_error(err) ) { show_asapo_error("Couldn't send ASAP::O message", err); diff --git a/tests/geom_roundtrip b/tests/geom_roundtrip index 6d205f06..1d74befd 100755 --- a/tests/geom_roundtrip +++ b/tests/geom_roundtrip @@ -25,6 +25,7 @@ q0a0/corner_x = 443.819000 q0a0/corner_y = -49.871900 q0a0/fs = 0.004806x +0.999989y +0.000000z q0a0/ss = -0.999989x +0.004806y +0.000000z +q0a0/dim3 = 0 q0a1/min_fs = 194 q0a1/max_fs = 387 @@ -34,6 +35,7 @@ q0a1/corner_x = 444.766000 q0a1/corner_y = 147.126000 q0a1/fs = 0.004806x +0.999989y +0.000000z q0a1/ss = -0.999989x +0.004806y +0.000000z +q0a1/dim3 = 0 q0a2/min_fs = 0 q0a2/max_fs = 193 @@ -43,6 +45,7 @@ q0a2/corner_x = 239.800000 q0a2/corner_y = -49.350400 q0a2/fs = 0.003265x +0.999995y +0.000000z q0a2/ss = -0.999995x +0.003265y +0.000000z +q0a2/dim3 = 0 q0a3/min_fs = 194 q0a3/max_fs = 387 @@ -52,6 +55,7 @@ q0a3/corner_x = 240.444000 q0a3/corner_y = 147.649000 q0a3/fs = 0.003265x +0.999995y +0.000000z q0a3/ss = -0.999995x +0.003265y +0.000000z +q0a3/dim3 = 0 q0a4/min_fs = 0 q0a4/max_fs = 193 @@ -61,6 +65,7 @@ q0a4/corner_x = 872.219000 q0a4/corner_y = 342.054000 q0a4/fs = -0.999997x +0.002424y +0.000000z q0a4/ss = -0.002424x -0.999997y +0.000000z +q0a4/dim3 = 0 q0a5/min_fs = 194 q0a5/max_fs = 387 @@ -70,6 +75,7 @@ q0a5/corner_x = 675.220000 q0a5/corner_y = 342.532000 q0a5/fs = -0.999997x +0.002424y +0.000000z q0a5/ss = -0.002424x -0.999997y +0.000000z +q0a5/dim3 = 0 q0a6/min_fs = 0 q0a6/max_fs = 193 @@ -79,6 +85,7 @@ q0a6/corner_x = 871.381000 q0a6/corner_y = 135.836000 q0a6/fs = -0.999997x +0.002685y +0.000000z q0a6/ss = -0.002685x -0.999997y +0.000000z +q0a6/dim3 = 0 q0a7/min_fs = 194 q0a7/max_fs = 387 @@ -88,6 +95,7 @@ q0a7/corner_x = 674.382000 q0a7/corner_y = 136.365000 q0a7/fs = -0.999997x +0.002685y +0.000000z q0a7/ss = -0.002685x -0.999997y +0.000000z +q0a7/dim3 = 0 q0a8/min_fs = 0 q0a8/max_fs = 193 @@ -97,6 +105,7 @@ q0a8/corner_x = 480.758000 q0a8/corner_y = 769.640000 q0a8/fs = -0.000078x -0.999999y +0.000000z q0a8/ss = 0.999999x -0.000078y +0.000000z +q0a8/dim3 = 0 q0a9/min_fs = 194 q0a9/max_fs = 387 @@ -106,6 +115,7 @@ q0a9/corner_x = 480.743000 q0a9/corner_y = 572.640000 q0a9/fs = -0.000078x -0.999999y +0.000000z q0a9/ss = 0.999999x -0.000078y +0.000000z +q0a9/dim3 = 0 q0a10/min_fs = 0 q0a10/max_fs = 193 @@ -115,6 +125,7 @@ q0a10/corner_x = 689.447000 q0a10/corner_y = 770.295000 q0a10/fs = 0.001551x -0.999999y +0.000000z q0a10/ss = 0.999999x +0.001551y +0.000000z +q0a10/dim3 = 0 q0a11/min_fs = 194 q0a11/max_fs = 387 @@ -124,6 +135,7 @@ q0a11/corner_x = 689.752000 q0a11/corner_y = 573.296000 q0a11/fs = 0.001551x -0.999999y +0.000000z q0a11/ss = 0.999999x +0.001551y +0.000000z +q0a11/dim3 = 0 q0a12/min_fs = 0 q0a12/max_fs = 193 @@ -133,6 +145,7 @@ q0a12/corner_x = 445.672000 q0a12/corner_y = 751.701000 q0a12/fs = -0.999998x -0.002161y +0.000000z q0a12/ss = 0.002161x -0.999998y +0.000000z +q0a12/dim3 = 0 q0a13/min_fs = 194 q0a13/max_fs = 387 @@ -142,6 +155,7 @@ q0a13/corner_x = 248.672000 q0a13/corner_y = 751.276000 q0a13/fs = -0.999998x -0.002161y +0.000000z q0a13/ss = 0.002161x -0.999998y +0.000000z +q0a13/dim3 = 0 q0a14/min_fs = 0 q0a14/max_fs = 193 @@ -151,6 +165,7 @@ q0a14/corner_x = 445.151000 q0a14/corner_y = 541.081000 q0a14/fs = -0.999999x -0.000074y +0.000000z q0a14/ss = 0.000074x -0.999999y +0.000000z +q0a14/dim3 = 0 q0a15/min_fs = 194 q0a15/max_fs = 387 @@ -160,6 +175,7 @@ q0a15/corner_x = 248.151000 q0a15/corner_y = 541.066000 q0a15/fs = -0.999999x -0.000074y +0.000000z q0a15/ss = 0.000074x -0.999999y +0.000000z +q0a15/dim3 = 0 q1a0/min_fs = 388 q1a0/max_fs = 581 @@ -169,6 +185,7 @@ q1a0/corner_x = 28.477600 q1a0/corner_y = 436.830000 q1a0/fs = -0.999990x -0.004167y +0.000000z q1a0/ss = 0.004167x -0.999990y +0.000000z +q1a0/dim3 = 1 q1a1/min_fs = 582 q1a1/max_fs = 775 @@ -178,6 +195,7 @@ q1a1/corner_x = -168.520000 q1a1/corner_y = 436.009000 q1a1/fs = -0.999990x -0.004167y +0.000000z q1a1/ss = 0.004167x -0.999990y +0.000000z +q1a1/dim3 = 1 q1a2/min_fs = 388 q1a2/max_fs = 581 @@ -187,6 +205,7 @@ q1a2/corner_x = 29.355900 q1a2/corner_y = 226.978000 q1a2/fs = -1.000001x +0.000385y +0.000000z q1a2/ss = -0.000385x -1.000001y +0.000000z +q1a2/dim3 = 1 q1a3/min_fs = 582 q1a3/max_fs = 775 @@ -196,6 +215,7 @@ q1a3/corner_x = -167.644000 q1a3/corner_y = 227.054000 q1a3/fs = -1.000001x +0.000385y +0.000000z q1a3/ss = -0.000385x -1.000001y +0.000000z +q1a3/dim3 = 1 q1a4/min_fs = 388 q1a4/max_fs = 581 @@ -205,6 +225,7 @@ q1a4/corner_x = -364.144000 q1a4/corner_y = 859.163000 q1a4/fs = 0.000539x -1.000000y +0.000000z q1a4/ss = 1.000000x +0.000539y +0.000000z +q1a4/dim3 = 1 q1a5/min_fs = 582 q1a5/max_fs = 775 @@ -214,6 +235,7 @@ q1a5/corner_x = -364.038000 q1a5/corner_y = 662.163000 q1a5/fs = 0.000539x -1.000000y +0.000000z q1a5/ss = 1.000000x +0.000539y +0.000000z +q1a5/dim3 = 1 q1a6/min_fs = 388 q1a6/max_fs = 581 @@ -223,6 +245,7 @@ q1a6/corner_x = -156.511000 q1a6/corner_y = 857.902000 q1a6/fs = -0.000337x -1.000000y +0.000000z q1a6/ss = 1.000000x -0.000337y +0.000000z +q1a6/dim3 = 1 q1a7/min_fs = 582 q1a7/max_fs = 775 @@ -232,6 +255,7 @@ q1a7/corner_x = -156.577000 q1a7/corner_y = 660.902000 q1a7/fs = -0.000337x -1.000000y +0.000000z q1a7/ss = 1.000000x -0.000337y +0.000000z +q1a7/dim3 = 1 q1a8/min_fs = 388 q1a8/max_fs = 581 @@ -241,6 +265,7 @@ q1a8/corner_x = -786.718000 q1a8/corner_y = 463.506000 q1a8/fs = 0.999996x +0.002303y +0.000000z q1a8/ss = -0.002303x +0.999996y +0.000000z +q1a8/dim3 = 1 q1a9/min_fs = 582 q1a9/max_fs = 775 @@ -250,6 +275,7 @@ q1a9/corner_x = -589.719000 q1a9/corner_y = 463.959000 q1a9/fs = 0.999996x +0.002303y +0.000000z q1a9/ss = -0.002303x +0.999996y +0.000000z +q1a9/dim3 = 1 q1a10/min_fs = 388 q1a10/max_fs = 581 @@ -259,6 +285,7 @@ q1a10/corner_x = -787.022000 q1a10/corner_y = 668.135000 q1a10/fs = 0.999997x +0.001741y +0.000000z q1a10/ss = -0.001741x +0.999997y +0.000000z +q1a10/dim3 = 1 q1a11/min_fs = 582 q1a11/max_fs = 775 @@ -268,6 +295,7 @@ q1a11/corner_x = -590.022000 q1a11/corner_y = 668.478000 q1a11/fs = 0.999997x +0.001741y +0.000000z q1a11/ss = -0.001741x +0.999997y +0.000000z +q1a11/dim3 = 1 q1a12/min_fs = 388 q1a12/max_fs = 581 @@ -277,6 +305,7 @@ q1a12/corner_x = -761.085000 q1a12/corner_y = 428.541000 q1a12/fs = -0.000201x -0.999999y +0.000000z q1a12/ss = 0.999999x -0.000201y +0.000000z +q1a12/dim3 = 1 q1a13/min_fs = 582 q1a13/max_fs = 775 @@ -286,6 +315,7 @@ q1a13/corner_x = -761.125000 q1a13/corner_y = 231.541000 q1a13/fs = -0.000201x -0.999999y +0.000000z q1a13/ss = 0.999999x -0.000201y +0.000000z +q1a13/dim3 = 1 q1a14/min_fs = 388 q1a14/max_fs = 581 @@ -295,6 +325,7 @@ q1a14/corner_x = -559.624000 q1a14/corner_y = 428.347000 q1a14/fs = 0.003097x -0.999995y +0.000000z q1a14/ss = 0.999995x +0.003097y +0.000000z +q1a14/dim3 = 1 q1a15/min_fs = 582 q1a15/max_fs = 775 @@ -304,6 +335,7 @@ q1a15/corner_x = -559.014000 q1a15/corner_y = 231.348000 q1a15/fs = 0.003097x -0.999995y +0.000000z q1a15/ss = 0.999995x +0.003097y +0.000000z +q1a15/dim3 = 1 q2a0/min_fs = 776 q2a0/max_fs = 969 @@ -313,6 +345,7 @@ q2a0/corner_x = -442.346000 q2a0/corner_y = 20.338200 q2a0/fs = -0.004086x -0.999991y +0.000000z q2a0/ss = 0.999991x -0.004086y +0.000000z +q2a0/dim3 = 2 q2a1/min_fs = 970 q2a1/max_fs = 1163 @@ -322,6 +355,7 @@ q2a1/corner_x = -443.151000 q2a1/corner_y = -176.660000 q2a1/fs = -0.004086x -0.999991y +0.000000z q2a1/ss = 0.999991x -0.004086y +0.000000z +q2a1/dim3 = 2 q2a2/min_fs = 776 q2a2/max_fs = 969 @@ -331,6 +365,7 @@ q2a2/corner_x = -235.519000 q2a2/corner_y = 19.231200 q2a2/fs = 0.000302x -1.000000y +0.000000z q2a2/ss = 1.000000x +0.000302y +0.000000z +q2a2/dim3 = 2 q2a3/min_fs = 970 q2a3/max_fs = 1163 @@ -340,6 +375,7 @@ q2a3/corner_x = -235.459000 q2a3/corner_y = -177.769000 q2a3/fs = 0.000302x -1.000000y +0.000000z q2a3/ss = 1.000000x +0.000302y +0.000000z +q2a3/dim3 = 2 q2a4/min_fs = 776 q2a4/max_fs = 969 @@ -349,6 +385,7 @@ q2a4/corner_x = -863.817000 q2a4/corner_y = -370.344000 q2a4/fs = 0.999997x -0.002037y +0.000000z q2a4/ss = 0.002037x +0.999997y +0.000000z +q2a4/dim3 = 2 q2a5/min_fs = 970 q2a5/max_fs = 1163 @@ -358,6 +395,7 @@ q2a5/corner_x = -666.817000 q2a5/corner_y = -370.746000 q2a5/fs = 0.999997x -0.002037y +0.000000z q2a5/ss = 0.002037x +0.999997y +0.000000z +q2a5/dim3 = 2 q2a6/min_fs = 776 q2a6/max_fs = 969 @@ -367,6 +405,7 @@ q2a6/corner_x = -863.549000 q2a6/corner_y = -165.126000 q2a6/fs = 1.000000x -0.001155y +0.000000z q2a6/ss = 0.001155x +1.000000y +0.000000z +q2a6/dim3 = 2 q2a7/min_fs = 970 q2a7/max_fs = 1163 @@ -376,6 +415,7 @@ q2a7/corner_x = -666.549000 q2a7/corner_y = -165.353000 q2a7/fs = 1.000000x -0.001155y +0.000000z q2a7/ss = 0.001155x +1.000000y +0.000000z +q2a7/dim3 = 2 q2a8/min_fs = 776 q2a8/max_fs = 969 @@ -385,6 +425,7 @@ q2a8/corner_x = -473.620000 q2a8/corner_y = -793.473000 q2a8/fs = 0.002076x +0.999998y +0.000000z q2a8/ss = -0.999998x +0.002076y +0.000000z +q2a8/dim3 = 2 q2a9/min_fs = 970 q2a9/max_fs = 1163 @@ -394,6 +435,7 @@ q2a9/corner_x = -473.211000 q2a9/corner_y = -596.474000 q2a9/fs = 0.002076x +0.999998y +0.000000z q2a9/ss = -0.999998x +0.002076y +0.000000z +q2a9/dim3 = 2 q2a10/min_fs = 776 q2a10/max_fs = 969 @@ -403,6 +445,7 @@ q2a10/corner_x = -676.809000 q2a10/corner_y = -792.653000 q2a10/fs = 0.004134x +0.999991y +0.000000z q2a10/ss = -0.999991x +0.004134y +0.000000z +q2a10/dim3 = 2 q2a11/min_fs = 970 q2a11/max_fs = 1163 @@ -412,6 +455,7 @@ q2a11/corner_x = -675.995000 q2a11/corner_y = -595.655000 q2a11/fs = 0.004134x +0.999991y +0.000000z q2a11/ss = -0.999991x +0.004134y +0.000000z +q2a11/dim3 = 2 q2a12/min_fs = 776 q2a12/max_fs = 969 @@ -421,6 +465,7 @@ q2a12/corner_x = -442.034000 q2a12/corner_y = -769.447000 q2a12/fs = 0.999981x -0.006417y +0.000000z q2a12/ss = 0.006417x +0.999981y +0.000000z +q2a12/dim3 = 2 q2a13/min_fs = 970 q2a13/max_fs = 1163 @@ -430,6 +475,7 @@ q2a13/corner_x = -245.038000 q2a13/corner_y = -770.711000 q2a13/fs = 0.999981x -0.006417y +0.000000z q2a13/ss = 0.006417x +0.999981y +0.000000z +q2a13/dim3 = 2 q2a14/min_fs = 776 q2a14/max_fs = 969 @@ -439,6 +485,7 @@ q2a14/corner_x = -441.283000 q2a14/corner_y = -566.627000 q2a14/fs = 0.999996x -0.002727y +0.000000z q2a14/ss = 0.002727x +0.999996y +0.000000z +q2a14/dim3 = 2 q2a15/min_fs = 970 q2a15/max_fs = 1163 @@ -448,6 +495,7 @@ q2a15/corner_x = -244.283000 q2a15/corner_y = -567.164000 q2a15/fs = 0.999996x -0.002727y +0.000000z q2a15/ss = 0.002727x +0.999996y +0.000000z +q2a15/dim3 = 2 q3a0/min_fs = 1164 q3a0/max_fs = 1357 @@ -457,6 +505,7 @@ q3a0/corner_x = -33.350700 q3a0/corner_y = -458.693000 q3a0/fs = 0.999988x -0.004965y +0.000000z q3a0/ss = 0.004965x +0.999988y +0.000000z +q3a0/dim3 = 3 q3a1/min_fs = 1358 q3a1/max_fs = 1551 @@ -466,6 +515,7 @@ q3a1/corner_x = 163.647000 q3a1/corner_y = -459.671000 q3a1/fs = 0.999988x -0.004965y +0.000000z q3a1/ss = 0.004965x +0.999988y +0.000000z +q3a1/dim3 = 3 q3a2/min_fs = 1164 q3a2/max_fs = 1357 @@ -475,6 +525,7 @@ q3a2/corner_x = -31.831600 q3a2/corner_y = -254.931000 q3a2/fs = 0.999998x -0.002316y +0.000000z q3a2/ss = 0.002316x +0.999998y +0.000000z +q3a2/dim3 = 3 q3a3/min_fs = 1358 q3a3/max_fs = 1551 @@ -484,6 +535,7 @@ q3a3/corner_x = 165.168000 q3a3/corner_y = -255.388000 q3a3/fs = 0.999998x -0.002316y +0.000000z q3a3/ss = 0.002316x +0.999998y +0.000000z +q3a3/dim3 = 3 q3a4/min_fs = 1164 q3a4/max_fs = 1357 @@ -493,6 +545,7 @@ q3a4/corner_x = 359.553000 q3a4/corner_y = -886.512000 q3a4/fs = 0.002474x +0.999997y +0.000000z q3a4/ss = -0.999997x +0.002474y +0.000000z +q3a4/dim3 = 3 q3a5/min_fs = 1358 q3a5/max_fs = 1551 @@ -502,6 +555,7 @@ q3a5/corner_x = 360.040000 q3a5/corner_y = -689.512000 q3a5/fs = 0.002474x +0.999997y +0.000000z q3a5/ss = -0.999997x +0.002474y +0.000000z +q3a5/dim3 = 3 q3a6/min_fs = 1164 q3a6/max_fs = 1357 @@ -511,6 +565,7 @@ q3a6/corner_x = 154.142000 q3a6/corner_y = -884.763000 q3a6/fs = 0.000059x +1.000000y +0.000000z q3a6/ss = -1.000000x +0.000059y +0.000000z +q3a6/dim3 = 3 q3a7/min_fs = 1358 q3a7/max_fs = 1551 @@ -520,6 +575,7 @@ q3a7/corner_x = 154.154000 q3a7/corner_y = -687.763000 q3a7/fs = 0.000059x +1.000000y +0.000000z q3a7/ss = -1.000000x +0.000059y +0.000000z +q3a7/dim3 = 3 q3a8/min_fs = 1164 q3a8/max_fs = 1357 @@ -529,6 +585,7 @@ q3a8/corner_x = 784.877000 q3a8/corner_y = -492.935000 q3a8/fs = -0.999993x +0.004040y +0.000000z q3a8/ss = -0.004040x -0.999993y +0.000000z +q3a8/dim3 = 3 q3a9/min_fs = 1358 q3a9/max_fs = 1551 @@ -538,6 +595,7 @@ q3a9/corner_x = 587.878000 q3a9/corner_y = -492.139000 q3a9/fs = -0.999993x +0.004040y +0.000000z q3a9/ss = -0.004040x -0.999993y +0.000000z +q3a9/dim3 = 3 q3a10/min_fs = 1164 q3a10/max_fs = 1357 @@ -547,6 +605,7 @@ q3a10/corner_x = 784.254000 q3a10/corner_y = -699.590000 q3a10/fs = -0.999971x +0.007529y +0.000000z q3a10/ss = -0.007529x -0.999971y +0.000000z +q3a10/dim3 = 3 q3a11/min_fs = 1358 q3a11/max_fs = 1551 @@ -556,6 +615,7 @@ q3a11/corner_x = 587.260000 q3a11/corner_y = -698.107000 q3a11/fs = -0.999971x +0.007529y +0.000000z q3a11/ss = -0.007529x -0.999971y +0.000000z +q3a11/dim3 = 3 q3a12/min_fs = 1164 q3a12/max_fs = 1357 @@ -565,6 +625,7 @@ q3a12/corner_x = 769.176000 q3a12/corner_y = -460.510000 q3a12/fs = 0.004516x +0.999990y +0.000000z q3a12/ss = -0.999990x +0.004516y +0.000000z +q3a12/dim3 = 3 q3a13/min_fs = 1358 q3a13/max_fs = 1551 @@ -574,6 +635,7 @@ q3a13/corner_x = 770.066000 q3a13/corner_y = -263.512000 q3a13/fs = 0.004516x +0.999990y +0.000000z q3a13/ss = -0.999990x +0.004516y +0.000000z +q3a13/dim3 = 3 q3a14/min_fs = 1164 q3a14/max_fs = 1357 @@ -583,6 +645,7 @@ q3a14/corner_x = 554.764000 q3a14/corner_y = -460.250000 q3a14/fs = 0.004918x +0.999989y +0.000000z q3a14/ss = -0.999989x +0.004918y +0.000000z +q3a14/dim3 = 3 q3a15/min_fs = 1358 q3a15/max_fs = 1551 @@ -592,6 +655,7 @@ q3a15/corner_x = 555.732000 q3a15/corner_y = -263.253000 q3a15/fs = 0.004918x +0.999989y +0.000000z q3a15/ss = -0.999989x +0.004918y +0.000000z +q3a15/dim3 = 3 group_a0 = q0a0,q0a1 group_a1 = q0a2,q0a3 |