about summary refs log tree commit diff
path: root/nixpkgs/pkgs/applications/science/physics/crystfel
diff options
context:
space:
mode:
Diffstat (limited to 'nixpkgs/pkgs/applications/science/physics/crystfel')
-rw-r--r--nixpkgs/pkgs/applications/science/physics/crystfel/default.nix242
-rw-r--r--nixpkgs/pkgs/applications/science/physics/crystfel/disable-fmemopen-on-aarch64-darwin.patch13
-rw-r--r--nixpkgs/pkgs/applications/science/physics/crystfel/libccp4-use-hardcoded-syminfo-lib.patch40
-rw-r--r--nixpkgs/pkgs/applications/science/physics/crystfel/link-to-argp-standalone-if-needed.patch26
4 files changed, 321 insertions, 0 deletions
diff --git a/nixpkgs/pkgs/applications/science/physics/crystfel/default.nix b/nixpkgs/pkgs/applications/science/physics/crystfel/default.nix
new file mode 100644
index 000000000000..92b48ec86309
--- /dev/null
+++ b/nixpkgs/pkgs/applications/science/physics/crystfel/default.nix
@@ -0,0 +1,242 @@
+{ lib
+, stdenv
+, fetchurl
+, fetchFromGitHub
+, fetchpatch
+, fetchzip
+, cmake
+, lz4
+, bzip2
+, m4
+, hdf5
+, gsl
+, unzip
+, makeWrapper
+, meson
+, git
+, ninja
+, eigen
+, pkg-config
+, wrapGAppsHook
+, flex
+, bison
+, doxygen
+, opencl-headers
+, ncurses
+, msgpack
+, fftw
+, zeromq
+, ocl-icd
+, gtk3
+, gdk-pixbuf
+, argp-standalone
+, memorymappingHook
+, withGui ? true
+, withBitshuffle ? true
+}:
+
+let
+  libccp4 = stdenv.mkDerivation rec {
+    pname = "libccp4";
+    version = "8.0.0";
+    src = fetchurl {
+      url = "https://ftp.ccp4.ac.uk/opensource/${pname}-${version}.tar.gz";
+      hash = "sha256-y4E66GYSoIZjKd6rfO6W6sVz2BvlskA0HUD5rVMi/y0=";
+    };
+    nativeBuildInputs = [ meson ninja ];
+    buildInputs = [ hdf5 gsl ];
+
+    configureFlags = [ "FFLAGS=-fallow-argument-mismatch" ];
+
+    # libccp4 tries to read syminfo.lib by looking at an environment variable, which hinders reproducibility.
+    # We hard-code this by providing a little patch and then passing the absolute path to syminfo.lib as a
+    # preprocessor flag.
+    env.NIX_CFLAGS_COMPILE = "-DNIX_PROVIDED_SYMOP_FILE=\"${placeholder "out"}/share/ccp4/syminfo.lib\"";
+
+    patches = [
+      ./libccp4-use-hardcoded-syminfo-lib.patch
+    ];
+
+    postPatch =
+      let
+        mesonPatch = fetchzip {
+          url = "https://wrapdb.mesonbuild.com/v2/libccp4c_8.0.0-1/get_patch#somefile.zip";
+          hash = "sha256-ohskfKh+972Pl56KtwAeWwHtAaAFNpCzz5vZBAI/vdU=";
+        };
+      in
+      ''
+        cp ${mesonPatch}/meson.build .
+      '';
+  };
+  # This is the statically-linked, pre-built binary of mosflm. Compiling it ourselves turns out to be very difficult
+  # since the build process is very hard-coded for a specific machine, architecture, and libraries.
+  mosflm =
+    let
+      version = "7.4.0";
+      src =
+        if stdenv.isDarwin then
+          fetchurl
+            {
+              url = "https://www.mrc-lmb.cam.ac.uk/mosflm/mosflm/ver${builtins.replaceStrings [ "." ] [ "" ] version}/pre-built/mosflm-osx-64-noX11.zip";
+              sha256 = "1da5wimv3kl8bccp49j69vh8gi28cn7axg59lrmb38s68c618h7j";
+            }
+        else
+          fetchurl {
+            url = "https://www.mrc-lmb.cam.ac.uk/mosflm/mosflm/ver${builtins.replaceStrings [ "." ] [ "" ] version}/pre-built/mosflm-linux-64-noX11.zip";
+            hash = "sha256:1f2qins5kaz5v6mkaclncqpirx3mlz177ywm13py9p6s9mk99g32";
+          };
+      mosflmBinary = if stdenv.isDarwin then "bin/mosflm" else "mosflm-linux-64-noX11";
+    in
+    stdenv.mkDerivation rec {
+      pname = "mosflm";
+
+      inherit version src;
+
+      dontBuild = true;
+
+      nativeBuildInputs = [ unzip makeWrapper ];
+
+      sourceRoot = ".";
+
+      # mosflm statically links against its own libccp4, which as the syminfo.lib environment variable problem.
+      # Here, we circumvent it by creating a little wrapper script that calls mosflm after setting the SYMINFO variable.
+      installPhase = ''
+        mkdir -p $out/bin
+        cp ${mosflmBinary} $out/bin/mosflm-raw
+        makeWrapper $out/bin/mosflm-raw $out/bin/mosflm --set SYMINFO ${libccp4}/share/syminfo.lib --add-flags -n
+      '';
+    };
+
+  xgandalf = stdenv.mkDerivation rec {
+    pname = "xgandalf";
+    version = "c6c5003ff1086e8c0fb5313660b4f02f3a3aab7b";
+    src = fetchurl {
+      url = "https://gitlab.desy.de/thomas.white/${pname}/-/archive/${version}/${pname}-${version}.tar.gz";
+      hash = "sha256-/uZlBwAINSoYqgLQFTMz8rS1Rpadu79JkO6Bu/+Nx9E=";
+    };
+
+    nativeBuildInputs = [ meson pkg-config ninja ];
+    buildInputs = [ eigen ];
+  };
+
+  pinkIndexer = stdenv.mkDerivation rec {
+    pname = "pinkindexer";
+    version = "5d4e016941eb2a9e50a10df96ded7ff1e2464503";
+    src = fetchurl {
+      url = "https://gitlab.desy.de/thomas.white/${pname}/-/archive/${version}/${pname}-${version}.tar.gz";
+      hash = "sha256-VnJOJJ247dNoBlos4Fu3GQBlAnTk9el+yZDRiicJtu0=";
+    };
+
+    nativeBuildInputs = [ meson pkg-config ninja ];
+    buildInputs = [ eigen ];
+  };
+
+  fdip = stdenv.mkDerivation rec {
+    pname = "fdip";
+    version = "5628fedddd79323b4b26df9b85e9543d83286d4c";
+    src = fetchurl {
+      url = "https://gitlab.desy.de/thomas.white/fdip/-/archive/${version}/fdip-${version}.tar.gz";
+      hash = "sha256-EaihnW7p//ecgMn+KKlfmBeXrnAqs+HdhN+ovuSrtiQ=";
+    };
+
+    nativeBuildInputs = [ meson ninja pkg-config ];
+    buildInputs = [ eigen ];
+  };
+
+  hdf5-external-filter-plugins = stdenv.mkDerivation rec {
+    pname = "HDF5-External-Filter-Plugins";
+    version = "0.1.0";
+    src = fetchFromGitHub {
+      owner = "nexusformat";
+      repo = pname;
+      rev = "49e3b65eca772bca77af13ba047d8b577673afba";
+      hash = "sha256-bEzfWdZuHmb0PDzCqy8Dey4tLtq+4coO0sT0GzqrTYI=";
+    };
+
+    patches = [
+      (fetchpatch {
+        url = "https://github.com/spanezz/HDF5-External-Filter-Plugins/commit/6b337fe36da97a3ef72354393687ce3386c0709d.patch";
+        hash = "sha256-wnBEdL/MjEyRHPwaVtuhzY+DW1AFeaUQUmIXh+JaRHo=";
+      })
+    ];
+
+    nativeBuildInputs = [ cmake ];
+    buildInputs = [ hdf5 lz4 bzip2 ];
+
+    cmakeFlags = [
+      "-DENABLE_BITSHUFFLE_PLUGIN=yes"
+      "-DENABLE_LZ4_PLUGIN=yes"
+      "-DENABLE_BZIP2_PLUGIN=yes"
+    ];
+  };
+in
+stdenv.mkDerivation rec {
+  pname = "crystfel";
+  version = "0.10.2";
+  src = fetchurl {
+    url = "https://www.desy.de/~twhite/${pname}/${pname}-${version}.tar.gz";
+    sha256 = "sha256-nCO9ndDKS54bVN9IhFBiCVNzqk7BsCljXFrOmlx+sP4=";
+  };
+  nativeBuildInputs = [ meson pkg-config ninja flex bison doxygen opencl-headers makeWrapper ]
+    ++ lib.optionals withGui [ wrapGAppsHook ];
+  buildInputs = [
+    hdf5
+    gsl
+    ncurses
+    msgpack
+    fftw
+    fdip
+    zeromq
+    ocl-icd
+    libccp4
+    mosflm
+    pinkIndexer
+    xgandalf
+  ] ++ lib.optionals withGui [ gtk3 gdk-pixbuf ]
+  ++ lib.optionals stdenv.isDarwin [
+    argp-standalone
+  ] ++ lib.optionals (stdenv.isDarwin && !stdenv.isAarch64) [
+    memorymappingHook
+  ]
+  ++ lib.optionals withBitshuffle [ hdf5-external-filter-plugins ];
+
+  patches = [
+    ./link-to-argp-standalone-if-needed.patch
+    ./disable-fmemopen-on-aarch64-darwin.patch
+    (fetchpatch {
+      url = "https://gitlab.desy.de/thomas.white/crystfel/-/commit/3c54d59e1c13aaae716845fed2585770c3ca9d14.diff";
+      hash = "sha256-oaJNBQQn0c+z4p1pnW4osRJA2KdKiz4hWu7uzoKY7wc=";
+    })
+  ];
+
+  # CrystFEL calls mosflm by searching PATH for it. We could've create a wrapper script that sets the PATH, but
+  # we'd have to do that for every CrystFEL executable (indexamajig, crystfel, partialator). Better to just
+  # hard-code mosflm's path once.
+  postPatch = ''
+    sed -i -e 's#execlp("mosflm"#execl("${mosflm}/bin/mosflm"#' libcrystfel/src/indexers/mosflm.c;
+  '';
+
+  postInstall = lib.optionalString withBitshuffle ''
+    for file in $out/bin/*; do
+      wrapProgram $file --set HDF5_PLUGIN_PATH ${hdf5-external-filter-plugins}/lib/plugins
+    done
+  '';
+
+  meta = with lib; {
+    description = "Data processing for serial crystallography";
+    longDescription = ''
+      CrystFEL is a suite of programs for processing (and simulating) Bragg diffraction data from "serial crystallography" experiments, often (but not always) performed using an X-ray Free-Electron Laser. Compared to rotation data, some of the particular characteristics of such data which call for a specialised software suite are:
+
+      - The sliced, rather than integrated, measurement of intensity data. Many, if not all reflections are partially integrated.
+      - Many patterns (thousands) are required - high throughput is needed.
+      - The crystal orientations in each pattern are random and uncorrelated.
+      - Merging into lower symmetry point groups may require the resolution of indexing ambiguities.'';
+    homepage = "https://www.desy.de/~twhite/crystfel/";
+    changelog = "https://www.desy.de/~twhite/crystfel/changes.html";
+    downloadPage = "https://www.desy.de/~twhite/crystfel/download.html";
+    license = licenses.gpl3Plus;
+    maintainers = with maintainers; [ pmiddend ];
+    platforms = platforms.unix;
+  };
+
+}
diff --git a/nixpkgs/pkgs/applications/science/physics/crystfel/disable-fmemopen-on-aarch64-darwin.patch b/nixpkgs/pkgs/applications/science/physics/crystfel/disable-fmemopen-on-aarch64-darwin.patch
new file mode 100644
index 000000000000..c35350d0008f
--- /dev/null
+++ b/nixpkgs/pkgs/applications/science/physics/crystfel/disable-fmemopen-on-aarch64-darwin.patch
@@ -0,0 +1,13 @@
+diff --git a/libcrystfel/src/image-cbf.c b/libcrystfel/src/image-cbf.c
+index b8f09a1f..f8a15c1b 100644
+--- a/libcrystfel/src/image-cbf.c
++++ b/libcrystfel/src/image-cbf.c
+@@ -287,7 +287,7 @@ static float *read_cbf_data(const char *filename, int gz, int *w, int *h)
+ 
+ 	} else {
+ 
+-		#ifdef HAVE_ZLIB
++		#if defined(HAVE_ZLIB) && !(defined(__aarch64__) && defined(__APPLE__))
+ 		gzFile gzfh;
+ 		int len_read;
+ 		size_t len;
diff --git a/nixpkgs/pkgs/applications/science/physics/crystfel/libccp4-use-hardcoded-syminfo-lib.patch b/nixpkgs/pkgs/applications/science/physics/crystfel/libccp4-use-hardcoded-syminfo-lib.patch
new file mode 100644
index 000000000000..1806d9b2b9da
--- /dev/null
+++ b/nixpkgs/pkgs/applications/science/physics/crystfel/libccp4-use-hardcoded-syminfo-lib.patch
@@ -0,0 +1,40 @@
+diff --git a/ccp4/csymlib.c b/ccp4/csymlib.c
+index 76bc70b..3616121 100644
+--- a/ccp4/csymlib.c
++++ b/ccp4/csymlib.c
+@@ -136,25 +136,7 @@ CCP4SPG *ccp4spg_load_spacegroup(const int numspg, const int ccp4numspg,
+     }
+   }
+ 
+-  /* Open the symop file: */
+-  if (!(symopfile = getenv("SYMINFO"))) {
+-    if (debug)
+-      printf("Environment variable SYMINFO not set ... guessing location of symmetry file. \n");
+-    if (!(ccp4dir = getenv("CLIBD"))) {
+-      printf("Environment variable CLIBD not set ... big trouble! \n");
+-      return NULL;
+-    }
+-
+-    symopfile = ccp4_utils_malloc((strlen(ccp4dir)+22)*sizeof(char));
+-    strcpy(symopfile,ccp4_utils_joinfilenames(ccp4dir,"syminfo.lib"));
+-    symopfile[strlen(ccp4dir)+21] = '\0';
+-    ccp4printf(1," SYMINFO file set to %s \n",symopfile);
+-  } else {
+-    if (debug) {
+-      ccp4printf(1,"\n Spacegroup information obtained from library file: \n");
+-      ccp4printf(1," Logical Name: SYMINFO   Filename: %s\n\n",symopfile);
+-    }
+-  }
++  symopfile = NIX_PROVIDED_SYMOP_FILE;
+ 
+   filein = fopen(symopfile,"r");
+   if (!filein) {
+@@ -162,8 +144,6 @@ CCP4SPG *ccp4spg_load_spacegroup(const int numspg, const int ccp4numspg,
+     return NULL;
+   }
+ 
+-  if (!(getenv("SYMINFO"))) free(symopfile);
+-
+   parser = ccp4_parse_start(20);
+   if (parser == NULL) 
+     ccp4_signal(CSYM_ERRNO(CSYMERR_ParserFail),"ccp4spg_load_spacegroup",NULL);
diff --git a/nixpkgs/pkgs/applications/science/physics/crystfel/link-to-argp-standalone-if-needed.patch b/nixpkgs/pkgs/applications/science/physics/crystfel/link-to-argp-standalone-if-needed.patch
new file mode 100644
index 000000000000..8314be29ac00
--- /dev/null
+++ b/nixpkgs/pkgs/applications/science/physics/crystfel/link-to-argp-standalone-if-needed.patch
@@ -0,0 +1,26 @@
+diff --git a/meson.build b/meson.build
+index 59bbcfb7..dd75d4e2 100644
+--- a/meson.build
++++ b/meson.build
+@@ -80,6 +80,12 @@ if cc.has_function('clock_gettime', prefix: '#include <time.h>')
+   conf_data.set10('HAVE_CLOCK_GETTIME', true)
+ endif
+ 
++if build_machine.system() == 'darwin' or build_machine.system() == 'freebsd' or not cc.links('#include <argp.h>\nstatic error_t parse_opt (int key, char *arg, struct argp_state *state) { argp_usage(state); return 0; }; void main() {}')
++    argpdep = cc.find_library('argp')
++else
++    argpdep = dependency('', required : false)
++endif
++
+ # ************************ libcrystfel (subdir) ************************
+ 
+ subdir('libcrystfel')
+@@ -180,7 +186,7 @@ endif
+ 
+ indexamajig = executable('indexamajig', indexamajig_sources,
+                          dependencies: [mdep, libcrystfeldep, gsldep,
+-                                        pthreaddep, zmqdep, asapodep],
++                                        pthreaddep, zmqdep, asapodep, argpdep],
+                          install: true,
+                          install_rpath: '$ORIGIN/../lib64/:$ORIGIN/../lib')
+