.. _program_listing_file_dx2_scan.cxx: Program Listing for File scan.cxx ================================= |exhale_lsh| :ref:`Return to documentation for file ` (``dx2/scan.cxx``) .. |exhale_lsh| unicode:: U+021B0 .. UPWARDS ARROW WITH TIP LEFTWARDS .. code-block:: cpp #include "dx2/scan.hpp" Scan::Scan(std::array image_range, std::array oscillation) : image_range_{image_range} { num_images_ = image_range_[1] - image_range_[0] + 1; oscillation_start_ = oscillation[0]; oscillation_width_ = oscillation[1]; } Scan::Scan(json scan_data) { // minimal required keys are image range and ["properties"]:"oscillation" std::vector required_keys = {"image_range", "properties"}; for (const auto &key : required_keys) { if (scan_data.find(key) == scan_data.end()) { throw std::invalid_argument("Key " + key + " is missing from the input scan JSON"); } } image_range_ = scan_data["image_range"]; num_images_ = image_range_[1] - image_range_[0] + 1; if (scan_data["properties"].find("oscillation") == scan_data["properties"].end()) { throw std::invalid_argument( "Key oscillation is missing from the input scan['properties'] JSON"); } std::vector oscillation; json osc_array = scan_data["properties"]["oscillation"]; // Just read the first two oscillation values as that is all that is needed if (osc_array.size() < 1) { // Unlikely to happen but check anyway for safety. throw std::invalid_argument( "scan['properties']['oscillation'] has no values in the scan JSON"); } else if (osc_array.size() == 1) { // SSX scans just have a single oscillation value (the start angle, usually // 0). Therefore by convention the oscillation width is 0. The dials/dxtbx // output should probably be changed to have two oscillation values both of // zero as a consistent model. oscillation.push_back(osc_array[0]); oscillation_start_ = oscillation[0]; oscillation_width_ = 0; } else { // Typical rotation scan. for (json::iterator it = osc_array.begin(); it != osc_array.begin() + 2; ++it) { oscillation.push_back(*it); } oscillation_start_ = oscillation[0]; oscillation_width_ = oscillation[1] - oscillation[0]; } } json Scan::to_json() const { json scan_data; scan_data["image_range"] = image_range_; scan_data["batch_offset"] = 0; // We MUST NOT use batch offsets in dx2, // written out here for compatibility std::vector oscillation_array(num_images_); for (int i = 0; i < num_images_; i++) { oscillation_array[i] = oscillation_start_ + oscillation_width_ * i; } json properties; properties["oscillation"] = oscillation_array; if (oscillation_array.size() == 1) { properties["oscillation_width"] = 0; } scan_data["properties"] = properties; // FIXME for dials compatibility, do we need exposure times and epochs arrays, // also valid_image_ranges empty dict? return scan_data; } std::array Scan::get_image_range() const { return image_range_; } std::array Scan::get_oscillation() const { return {oscillation_start_, oscillation_width_}; }