// SPDX-FileCopyrightText: 2026 Filip Leonarski, Paul Scherrer Institute // SPDX-License-Identifier: GPL-3.0-only #include "JFJochProcessCommandLine.h" #include "../common/DiffractionExperiment.h" #include #include namespace { std::string quote_if_needed(const std::string &s) { if (s.find_first_of(" \t\"'") == std::string::npos) return s; std::string out = "\""; for (char c: s) { if (c == '"' || c == '\\') out += '\\'; out += c; } out += '"'; return out; } const char *indexing_alg_flag(IndexingAlgorithmEnum a) { switch (a) { case IndexingAlgorithmEnum::FFBIDX: return "ffbidx"; case IndexingAlgorithmEnum::FFT: return "fft"; case IndexingAlgorithmEnum::FFTW: return "fftw"; case IndexingAlgorithmEnum::None: return "none"; case IndexingAlgorithmEnum::Auto: default: return "auto"; } } const char *refine_flag(GeomRefinementAlgorithmEnum r) { switch (r) { case GeomRefinementAlgorithmEnum::None: return "none"; case GeomRefinementAlgorithmEnum::OrientationOnly: return "orientation"; case GeomRefinementAlgorithmEnum::BeamCenter: default: return "beam_and_lattice"; } } std::string num(double v) { std::ostringstream o; o << v; return o.str(); } } std::string JFJochProcessCommandLine(const ProcessConfig &config, const DiffractionExperiment &experiment, const std::string &input_file) { std::vector args; const bool azint = (config.mode == ProcessMode::AzimuthalIntegration); args.emplace_back(azint ? "jfjoch_azint" : "jfjoch_process"); auto add = [&](const std::string &flag, const std::string &val) { args.push_back(flag); args.push_back(val); }; if (!config.output_prefix.empty()) add("-o", config.output_prefix); add("-N", std::to_string(config.nthreads)); if (config.start_image != 0) add("-s", std::to_string(config.start_image)); if (config.end_image >= 0) add("-e", std::to_string(config.end_image)); if (config.stride != 1) add("-t", std::to_string(config.stride)); if (azint) { const auto a = experiment.GetAzimuthalIntegrationSettings(); add("--min-q", num(a.GetLowQ_recipA())); add("--max-q", num(a.GetHighQ_recipA())); add("--q-spacing", num(a.GetQSpacing_recipA())); add("--azimuthal-bins", std::to_string(a.GetAzimuthalBinCount())); add("--polarization-correction", a.IsPolarizationCorrection() ? "on" : "off"); add("--solid-angle-correction", a.IsSolidAngleCorrection() ? "on" : "off"); } else { const auto &sf = config.spot_finding; add("--spot-sigma", num(sf.signal_to_noise_threshold)); add("--spot-threshold", std::to_string(sf.photon_count_threshold)); add("--spot-high-resolution", num(sf.high_resolution_limit)); add("--max-spots", std::to_string(experiment.GetMaxSpotCount())); const auto idx = experiment.GetIndexingSettings(); add("-X", indexing_alg_flag(idx.GetAlgorithm())); add("-r", refine_flag(idx.GetGeomRefinementAlgorithm())); if (const auto sg = experiment.GetSpaceGroupNumber()) add("-S", std::to_string(*sg)); if (const auto uc = experiment.GetUnitCell()) { std::ostringstream o; o << uc->a << "," << uc->b << "," << uc->c << "," << uc->alpha << "," << uc->beta << "," << uc->gamma; add("-C", o.str()); } if (const auto bw = experiment.GetBandwidthFWHM()) add("--bandwidth", num(*bw)); const auto bragg = experiment.GetBraggIntegrationSettings(); std::ostringstream radii; radii << bragg.GetR1() << "," << bragg.GetR2() << "," << bragg.GetR3(); add("--integration-radius", radii.str()); if (config.rotation_indexing) { if (config.two_pass_rotation) add("-R", std::to_string(config.rotation_indexing_image_count)); else args.emplace_back("--single-pass-rotation"); if (!config.reuse_rotation_spots) args.emplace_back("--redo-rotation-spots"); } if (config.run_scaling) { args.emplace_back("-M"); const auto sc = experiment.GetScalingSettings(); if (const auto pm = sc.GetPartialityModel()) add("-P", *pm == PartialityModel::Unity ? "unity" : *pm == PartialityModel::Rotation ? "rot" : "fixed"); if (!sc.GetMergeFriedel()) args.emplace_back("-A"); if (sc.GetRefineB()) args.emplace_back("-B"); } } args.push_back(input_file); std::ostringstream cmd; for (size_t i = 0; i < args.size(); i++) { if (i) cmd << ' '; cmd << quote_if_needed(args[i]); } return cmd.str(); }