grid scan: a raster reaches the spot engine, and the crystal cap says none rather than zero

Two defects the merge created and one the API carried.

Rugnux gated the per-image spot engine on AnalysisModeIsMX, so AnalysisMode::Grid
fell through to the azimuthal-integration-only path: a raster ran, scored nothing,
and reported no crystals. The gate now asks the stages table whether the mode does
spot finding, which is the actual question - three modes need that engine for three
different reasons, and a fourth would otherwise have to be remembered here too.

max_crystals was a required integer defaulting to 10, with 0 meaning "all". Zero
reads as "report no crystals", the opposite of what it did. It is now optional, and
absent means no cap; a crystal found and then dropped is information the caller
cannot get back. grow_score_threshold was missing from the schema entirely.

Measured over the labelled corpus after these fixes: 34 of 34 confirmed-protein
rasters yield a crystal, 0 of 8 water, 0 of 6 ice, 19 of 19 heldout.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EFEJG6WBQv8th4UJFNe53N
This commit is contained in:
leonarski_fandClaude Opus 5 committed 2026-09-08 08:22:14 +02:00
1 parent 37efa573c4
commit d4f280047f
13 files changed
+166 -62

No files matched your search

+7 -2
View File
@@ -1186,9 +1186,12 @@ org::openapitools::server::model::Analysis_settings Convert(const AnalysisSettin
GridScanAnalysisSettings Convert(const org::openapitools::server::model::Grid_scan_analysis_settings &input) {
GridScanAnalysisSettings ret;
ret.ProteinScoreThreshold(input.getProteinScoreThreshold());
ret.GrowScoreThreshold(input.getGrowScoreThreshold());
ret.MinBlobCells(input.getMinBlobCells());
ret.DecisiveSingleCellScore(input.getDecisiveSingleCellScore());
ret.MaxCrystals(input.getMaxCrystals());
// Absent means no cap, so an unset property must not become a cap of zero.
if (input.maxCrystalsIsSet())
ret.MaxCrystals(input.getMaxCrystals());
ret.Indexing(input.isIndexing());
return ret;
}
@@ -1196,9 +1199,11 @@ GridScanAnalysisSettings Convert(const org::openapitools::server::model::Grid_sc
org::openapitools::server::model::Grid_scan_analysis_settings Convert(const GridScanAnalysisSettings &input) {
org::openapitools::server::model::Grid_scan_analysis_settings ret;
ret.setProteinScoreThreshold(input.GetProteinScoreThreshold());
ret.setGrowScoreThreshold(input.GetGrowScoreThreshold());
ret.setMinBlobCells(input.GetMinBlobCells());
ret.setDecisiveSingleCellScore(input.GetDecisiveSingleCellScore());
ret.setMaxCrystals(input.GetMaxCrystals());
if (const auto cap = input.GetMaxCrystals())
ret.setMaxCrystals(*cap);
ret.setIndexing(input.IsIndexing());
return ret;
}
@@ -22,9 +22,11 @@ namespace org::openapitools::server::model
Grid_scan_analysis_settings::Grid_scan_analysis_settings()
{
m_Protein_score_threshold = 0.5f;
m_Grow_score_threshold = 0.35f;
m_Min_blob_cells = 3L;
m_Decisive_single_cell_score = 0.9f;
m_Max_crystals = 10L;
m_Decisive_single_cell_score = 0.6f;
m_Max_crystals = 0L;
m_Max_crystalsIsSet = false;
m_Indexing = true;
}
@@ -69,6 +71,25 @@ bool Grid_scan_analysis_settings::validate(std::stringstream& msg, const std::st
}
/* Grow_score_threshold */ {
const float& value = m_Grow_score_threshold;
const std::string currentValuePath = _pathPrefix + ".growScoreThreshold";
if (value < static_cast<float>(0))
{
success = false;
msg << currentValuePath << ": must be greater than or equal to 0;";
}
if (value > static_cast<float>(1))
{
success = false;
msg << currentValuePath << ": must be less than or equal to 1;";
}
}
/* Min_blob_cells */ {
const int64_t& value = m_Min_blob_cells;
const std::string currentValuePath = _pathPrefix + ".minBlobCells";
@@ -101,8 +122,8 @@ bool Grid_scan_analysis_settings::validate(std::stringstream& msg, const std::st
}
/* Max_crystals */ {
if (maxCrystalsIsSet())
{
const int64_t& value = m_Max_crystals;
const std::string currentValuePath = _pathPrefix + ".maxCrystals";
@@ -126,14 +147,17 @@ bool Grid_scan_analysis_settings::operator==(const Grid_scan_analysis_settings&
(getProteinScoreThreshold() == rhs.getProteinScoreThreshold())
&&
(getGrowScoreThreshold() == rhs.getGrowScoreThreshold())
&&
(getMinBlobCells() == rhs.getMinBlobCells())
&&
(getDecisiveSingleCellScore() == rhs.getDecisiveSingleCellScore())
&&
(getMaxCrystals() == rhs.getMaxCrystals())
&&
((!maxCrystalsIsSet() && !rhs.maxCrystalsIsSet()) || (maxCrystalsIsSet() && rhs.maxCrystalsIsSet() && getMaxCrystals() == rhs.getMaxCrystals())) &&
(isIndexing() == rhs.isIndexing())
@@ -150,9 +174,11 @@ void to_json(nlohmann::json& j, const Grid_scan_analysis_settings& o)
{
j = nlohmann::json::object();
j["protein_score_threshold"] = o.m_Protein_score_threshold;
j["grow_score_threshold"] = o.m_Grow_score_threshold;
j["min_blob_cells"] = o.m_Min_blob_cells;
j["decisive_single_cell_score"] = o.m_Decisive_single_cell_score;
j["max_crystals"] = o.m_Max_crystals;
if(o.maxCrystalsIsSet())
j["max_crystals"] = o.m_Max_crystals;
j["indexing"] = o.m_Indexing;
}
@@ -160,9 +186,14 @@ void to_json(nlohmann::json& j, const Grid_scan_analysis_settings& o)
void from_json(const nlohmann::json& j, Grid_scan_analysis_settings& o)
{
j.at("protein_score_threshold").get_to(o.m_Protein_score_threshold);
j.at("grow_score_threshold").get_to(o.m_Grow_score_threshold);
j.at("min_blob_cells").get_to(o.m_Min_blob_cells);
j.at("decisive_single_cell_score").get_to(o.m_Decisive_single_cell_score);
j.at("max_crystals").get_to(o.m_Max_crystals);
if(j.find("max_crystals") != j.end())
{
j.at("max_crystals").get_to(o.m_Max_crystals);
o.m_Max_crystalsIsSet = true;
}
j.at("indexing").get_to(o.m_Indexing);
}
@@ -175,6 +206,14 @@ void Grid_scan_analysis_settings::setProteinScoreThreshold(float const value)
{
m_Protein_score_threshold = value;
}
float Grid_scan_analysis_settings::getGrowScoreThreshold() const
{
return m_Grow_score_threshold;
}
void Grid_scan_analysis_settings::setGrowScoreThreshold(float const value)
{
m_Grow_score_threshold = value;
}
int64_t Grid_scan_analysis_settings::getMinBlobCells() const
{
return m_Min_blob_cells;
@@ -198,6 +237,15 @@ int64_t Grid_scan_analysis_settings::getMaxCrystals() const
void Grid_scan_analysis_settings::setMaxCrystals(int64_t const value)
{
m_Max_crystals = value;
m_Max_crystalsIsSet = true;
}
bool Grid_scan_analysis_settings::maxCrystalsIsSet() const
{
return m_Max_crystalsIsSet;
}
void Grid_scan_analysis_settings::unsetMax_crystals()
{
m_Max_crystalsIsSet = false;
}
bool Grid_scan_analysis_settings::isIndexing() const
{
+12 -3
View File
@@ -63,20 +63,27 @@ public:
float getProteinScoreThreshold() const;
void setProteinScoreThreshold(float const value);
/// <summary>
/// A patch is grown out to this score once it has started, so a crystal is not broken in two by a single cell that fell just under protein_score_threshold. Growth can never start on its own - a patch that never reaches the seed threshold is discarded - so lowering this cannot turn weak background into a crystal.
/// </summary>
float getGrowScoreThreshold() const;
void setGrowScoreThreshold(float const value);
/// <summary>
/// How many cells above that threshold make a shape rather than a coincidence. Two cells can be the two ends of a single hit lying on a cell boundary; three is the smallest patch that is not.
/// </summary>
int64_t getMinBlobCells() const;
void setMinBlobCells(int64_t const value);
/// <summary>
/// ...unless one cell on its own is decisive. The rule above is about coincidences, and a lone cell scoring near the top of a saturating score is not one - a crystal smaller than the grid step lights exactly one cell, and refusing it would lose precisely the samples a fine raster is run to find. Set well above protein_score_threshold: this admits the obvious case, it does not lower the general threshold by the back door.
/// ...unless one cell on its own is decisive. The rule above is about coincidences, and a lone cell scoring near the top of a saturating score is not one - a crystal smaller than the grid step lights exactly one cell, and refusing it would lose precisely the samples a fine raster is run to find. The bar is the patch PEAK, not its mean. 0.6 is measured: over 67 labelled rasters the peak-score populations do not overlap - no water raster reaches 0.15 and no ice raster 0.50, while the weakest confirmed-protein raster peaks at 0.67 - so 0.6 is the middle of that gap.
/// </summary>
float getDecisiveSingleCellScore() const;
void setDecisiveSingleCellScore(float const value);
/// <summary>
/// Most crystals reported. A raster over a loop full of shards can label dozens of blobs, and past the first few the list is no longer a ranking anyone acts on. Crystals are sorted by score, so this keeps the best.
/// Most crystals reported, best first. ABSENT MEANS NO CAP, which is the default: a crystal that was found and then dropped is information the caller cannot get back. Set it where a loop full of shards would otherwise label dozens of blobs that nobody acts on.
/// </summary>
int64_t getMaxCrystals() const;
void setMaxCrystals(int64_t const value);
bool maxCrystalsIsSet() const;
void unsetMax_crystals();
/// <summary>
/// Whether each raster cell is indexed as well as scored. On by default: a raster runs at up to 100 Hz, which the FFT indexer keeps up with, and it is additive - blobs are still found on the protein score, so indexing changes nothing about which cells are called crystals and only adds what was found in them. The lattice count per cell is the cheapest multi-lattice or cracked-crystal signal there is, and on a fixed-target serial experiment with a known cell a raster that indexes is most of the measurement. Turn it off for a very large raster where the GPU is the constraint.
/// </summary>
@@ -88,12 +95,14 @@ public:
protected:
float m_Protein_score_threshold;
float m_Grow_score_threshold;
int64_t m_Min_blob_cells;
float m_Decisive_single_cell_score;
int64_t m_Max_crystals;
bool m_Max_crystalsIsSet;
bool m_Indexing;
+20 -8
View File
@@ -2769,7 +2769,7 @@ components:
- protein_score_threshold
- min_blob_cells
- decisive_single_cell_score
- max_crystals
- grow_score_threshold
- indexing
properties:
protein_score_threshold:
@@ -2781,6 +2781,17 @@ components:
description: |
A raster cell counts as protein above this. The per-image protein score saturates, so this
only has to separate "something diffracted here" from "nothing did".
grow_score_threshold:
type: number
format: float
minimum: 0
maximum: 1
default: 0.35
description: |
A patch is grown out to this score once it has started, so a crystal is not broken in two
by a single cell that fell just under protein_score_threshold. Growth can never start on
its own - a patch that never reaches the seed threshold is discarded - so lowering this
cannot turn weak background into a crystal.
min_blob_cells:
type: integer
format: int64
@@ -2795,22 +2806,23 @@ components:
format: float
minimum: 0
maximum: 1
default: 0.9
default: 0.6
description: |
...unless one cell on its own is decisive. The rule above is about coincidences, and a
lone cell scoring near the top of a saturating score is not one - a crystal smaller than
the grid step lights exactly one cell, and refusing it would lose precisely the samples a
fine raster is run to find. Set well above protein_score_threshold: this admits the
obvious case, it does not lower the general threshold by the back door.
fine raster is run to find. The bar is the patch PEAK, not its mean.
0.6 is measured: over 67 labelled rasters the peak-score populations do not overlap - no
water raster reaches 0.15 and no ice raster 0.50, while the weakest confirmed-protein
raster peaks at 0.67 - so 0.6 is the middle of that gap.
max_crystals:
type: integer
format: int64
minimum: 1
default: 10
description: |
Most crystals reported. A raster over a loop full of shards can label dozens of blobs, and
past the first few the list is no longer a ranking anyone acts on. Crystals are sorted by
score, so this keeps the best.
Most crystals reported, best first. ABSENT MEANS NO CAP, which is the default: a crystal
that was found and then dropped is information the caller cannot get back. Set it where a
loop full of shards would otherwise label dozens of blobs that nobody acts on.
indexing:
type: boolean
default: true
+16 -10
View File
@@ -682,17 +682,23 @@ this API cannot express it. Rotation data is collected here and processed offlin
Persistent - not reset by a data collection.</p>
</div></div><h5 class="sc-dAlyuH jbQuod">Request Body schema: <span class="sc-cWSHoV fzNksy">application/json</span></h5><div class="sc-eeDRCY sc-eBMEME gTGgei fMmru"></div><table class="sc-dAbbOL ccPhmY"><tbody><tr class=""><td class="sc-dLMFU sc-eldPxv hZbWKe jXkfaY" kind="field" title="protein_score_threshold"><span class="sc-gFqAkR eRqgPI"></span><span class="property-name">protein_score_threshold</span><div class="sc-Nxspf sc-hRJfrW cXxAXt kYVhSL">required</div></td><td class="sc-fPXMVe bAXEAa"><div><div><span class="sc-Nxspf sc-cfxfcM cXxAXt jrGEaR"></span><span class="sc-Nxspf sc-gFAWRd cXxAXt dYzdDr">number</span><span class="sc-Nxspf sc-gFAWRd cXxAXt dYzdDr"> <!-- -->&lt;<!-- -->float<!-- -->&gt;<!-- --> </span><span> <span class="sc-Nxspf sc-fxwrCY cXxAXt eMVOei"> <!-- -->[ 0 .. 1 ]<!-- --> </span></span></div><div><span class="sc-Nxspf cXxAXt"> <!-- -->Default:<!-- --> </span> <span class="sc-Nxspf sc-ddjGPC cXxAXt jZOCAW">0.5</span></div> <div><div class="sc-eeDRCY sc-eBMEME gTGgei fbXBig"><p>A raster cell counts as protein above this. The per-image protein score saturates, so this
only has to separate &quot;something diffracted here&quot; from &quot;nothing did&quot;.</p>
</div></div></div></td></tr><tr class=""><td class="sc-dLMFU sc-eldPxv hZbWKe jXkfaY" kind="field" title="grow_score_threshold"><span class="sc-gFqAkR eRqgPI"></span><span class="property-name">grow_score_threshold</span><div class="sc-Nxspf sc-hRJfrW cXxAXt kYVhSL">required</div></td><td class="sc-fPXMVe bAXEAa"><div><div><span class="sc-Nxspf sc-cfxfcM cXxAXt jrGEaR"></span><span class="sc-Nxspf sc-gFAWRd cXxAXt dYzdDr">number</span><span class="sc-Nxspf sc-gFAWRd cXxAXt dYzdDr"> <!-- -->&lt;<!-- -->float<!-- -->&gt;<!-- --> </span><span> <span class="sc-Nxspf sc-fxwrCY cXxAXt eMVOei"> <!-- -->[ 0 .. 1 ]<!-- --> </span></span></div><div><span class="sc-Nxspf cXxAXt"> <!-- -->Default:<!-- --> </span> <span class="sc-Nxspf sc-ddjGPC cXxAXt jZOCAW">0.35</span></div> <div><div class="sc-eeDRCY sc-eBMEME gTGgei fbXBig"><p>A patch is grown out to this score once it has started, so a crystal is not broken in two
by a single cell that fell just under protein_score_threshold. Growth can never start on
its own - a patch that never reaches the seed threshold is discarded - so lowering this
cannot turn weak background into a crystal.</p>
</div></div></div></td></tr><tr class=""><td class="sc-dLMFU sc-eldPxv hZbWKe jXkfaY" kind="field" title="min_blob_cells"><span class="sc-gFqAkR eRqgPI"></span><span class="property-name">min_blob_cells</span><div class="sc-Nxspf sc-hRJfrW cXxAXt kYVhSL">required</div></td><td class="sc-fPXMVe bAXEAa"><div><div><span class="sc-Nxspf sc-cfxfcM cXxAXt jrGEaR"></span><span class="sc-Nxspf sc-gFAWRd cXxAXt dYzdDr">integer</span><span class="sc-Nxspf sc-gFAWRd cXxAXt dYzdDr"> <!-- -->&lt;<!-- -->int64<!-- -->&gt;<!-- --> </span><span> <span class="sc-Nxspf sc-fxwrCY cXxAXt eMVOei"> <!-- -->&gt;= 1<!-- --> </span></span></div><div><span class="sc-Nxspf cXxAXt"> <!-- -->Default:<!-- --> </span> <span class="sc-Nxspf sc-ddjGPC cXxAXt jZOCAW">3</span></div> <div><div class="sc-eeDRCY sc-eBMEME gTGgei fbXBig"><p>How many cells above that threshold make a shape rather than a coincidence. Two cells can
be the two ends of a single hit lying on a cell boundary; three is the smallest patch that
is not.</p>
</div></div></div></td></tr><tr class=""><td class="sc-dLMFU sc-eldPxv hZbWKe jXkfaY" kind="field" title="decisive_single_cell_score"><span class="sc-gFqAkR eRqgPI"></span><span class="property-name">decisive_single_cell_score</span><div class="sc-Nxspf sc-hRJfrW cXxAXt kYVhSL">required</div></td><td class="sc-fPXMVe bAXEAa"><div><div><span class="sc-Nxspf sc-cfxfcM cXxAXt jrGEaR"></span><span class="sc-Nxspf sc-gFAWRd cXxAXt dYzdDr">number</span><span class="sc-Nxspf sc-gFAWRd cXxAXt dYzdDr"> <!-- -->&lt;<!-- -->float<!-- -->&gt;<!-- --> </span><span> <span class="sc-Nxspf sc-fxwrCY cXxAXt eMVOei"> <!-- -->[ 0 .. 1 ]<!-- --> </span></span></div><div><span class="sc-Nxspf cXxAXt"> <!-- -->Default:<!-- --> </span> <span class="sc-Nxspf sc-ddjGPC cXxAXt jZOCAW">0.9</span></div> <div><div class="sc-eeDRCY sc-eBMEME gTGgei fbXBig"><p>...unless one cell on its own is decisive. The rule above is about coincidences, and a
</div></div></div></td></tr><tr class=""><td class="sc-dLMFU sc-eldPxv hZbWKe jXkfaY" kind="field" title="decisive_single_cell_score"><span class="sc-gFqAkR eRqgPI"></span><span class="property-name">decisive_single_cell_score</span><div class="sc-Nxspf sc-hRJfrW cXxAXt kYVhSL">required</div></td><td class="sc-fPXMVe bAXEAa"><div><div><span class="sc-Nxspf sc-cfxfcM cXxAXt jrGEaR"></span><span class="sc-Nxspf sc-gFAWRd cXxAXt dYzdDr">number</span><span class="sc-Nxspf sc-gFAWRd cXxAXt dYzdDr"> <!-- -->&lt;<!-- -->float<!-- -->&gt;<!-- --> </span><span> <span class="sc-Nxspf sc-fxwrCY cXxAXt eMVOei"> <!-- -->[ 0 .. 1 ]<!-- --> </span></span></div><div><span class="sc-Nxspf cXxAXt"> <!-- -->Default:<!-- --> </span> <span class="sc-Nxspf sc-ddjGPC cXxAXt jZOCAW">0.6</span></div> <div><div class="sc-eeDRCY sc-eBMEME gTGgei fbXBig"><p>...unless one cell on its own is decisive. The rule above is about coincidences, and a
lone cell scoring near the top of a saturating score is not one - a crystal smaller than
the grid step lights exactly one cell, and refusing it would lose precisely the samples a
fine raster is run to find. Set well above protein_score_threshold: this admits the
obvious case, it does not lower the general threshold by the back door.</p>
</div></div></div></td></tr><tr class=""><td class="sc-dLMFU sc-eldPxv hZbWKe jXkfaY" kind="field" title="max_crystals"><span class="sc-gFqAkR eRqgPI"></span><span class="property-name">max_crystals</span><div class="sc-Nxspf sc-hRJfrW cXxAXt kYVhSL">required</div></td><td class="sc-fPXMVe bAXEAa"><div><div><span class="sc-Nxspf sc-cfxfcM cXxAXt jrGEaR"></span><span class="sc-Nxspf sc-gFAWRd cXxAXt dYzdDr">integer</span><span class="sc-Nxspf sc-gFAWRd cXxAXt dYzdDr"> <!-- -->&lt;<!-- -->int64<!-- -->&gt;<!-- --> </span><span> <span class="sc-Nxspf sc-fxwrCY cXxAXt eMVOei"> <!-- -->&gt;= 1<!-- --> </span></span></div><div><span class="sc-Nxspf cXxAXt"> <!-- -->Default:<!-- --> </span> <span class="sc-Nxspf sc-ddjGPC cXxAXt jZOCAW">10</span></div> <div><div class="sc-eeDRCY sc-eBMEME gTGgei fbXBig"><p>Most crystals reported. A raster over a loop full of shards can label dozens of blobs, and
past the first few the list is no longer a ranking anyone acts on. Crystals are sorted by
score, so this keeps the best.</p>
fine raster is run to find. The bar is the patch PEAK, not its mean.
0.6 is measured: over 67 labelled rasters the peak-score populations do not overlap - no
water raster reaches 0.15 and no ice raster 0.50, while the weakest confirmed-protein
raster peaks at 0.67 - so 0.6 is the middle of that gap.</p>
</div></div></div></td></tr><tr class=""><td class="sc-dLMFU sc-eldPxv hZbWKe jXkfaY" kind="field" title="max_crystals"><span class="sc-gFqAkR eRqgPI"></span><span class="property-name">max_crystals</span></td><td class="sc-fPXMVe bAXEAa"><div><div><span class="sc-Nxspf sc-cfxfcM cXxAXt jrGEaR"></span><span class="sc-Nxspf sc-gFAWRd cXxAXt dYzdDr">integer</span><span class="sc-Nxspf sc-gFAWRd cXxAXt dYzdDr"> <!-- -->&lt;<!-- -->int64<!-- -->&gt;<!-- --> </span><span> <span class="sc-Nxspf sc-fxwrCY cXxAXt eMVOei"> <!-- -->&gt;= 1<!-- --> </span></span></div> <div><div class="sc-eeDRCY sc-eBMEME gTGgei fbXBig"><p>Most crystals reported, best first. ABSENT MEANS NO CAP, which is the default: a crystal
that was found and then dropped is information the caller cannot get back. Set it where a
loop full of shards would otherwise label dozens of blobs that nobody acts on.</p>
</div></div></div></td></tr><tr class="last "><td class="sc-dLMFU sc-eldPxv hZbWKe jXkfaY" kind="field" title="indexing"><span class="sc-gFqAkR eRqgPI"></span><span class="property-name">indexing</span><div class="sc-Nxspf sc-hRJfrW cXxAXt kYVhSL">required</div></td><td class="sc-fPXMVe bAXEAa"><div><div><span class="sc-Nxspf sc-cfxfcM cXxAXt jrGEaR"></span><span class="sc-Nxspf sc-gFAWRd cXxAXt dYzdDr">boolean</span></div><div><span class="sc-Nxspf cXxAXt"> <!-- -->Default:<!-- --> </span> <span class="sc-Nxspf sc-ddjGPC cXxAXt jZOCAW">true</span></div> <div><div class="sc-eeDRCY sc-eBMEME gTGgei fbXBig"><p>Whether each raster cell is indexed as well as scored. On by default: a raster runs at up
to 100 Hz, which the FFT indexer keeps up with, and it is additive - blobs are still found
on the protein score, so indexing changes nothing about which cells are called crystals
@@ -704,10 +710,10 @@ large raster where the GPU is the constraint.</p>
</div></button></div><div><button class="sc-kzqdkY bXzzUN"><svg class="sc-cwHptR cSkZlF" version="1.1" viewBox="0 0 24 24" x="0" xmlns="http://www.w3.org/2000/svg" y="0" aria-hidden="true"><polygon points="17.3 8.3 12 13.6 6.7 8.3 5.3 9.7 12 16.4 18.7 9.7 "></polygon></svg><strong class="sc-dSIIpw bpEYcE">400<!-- --> </strong><div class="sc-eeDRCY sc-eBMEME sc-dCFHLb gTGgei kekOtA kCaLQd"><p>Input parsing or validation error</p>
</div></button></div><div><button class="sc-kzqdkY bXzzUN"><svg class="sc-cwHptR cSkZlF" version="1.1" viewBox="0 0 24 24" x="0" xmlns="http://www.w3.org/2000/svg" y="0" aria-hidden="true"><polygon points="17.3 8.3 12 13.6 6.7 8.3 5.3 9.7 12 16.4 18.7 9.7 "></polygon></svg><strong class="sc-dSIIpw bpEYcE">500<!-- --> </strong><div class="sc-eeDRCY sc-eBMEME sc-dCFHLb gTGgei kekOtA kCaLQd"><p>Error within Jungfraujoch code - see output message.</p>
</div></button></div></div></div><div class="sc-iGgWBj sc-gsFSXq ibAZSi eDeKjd"><div class="sc-ejfMa-d bNUPQg"><button class="sc-EgOXT cFEcOl"><span type="put" class="sc-eZYNyq cnqpVw http-verb put">put</span><span class="sc-iEXKAA gUNSDu">/config/grid_scan_analysis</span><svg class="sc-cwHptR iVFMLx" style="margin-right:-25px" version="1.1" viewBox="0 0 24 24" x="0" xmlns="http://www.w3.org/2000/svg" y="0" aria-hidden="true"><polygon points="17.3 8.3 12 13.6 6.7 8.3 5.3 9.7 12 16.4 18.7 9.7 "></polygon></svg></button><div aria-hidden="true" class="sc-dlWCHZ kWacYr"><div class="sc-hHOBiw cndTNO"><div class="sc-eeDRCY sc-eBMEME gTGgei fbXBig"><p>Test Jungfraujoch system</p>
</div><div tabindex="0" role="button"><div class="sc-kWtpeL gEncxT"><span>http://localhost:5232</span>/config/grid_scan_analysis</div></div></div></div></div><div><h3 class="sc-kpDqfm eBBgSB"> <!-- -->Request samples<!-- --> </h3><div class="sc-bXCLTC dHowgL" data-rttabs="true"><ul class="react-tabs__tab-list" role="tablist"><li class="react-tabs__tab react-tabs__tab--selected" role="tab" id="tab_R_ii9a_0" aria-selected="true" aria-disabled="false" aria-controls="panel_R_ii9a_0" tabindex="0" data-rttab="true">Payload</li></ul><div class="react-tabs__tab-panel react-tabs__tab-panel--selected" role="tabpanel" id="panel_R_ii9a_0" aria-labelledby="tab_R_ii9a_0"><div><div class="sc-bbSZdi gCVTxk"><span class="sc-fjvvzt jWReSk">Content type</span><div class="sc-JrDLc iTKzPJ">application/json</div></div><div class="sc-uVWWZ gQROPU"><div class="sc-esYiGF dWQNJI"><div class="sc-koXPp efufqz"><button><div class="sc-fhzFiK kwZDms">Copy</div></button></div><div tabindex="0" class="sc-eeDRCY gTGgei sc-fXSgeo bnrBiz"><div class="redoc-json"><code><button class="collapser" aria-label="collapse"></button><span class="token punctuation">{</span><span class="ellipsis"></span><ul class="obj collapsible"><li><div class="hoverable "><span class="property token string">"protein_score_threshold"</span>: <span class="token number">0.5</span><span class="token punctuation">,</span></div></li><li><div class="hoverable "><span class="property token string">"min_blob_cells"</span>: <span class="token number">3</span><span class="token punctuation">,</span></div></li><li><div class="hoverable "><span class="property token string">"decisive_single_cell_score"</span>: <span class="token number">0.9</span><span class="token punctuation">,</span></div></li><li><div class="hoverable "><span class="property token string">"max_crystals"</span>: <span class="token number">10</span><span class="token punctuation">,</span></div></li><li><div class="hoverable "><span class="property token string">"indexing"</span>: <span class="token boolean">true</span></div></li></ul><span class="token punctuation">}</span></code></div></div></div></div></div></div></div></div><div><h3 class="sc-kpDqfm eBBgSB"> <!-- -->Response samples<!-- --> </h3><div class="sc-bXCLTC dHowgL" data-rttabs="true"><ul class="react-tabs__tab-list" role="tablist"><li class="tab-error react-tabs__tab--selected" role="tab" id="tab_R_ji9a_0" aria-selected="true" aria-disabled="false" aria-controls="panel_R_ji9a_0" tabindex="0" data-rttab="true">500</li></ul><div class="react-tabs__tab-panel react-tabs__tab-panel--selected" role="tabpanel" id="panel_R_ji9a_0" aria-labelledby="tab_R_ji9a_0"><div><div class="sc-bbSZdi gCVTxk"><span class="sc-fjvvzt jWReSk">Content type</span><div class="sc-JrDLc iTKzPJ">application/json</div></div><div class="sc-uVWWZ gQROPU"><div class="sc-esYiGF dWQNJI"><div class="sc-koXPp efufqz"><button><div class="sc-fhzFiK kwZDms">Copy</div></button></div><div tabindex="0" class="sc-eeDRCY gTGgei sc-fXSgeo bnrBiz"><div class="redoc-json"><code><button class="collapser" aria-label="collapse"></button><span class="token punctuation">{</span><span class="ellipsis"></span><ul class="obj collapsible"><li><div class="hoverable "><span class="property token string">"msg"</span>: <span class="token string">&quot;Detector in wrong state&quot;</span><span class="token punctuation">,</span></div></li><li><div class="hoverable "><span class="property token string">"reason"</span>: <span class="token string">&quot;WrongDAQState&quot;</span></div></li></ul><span class="token punctuation">}</span></code></div></div></div></div></div></div></div></div></div></div></div><div id="/paths/~1config~1grid_scan_analysis/get" data-section-id="/paths/~1config~1grid_scan_analysis/get" class="sc-dcJsrY cqVkUp"><div class="sc-kAyceB hBQWIZ"><div class="sc-fqkvVR oJKYx"><h2 class="sc-jXbUNg fWnwAh"><a class="sc-jlZhew kbdRLs" href="#/paths/~1config~1grid_scan_analysis/get" aria-label="/paths/~1config~1grid_scan_analysis/get"></a>Get grid scan analysis configuration<!-- --> </h2><div class="sc-bVVIoq icSMtY"><div class="sc-eeDRCY sc-eBMEME gTGgei fMmru"><p>Can be done anytime</p>
</div><div tabindex="0" role="button"><div class="sc-kWtpeL gEncxT"><span>http://localhost:5232</span>/config/grid_scan_analysis</div></div></div></div></div><div><h3 class="sc-kpDqfm eBBgSB"> <!-- -->Request samples<!-- --> </h3><div class="sc-bXCLTC dHowgL" data-rttabs="true"><ul class="react-tabs__tab-list" role="tablist"><li class="react-tabs__tab react-tabs__tab--selected" role="tab" id="tab_R_ii9a_0" aria-selected="true" aria-disabled="false" aria-controls="panel_R_ii9a_0" tabindex="0" data-rttab="true">Payload</li></ul><div class="react-tabs__tab-panel react-tabs__tab-panel--selected" role="tabpanel" id="panel_R_ii9a_0" aria-labelledby="tab_R_ii9a_0"><div><div class="sc-bbSZdi gCVTxk"><span class="sc-fjvvzt jWReSk">Content type</span><div class="sc-JrDLc iTKzPJ">application/json</div></div><div class="sc-uVWWZ gQROPU"><div class="sc-esYiGF dWQNJI"><div class="sc-koXPp efufqz"><button><div class="sc-fhzFiK kwZDms">Copy</div></button></div><div tabindex="0" class="sc-eeDRCY gTGgei sc-fXSgeo bnrBiz"><div class="redoc-json"><code><button class="collapser" aria-label="collapse"></button><span class="token punctuation">{</span><span class="ellipsis"></span><ul class="obj collapsible"><li><div class="hoverable "><span class="property token string">"protein_score_threshold"</span>: <span class="token number">0.5</span><span class="token punctuation">,</span></div></li><li><div class="hoverable "><span class="property token string">"grow_score_threshold"</span>: <span class="token number">0.35</span><span class="token punctuation">,</span></div></li><li><div class="hoverable "><span class="property token string">"min_blob_cells"</span>: <span class="token number">3</span><span class="token punctuation">,</span></div></li><li><div class="hoverable "><span class="property token string">"decisive_single_cell_score"</span>: <span class="token number">0.6</span><span class="token punctuation">,</span></div></li><li><div class="hoverable "><span class="property token string">"max_crystals"</span>: <span class="token number">1</span><span class="token punctuation">,</span></div></li><li><div class="hoverable "><span class="property token string">"indexing"</span>: <span class="token boolean">true</span></div></li></ul><span class="token punctuation">}</span></code></div></div></div></div></div></div></div></div><div><h3 class="sc-kpDqfm eBBgSB"> <!-- -->Response samples<!-- --> </h3><div class="sc-bXCLTC dHowgL" data-rttabs="true"><ul class="react-tabs__tab-list" role="tablist"><li class="tab-error react-tabs__tab--selected" role="tab" id="tab_R_ji9a_0" aria-selected="true" aria-disabled="false" aria-controls="panel_R_ji9a_0" tabindex="0" data-rttab="true">500</li></ul><div class="react-tabs__tab-panel react-tabs__tab-panel--selected" role="tabpanel" id="panel_R_ji9a_0" aria-labelledby="tab_R_ji9a_0"><div><div class="sc-bbSZdi gCVTxk"><span class="sc-fjvvzt jWReSk">Content type</span><div class="sc-JrDLc iTKzPJ">application/json</div></div><div class="sc-uVWWZ gQROPU"><div class="sc-esYiGF dWQNJI"><div class="sc-koXPp efufqz"><button><div class="sc-fhzFiK kwZDms">Copy</div></button></div><div tabindex="0" class="sc-eeDRCY gTGgei sc-fXSgeo bnrBiz"><div class="redoc-json"><code><button class="collapser" aria-label="collapse"></button><span class="token punctuation">{</span><span class="ellipsis"></span><ul class="obj collapsible"><li><div class="hoverable "><span class="property token string">"msg"</span>: <span class="token string">&quot;Detector in wrong state&quot;</span><span class="token punctuation">,</span></div></li><li><div class="hoverable "><span class="property token string">"reason"</span>: <span class="token string">&quot;WrongDAQState&quot;</span></div></li></ul><span class="token punctuation">}</span></code></div></div></div></div></div></div></div></div></div></div></div><div id="/paths/~1config~1grid_scan_analysis/get" data-section-id="/paths/~1config~1grid_scan_analysis/get" class="sc-dcJsrY cqVkUp"><div class="sc-kAyceB hBQWIZ"><div class="sc-fqkvVR oJKYx"><h2 class="sc-jXbUNg fWnwAh"><a class="sc-jlZhew kbdRLs" href="#/paths/~1config~1grid_scan_analysis/get" aria-label="/paths/~1config~1grid_scan_analysis/get"></a>Get grid scan analysis configuration<!-- --> </h2><div class="sc-bVVIoq icSMtY"><div class="sc-eeDRCY sc-eBMEME gTGgei fMmru"><p>Can be done anytime</p>
</div></div><div><h3 class="sc-fMMURN egoxtT">Responses</h3><div><button class="sc-kzqdkY jgSwKD"><svg class="sc-cwHptR hWEnWx" version="1.1" viewBox="0 0 24 24" x="0" xmlns="http://www.w3.org/2000/svg" y="0" aria-hidden="true"><polygon points="17.3 8.3 12 13.6 6.7 8.3 5.3 9.7 12 16.4 18.7 9.7 "></polygon></svg><strong class="sc-dSIIpw bpEYcE">200<!-- --> </strong><div class="sc-eeDRCY sc-eBMEME sc-dCFHLb gTGgei kekOtA kCaLQd"><p>Everything OK</p>
</div></button></div></div></div><div class="sc-iGgWBj sc-gsFSXq ibAZSi eDeKjd"><div class="sc-ejfMa-d bNUPQg"><button class="sc-EgOXT cFEcOl"><span type="get" class="sc-eZYNyq qGfV http-verb get">get</span><span class="sc-iEXKAA gUNSDu">/config/grid_scan_analysis</span><svg class="sc-cwHptR iVFMLx" style="margin-right:-25px" version="1.1" viewBox="0 0 24 24" x="0" xmlns="http://www.w3.org/2000/svg" y="0" aria-hidden="true"><polygon points="17.3 8.3 12 13.6 6.7 8.3 5.3 9.7 12 16.4 18.7 9.7 "></polygon></svg></button><div aria-hidden="true" class="sc-dlWCHZ kWacYr"><div class="sc-hHOBiw cndTNO"><div class="sc-eeDRCY sc-eBMEME gTGgei fbXBig"><p>Test Jungfraujoch system</p>
</div><div tabindex="0" role="button"><div class="sc-kWtpeL gEncxT"><span>http://localhost:5232</span>/config/grid_scan_analysis</div></div></div></div></div><div><h3 class="sc-kpDqfm eBBgSB"> <!-- -->Response samples<!-- --> </h3><div class="sc-bXCLTC dHowgL" data-rttabs="true"><ul class="react-tabs__tab-list" role="tablist"><li class="tab-success react-tabs__tab--selected" role="tab" id="tab_R_ji9q_0" aria-selected="true" aria-disabled="false" aria-controls="panel_R_ji9q_0" tabindex="0" data-rttab="true">200</li></ul><div class="react-tabs__tab-panel react-tabs__tab-panel--selected" role="tabpanel" id="panel_R_ji9q_0" aria-labelledby="tab_R_ji9q_0"><div><div class="sc-bbSZdi gCVTxk"><span class="sc-fjvvzt jWReSk">Content type</span><div class="sc-JrDLc iTKzPJ">application/json</div></div><div class="sc-uVWWZ gQROPU"><div class="sc-esYiGF dWQNJI"><div class="sc-koXPp efufqz"><button><div class="sc-fhzFiK kwZDms">Copy</div></button></div><div tabindex="0" class="sc-eeDRCY gTGgei sc-fXSgeo bnrBiz"><div class="redoc-json"><code><button class="collapser" aria-label="collapse"></button><span class="token punctuation">{</span><span class="ellipsis"></span><ul class="obj collapsible"><li><div class="hoverable "><span class="property token string">"protein_score_threshold"</span>: <span class="token number">0.5</span><span class="token punctuation">,</span></div></li><li><div class="hoverable "><span class="property token string">"min_blob_cells"</span>: <span class="token number">3</span><span class="token punctuation">,</span></div></li><li><div class="hoverable "><span class="property token string">"decisive_single_cell_score"</span>: <span class="token number">0.9</span><span class="token punctuation">,</span></div></li><li><div class="hoverable "><span class="property token string">"max_crystals"</span>: <span class="token number">10</span><span class="token punctuation">,</span></div></li><li><div class="hoverable "><span class="property token string">"indexing"</span>: <span class="token boolean">true</span></div></li></ul><span class="token punctuation">}</span></code></div></div></div></div></div></div></div></div></div></div></div><div id="/paths/~1config~1calibration/put" data-section-id="/paths/~1config~1calibration/put" class="sc-dcJsrY cqVkUp"><div class="sc-kAyceB hBQWIZ"><div class="sc-fqkvVR oJKYx"><h2 class="sc-jXbUNg fWnwAh"><a class="sc-jlZhew kbdRLs" href="#/paths/~1config~1calibration/put" aria-label="/paths/~1config~1calibration/put"></a>Change powder calibration settings<!-- --> </h2><div class="sc-bVVIoq icSMtY"><div class="sc-eeDRCY sc-eBMEME gTGgei fMmru"><p>This can only be done when detector is <code>Idle</code>, <code>Error</code> or <code>Inactive</code> states.
</div><div tabindex="0" role="button"><div class="sc-kWtpeL gEncxT"><span>http://localhost:5232</span>/config/grid_scan_analysis</div></div></div></div></div><div><h3 class="sc-kpDqfm eBBgSB"> <!-- -->Response samples<!-- --> </h3><div class="sc-bXCLTC dHowgL" data-rttabs="true"><ul class="react-tabs__tab-list" role="tablist"><li class="tab-success react-tabs__tab--selected" role="tab" id="tab_R_ji9q_0" aria-selected="true" aria-disabled="false" aria-controls="panel_R_ji9q_0" tabindex="0" data-rttab="true">200</li></ul><div class="react-tabs__tab-panel react-tabs__tab-panel--selected" role="tabpanel" id="panel_R_ji9q_0" aria-labelledby="tab_R_ji9q_0"><div><div class="sc-bbSZdi gCVTxk"><span class="sc-fjvvzt jWReSk">Content type</span><div class="sc-JrDLc iTKzPJ">application/json</div></div><div class="sc-uVWWZ gQROPU"><div class="sc-esYiGF dWQNJI"><div class="sc-koXPp efufqz"><button><div class="sc-fhzFiK kwZDms">Copy</div></button></div><div tabindex="0" class="sc-eeDRCY gTGgei sc-fXSgeo bnrBiz"><div class="redoc-json"><code><button class="collapser" aria-label="collapse"></button><span class="token punctuation">{</span><span class="ellipsis"></span><ul class="obj collapsible"><li><div class="hoverable "><span class="property token string">"protein_score_threshold"</span>: <span class="token number">0.5</span><span class="token punctuation">,</span></div></li><li><div class="hoverable "><span class="property token string">"grow_score_threshold"</span>: <span class="token number">0.35</span><span class="token punctuation">,</span></div></li><li><div class="hoverable "><span class="property token string">"min_blob_cells"</span>: <span class="token number">3</span><span class="token punctuation">,</span></div></li><li><div class="hoverable "><span class="property token string">"decisive_single_cell_score"</span>: <span class="token number">0.6</span><span class="token punctuation">,</span></div></li><li><div class="hoverable "><span class="property token string">"max_crystals"</span>: <span class="token number">1</span><span class="token punctuation">,</span></div></li><li><div class="hoverable "><span class="property token string">"indexing"</span>: <span class="token boolean">true</span></div></li></ul><span class="token punctuation">}</span></code></div></div></div></div></div></div></div></div></div></div></div><div id="/paths/~1config~1calibration/put" data-section-id="/paths/~1config~1calibration/put" class="sc-dcJsrY cqVkUp"><div class="sc-kAyceB hBQWIZ"><div class="sc-fqkvVR oJKYx"><h2 class="sc-jXbUNg fWnwAh"><a class="sc-jlZhew kbdRLs" href="#/paths/~1config~1calibration/put" aria-label="/paths/~1config~1calibration/put"></a>Change powder calibration settings<!-- --> </h2><div class="sc-bVVIoq icSMtY"><div class="sc-eeDRCY sc-eBMEME gTGgei fMmru"><p>This can only be done when detector is <code>Idle</code>, <code>Error</code> or <code>Inactive</code> states.
Persistent - not reset by a data collection.</p>
</div></div><h5 class="sc-dAlyuH jbQuod">Request Body schema: <span class="sc-cWSHoV fzNksy">application/json</span></h5><div class="sc-eeDRCY sc-eBMEME gTGgei fMmru"></div><table class="sc-dAbbOL ccPhmY"><tbody><tr class=""><td class="sc-dLMFU sc-eldPxv hZbWKe jXkfaY" kind="field" title="calibrant"><span class="sc-gFqAkR eRqgPI"></span><span class="property-name">calibrant</span></td><td class="sc-fPXMVe bAXEAa"><div><div><span class="sc-Nxspf sc-cfxfcM cXxAXt jrGEaR"></span><span class="sc-Nxspf sc-gFAWRd cXxAXt dYzdDr">string</span></div> <div><div class="sc-eeDRCY sc-eBMEME gTGgei fbXBig"><p>Which calibrant&#39;s ring d-spacings the geometry is fitted against. Empty selects the
processing program&#39;s own default rather than meaning &quot;no calibrant&quot;.</p>
@@ -950,7 +956,7 @@ This can only be done when detector is <code>Idle</code>, <code>Error</code> or
</div></button></div></div></div><div class="sc-iGgWBj sc-gsFSXq ibAZSi eDeKjd"><div class="sc-ejfMa-d bNUPQg"><button class="sc-EgOXT cFEcOl"><span type="put" class="sc-eZYNyq cnqpVw http-verb put">put</span><span class="sc-iEXKAA gUNSDu">/config/roi</span><svg class="sc-cwHptR iVFMLx" style="margin-right:-25px" version="1.1" viewBox="0 0 24 24" x="0" xmlns="http://www.w3.org/2000/svg" y="0" aria-hidden="true"><polygon points="17.3 8.3 12 13.6 6.7 8.3 5.3 9.7 12 16.4 18.7 9.7 "></polygon></svg></button><div aria-hidden="true" class="sc-dlWCHZ kWacYr"><div class="sc-hHOBiw cndTNO"><div class="sc-eeDRCY sc-eBMEME gTGgei fbXBig"><p>Test Jungfraujoch system</p>
</div><div tabindex="0" role="button"><div class="sc-kWtpeL gEncxT"><span>http://localhost:5232</span>/config/roi</div></div></div></div></div><div><h3 class="sc-kpDqfm eBBgSB"> <!-- -->Request samples<!-- --> </h3><div class="sc-bXCLTC dHowgL" data-rttabs="true"><ul class="react-tabs__tab-list" role="tablist"><li class="react-tabs__tab react-tabs__tab--selected" role="tab" id="tab_R_iipq_0" aria-selected="true" aria-disabled="false" aria-controls="panel_R_iipq_0" tabindex="0" data-rttab="true">Payload</li></ul><div class="react-tabs__tab-panel react-tabs__tab-panel--selected" role="tabpanel" id="panel_R_iipq_0" aria-labelledby="tab_R_iipq_0"><div><div class="sc-bbSZdi gCVTxk"><span class="sc-fjvvzt jWReSk">Content type</span><div class="sc-JrDLc iTKzPJ">application/json</div></div><div class="sc-uVWWZ gQROPU"><div class="sc-esYiGF dWQNJI"><div class="sc-koXPp efufqz"><button><div class="sc-fhzFiK kwZDms">Copy</div></button><button> Expand all </button><button> Collapse all </button></div><div tabindex="0" class="sc-eeDRCY gTGgei sc-fXSgeo bnrBiz"><div class="redoc-json"><code><button class="collapser" aria-label="collapse"></button><span class="token punctuation">{</span><span class="ellipsis"></span><ul class="obj collapsible"><li><div class="hoverable "><span class="property token string">"box"</span>: <button class="collapser" aria-label="collapse"></button><span class="token punctuation">{</span><span class="ellipsis"></span><ul class="obj collapsible"><li><div class="hoverable collapsed"><span class="property token string">"rois"</span>: <button class="collapser" aria-label="expand"></button><span class="token punctuation">[</span><span class="ellipsis"></span><ul class="array collapsible"><li><div class="hoverable collapsed"><button class="collapser" aria-label="expand"></button><span class="token punctuation">{</span><span class="ellipsis"></span><ul class="obj collapsible"><li><div class="hoverable collapsed"><span class="property token string">"name"</span>: <span class="token string">&quot;string&quot;</span><span class="token punctuation">,</span></div></li><li><div class="hoverable collapsed"><span class="property token string">"min_x_pxl"</span>: <span class="token number">0</span><span class="token punctuation">,</span></div></li><li><div class="hoverable collapsed"><span class="property token string">"max_x_pxl"</span>: <span class="token number">0</span><span class="token punctuation">,</span></div></li><li><div class="hoverable collapsed"><span class="property token string">"min_y_pxl"</span>: <span class="token number">0</span><span class="token punctuation">,</span></div></li><li><div class="hoverable collapsed"><span class="property token string">"max_y_pxl"</span>: <span class="token number">0</span></div></li></ul><span class="token punctuation">}</span></div></li></ul><span class="token punctuation">]</span></div></li></ul><span class="token punctuation">}</span><span class="token punctuation">,</span></div></li><li><div class="hoverable "><span class="property token string">"circle"</span>: <button class="collapser" aria-label="collapse"></button><span class="token punctuation">{</span><span class="ellipsis"></span><ul class="obj collapsible"><li><div class="hoverable collapsed"><span class="property token string">"rois"</span>: <button class="collapser" aria-label="expand"></button><span class="token punctuation">[</span><span class="ellipsis"></span><ul class="array collapsible"><li><div class="hoverable collapsed"><button class="collapser" aria-label="expand"></button><span class="token punctuation">{</span><span class="ellipsis"></span><ul class="obj collapsible"><li><div class="hoverable collapsed"><span class="property token string">"name"</span>: <span class="token string">&quot;string&quot;</span><span class="token punctuation">,</span></div></li><li><div class="hoverable collapsed"><span class="property token string">"center_x_pxl"</span>: <span class="token number">0.1</span><span class="token punctuation">,</span></div></li><li><div class="hoverable collapsed"><span class="property token string">"center_y_pxl"</span>: <span class="token number">0.1</span><span class="token punctuation">,</span></div></li><li><div class="hoverable collapsed"><span class="property token string">"radius_pxl"</span>: <span class="token number">0.1</span></div></li></ul><span class="token punctuation">}</span></div></li></ul><span class="token punctuation">]</span></div></li></ul><span class="token punctuation">}</span><span class="token punctuation">,</span></div></li><li><div class="hoverable "><span class="property token string">"azim"</span>: <button class="collapser" aria-label="collapse"></button><span class="token punctuation">{</span><span class="ellipsis"></span><ul class="obj collapsible"><li><div class="hoverable collapsed"><span class="property token string">"rois"</span>: <button class="collapser" aria-label="expand"></button><span class="token punctuation">[</span><span class="eLine truncated
</div></button></div></div></div><div class="sc-iGgWBj sc-gsFSXq ibAZSi eDeKjd"><div class="sc-ejfMa-d bNUPQg"><button class="sc-EgOXT cFEcOl"><span type="get" class="sc-eZYNyq qGfV http-verb get">get</span><span class="sc-iEXKAA gUNSDu">/statistics</span><svg class="sc-cwHptR iVFMLx" style="margin-right:-25px" version="1.1" viewBox="0 0 24 24" x="0" xmlns="http://www.w3.org/2000/svg" y="0" aria-hidden="true"><polygon points="17.3 8.3 12 13.6 6.7 8.3 5.3 9.7 12 16.4 18.7 9.7 "></polygon></svg></button><div aria-hidden="true" class="sc-dlWCHZ kWacYr"><div class="sc-hHOBiw cndTNO"><div class="sc-eeDRCY sc-eBMEME gTGgei fbXBig"><p>Test Jungfraujoch system</p>
</div><div tabindex="0" role="button"><div class="sc-kWtpeL gEncxT"><span>http://localhost:5232</span>/statistics</div></div></div></div></div><div><h3 class="sc-kpDqfm eBBgSB"> <!-- -->Response samples<!-- --> </h3><div class="sc-bXCLTC dHowgL" data-rttabs="true"><ul class="react-tabs__tab-list" role="tablist"><li class="tab-success react-tabs__tab--selected" role="tab" id="tab_R_jiqa_0" aria-selected="true" aria-disabled="false" aria-controls="panel_R_jiqa_0" tabindex="0" data-rttab="true">200</li></ul><div class="react-tabs__tab-panel react-tabs__tab-panel--selected" role="tabpanel" id="panel_R_jiqa_0" aria-labelledby="tab_R_jiqa_0"><div><div class="sc-bbSZdi gCVTxk"><span class="sc-fjvvzt jWReSk">Content type</span><div class="sc-JrDLc iTKzPJ">application/json</div></div><div class="sc-uVWWZ gQROPU"><div class="sc-esYiGF dWQNJI"><div class="sc-koXPp efufqz"><button><div class="sc-fhzFiK kwZDms">Copy</div></button><button> Expand all </button><button> Collapse all </button></div><div tabindex="0" class="sc-eeDRCY gTGgei sc-fXSgeo bnrBiz"><div class="redoc-json"><code><button class="collapser" aria-label="collapse"></button><span class="token punctuation">{</span><span class="ellipsis"></span><ul class="obj collapsible"><li><div class="hoverable "><span class="property token string">"detector"</span>: <button class="collapser" aria-label="collapse"></button><span class="token punctuation">{</span><span class="ellipsis"></span><ul class="obj collapsible"><li><div class="hoverable collapsed"><span class="property token string">"state"</span>: <span class="token string">&quot;Idle&quot;</span><span class="token punctuation">,</span></div></li><li><div class="hoverable collapsed"><span class="property token string">"powerchip"</span>: <span class="token string">&quot;PowerOn&quot;</span><span class="token punctuation">,</span></div></li><li><div class="hoverable collapsed"><span class="property token string">"server_version"</span>: <span class="token string">&quot;string&quot;</span><span class="token punctuation">,</span></div></li><li><div class="hoverable collapsed"><span class="property token string">"number_of_triggers_left"</span>: <span class="token number">0</span><span class="token punctuation">,</span></div></li><li><div class="hoverable collapsed"><span class="property token string">"fpga_temp_degC"</span>: <button class="collapser" aria-label="expand"></button><span class="token punctuation">[</span><span class="ellipsis"></span><ul class="array collapsible"><li><div class="hoverable collapsed"><span class="token number">0</span></div></li></ul><span class="token punctuation">]</span><span class="token punctuation">,</span></div></li><li><div class="hoverable collapsed"><span class="property token string">"high_voltage_V"</span>: <button class="collapser" aria-label="expand"></button><span class="token punctuation">[</span><span class="ellipsis"></span><ul class="array collapsible"><li><div class="hoverable collapsed"><span class="token number">0</span></div></li></ul><span class="token punctuation">]</span></div></li></ul><span class="token punctuation">}</span><span class="token punctuation">,</span></div></li><li><div class="hoverable "><span class="property token string">"detector_list"</span>: <button class="collapser" aria-label="collapse"></button><span class="token punctuation">{</span><span class="ellipsis"></span><ul class="obj collapsible"><li><div class="hoverable collapsed"><span class="property token string">"detectors"</span>: <button class="collapser" aria-label="expand"></button><span class="token punctuation">[</span><span class="ellipsis"></span><ul class="array collapsible"><li><div class="hoverable collapsed"><button class="collapser" aria-label="expand"></button><span class="token punctuation">{</span><span class="ellipsis"></span><ul class="obj collapsible"><li><div class="hoverable collapsed"><span class="property token string">"id"</span>: <span class="token number">0</span><span class="token punctuation">,</span></div></li><li><div class="hoverable collapsed"><span class="property token string">"description"</span>: <span class="token string">&quot;JUNGFRAU 4 Mpixel&quot;</span><span class="token punctuation">,</span></div></li><li><div class="hoverable collapsed"><span class="property token string">"serial_number"</span>: <span class="token string">&quot;JF17T16V01&quot;</span><span class="token punctuation">,</span></div></li><li><div class="hoverable collapsed"><span class="property token string">"base_ipv4_addr"</span>: <span class="token string">&quot;10.10.10.1&quot;</span><span class="token punctuation">,</span></div></li><li><div class="hoverable collapsed"><span class="property token string">"udp_interface_count"</span>: <span class="token number">2</span><span class="token punctuation">,</span></div></li><li><div class="hoverable collapsed"><span class="property token string">"nmodules"</span>: <span class="token number">18</span><span class="token punctuationLine truncated
</div><div tabindex="0" role="button"><div class="sc-kWtpeL gEncxT"><span>http://localhost:5232</span>/statistics</div></div></div></div></div><div><h3 class="sc-kpDqfm eBBgSB"> <!-- -->Response samples<!-- --> </h3><div class="sc-bXCLTC dHowgL" data-rttabs="true"><ul class="react-tabs__tab-list" role="tablist"><li class="tab-success react-tabs__tab--selected" role="tab" id="tab_R_jiqa_0" aria-selected="true" aria-disabled="false" aria-controls="panel_R_jiqa_0" tabindex="0" data-rttab="true">200</li></ul><div class="react-tabs__tab-panel react-tabs__tab-panel--selected" role="tabpanel" id="panel_R_jiqa_0" aria-labelledby="tab_R_jiqa_0"><div><div class="sc-bbSZdi gCVTxk"><span class="sc-fjvvzt jWReSk">Content type</span><div class="sc-JrDLc iTKzPJ">application/json</div></div><div class="sc-uVWWZ gQROPU"><div class="sc-esYiGF dWQNJI"><div class="sc-koXPp efufqz"><button><div class="sc-fhzFiK kwZDms">Copy</div></button><button> Expand all </button><button> Collapse all </button></div><div tabindex="0" class="sc-eeDRCY gTGgei sc-fXSgeo bnrBiz"><div class="redoc-json"><code><button class="collapser" aria-label="collapse"></button><span class="token punctuation">{</span><span class="ellipsis"></span><ul class="obj collapsible"><li><div class="hoverable "><span class="property token string">"detector"</span>: <button class="collapser" aria-label="collapse"></button><span class="token punctuation">{</span><span class="ellipsis"></span><ul class="obj collapsible"><li><div class="hoverable collapsed"><span class="property token string">"state"</span>: <span class="token string">&quot;Idle&quot;</span><span class="token punctuation">,</span></div></li><li><div class="hoverable collapsed"><span class="property token string">"powerchip"</span>: <span class="token string">&quot;PowerOn&quot;</span><span class="token punctuation">,</span></div></li><li><div class="hoverable collapsed"><span class="property token string">"server_version"</span>: <span class="token string">&quot;string&quot;</span><span class="token punctuation">,</span></div></li><li><div class="hoverable collapsed"><span class="property token string">"number_of_triggers_left"</span>: <span class="token number">0</span><span class="token punctuation">,</span></div></li><li><div class="hoverable collapsed"><span class="property token string">"fpga_temp_degC"</span>: <button class="collapser" aria-label="expand"></button><span class="token punctuation">[</span><span class="ellipsis"></span><ul class="array collapsible"><li><div class="hoverable collapsed"><span class="token number">0</span></div></li></ul><span class="token punctuation">]</span><span class="token punctuation">,</span></div></li><li><div class="hoverable collapsed"><span class="property token string">"high_voltage_V"</span>: <button class="collapser" aria-label="expand"></button><span class="token punctuation">[</span><span class="ellipsis"></span><ul class="array collapsible"><li><div class="hoverable collapsed"><span class="token number">0</span></div></li></ul><span class="token punctuation">]</span></div></li></ul><span class="token punctuation">}</span><span class="token punctuation">,</span></div></li><li><div class="hoverable "><span class="property token string">"detector_list"</span>: <button class="collapser" aria-label="collapse"></button><span class="token punctuation">{</span><span class="ellipsis"></span><ul class="obj collapsible"><li><div class="hoverable collapsed"><span class="property token string">"detectors"</span>: <button class="collapser" aria-label="expand"></button><span class="token punctuation">[</span><span class="ellipsis"></span><ul class="array collapsible"><li><div class="hoverable collapsed"><button class="collapser" aria-label="expand"></button><span class="token punctuation">{</span><span class="ellipsis"></span><ul class="obj collapsible"><li><div class="hoverable collapsed"><span class="property token string">"id"</span>: <span class="token number">0</span><span class="token punctuation">,</span></div></li><li><div class="hoverable collapsed"><span class="property token string">"description"</span>: <span class="token string">&quot;JUNGFRAU 4 Mpixel&quot;</span><span class="token punctuation">,</span></div></li><li><div class="hoverable collapsed"><span class="property token string">"serial_number"</span>: <span class="token string">&quot;JF17T16V01&quot;</span><span class="token punctuation">,</span></div></li><li><div class="hoverable collapsed"><span class="property token string">"base_ipv4_addr"</span>: <span class="token string">&quot;10.10.10.1&quot;</span><span class="token punctuation">,</span></div></li><li><div class="hoverable collapsed"><span class="property token string">"udp_interface_count"</span>: <span class="token number">2</span><span class="token punctuation">,</span></div></li><li><div class="hoverable collapsed"><span class="property token string">"nmodules"</span>: <span class="token number">18</span><span class="token punctuationLine truncated
</div></div><div><h3 class="sc-fMMURN egoxtT">Responses</h3><div><button class="sc-kzqdkY jgSwKD"><svg class="sc-cwHptR hWEnWx" version="1.1" viewBox="0 0 24 24" x="0" xmlns="http://www.w3.org/2000/svg" y="0" aria-hidden="true"><polygon points="17.3 8.3 12 13.6 6.7 8.3 5.3 9.7 12 16.4 18.7 9.7 "></polygon></svg><strong class="sc-dSIIpw bpEYcE">200<!-- --> </strong><div class="sc-eeDRCY sc-eBMEME sc-dCFHLb gTGgei kekOtA kCaLQd"><p>Everything OK</p>
</div></button></div><div><button class="sc-kzqdkY gnmLmb" disabled=""><strong class="sc-dSIIpw bpEYcE">404<!-- --> </strong><div class="sc-eeDRCY sc-eBMEME sc-dCFHLb gTGgei kekOtA kCaLQd"><p>No data collection performed so far</p>
</div></button></div></div></div><div class="sc-iGgWBj sc-gsFSXq ibAZSi eDeKjd"><div class="sc-ejfMa-d bNUPQg"><button class="sc-EgOXT cFEcOl"><span type="get" class="sc-eZYNyq qGfV http-verb get">get</span><span class="sc-iEXKAA gUNSDu">/statistics/data_collection</span><svg class="sc-cwHptR iVFMLx" style="margin-right:-25px" version="1.1" viewBox="0 0 24 24" x="0" xmlns="http://www.w3.org/2000/svg" y="0" aria-hidden="true"><polygon points="17.3 8.3 12 13.6 6.7 8.3 5.3 9.7 12 16.4 18.7 9.7 "></polygon></svg></button><div aria-hidden="true" class="sc-dlWCHZ kWacYr"><div class="sc-hHOBiw cndTNO"><div class="sc-eeDRCY sc-eBMEME gTGgei fbXBig"><p>Test Jungfraujoch system</p>
@@ -1073,7 +1079,7 @@ then image might be replaced in the buffer between calling /images and /image.cb
</div></button></div></div></div><div class="sc-iGgWBj sc-gsFSXq ibAZSi eDeKjd"><div class="sc-ejfMa-d bNUPQg"><button class="sc-EgOXT cFEcOl"><span type="get" class="sc-eZYNyq qGfV http-verb get">get</span><span class="sc-iEXKAA gUNSDu">/version</span><svg class="sc-cwHptR iVFMLx" style="margin-right:-25px" version="1.1" viewBox="0 0 24 24" x="0" xmlns="http://www.w3.org/2000/svg" y="0" aria-hidden="true"><polygon points="17.3 8.3 12 13.6 6.7 8.3 5.3 9.7 12 16.4 18.7 9.7 "></polygon></svg></button><div aria-hidden="true" class="sc-dlWCHZ kWacYr"><div class="sc-hHOBiw cndTNO"><div class="sc-eeDRCY sc-eBMEME gTGgei fbXBig"><p>Test Jungfraujoch system</p>
</div><div tabindex="0" role="button"><div class="sc-kWtpeL gEncxT"><span>http://localhost:5232</span>/version</div></div></div></div></div></div></div></div></div><div class="sc-dExYaf gZbfaQ"></div></div></div>
<script>
const __redoc_state = {"menu":{"activeItemIdx":-1},"spec":{"data":{"openapi":"3.0.3","info":{"title":"Jungfraujoch","description":"API to control Jungfraujoch developed by the Paul Scherrer Institute (Switzerland).\nJungfraujoch is a data acquisition and analysis system for pixel array detectors, primarly PSI JUNGFRAU.\nJungfraujoch uses FPGA boards to acquire data at high data rates.\n\n# License Clarification\n\nWhile this API definition is licensed under GPL-3.0, **the GPL copyleft provisions do not apply**\nwhen this file is used solely to generate OpenAPI clients or when implementing applications that\ninteract with the API. Generated client code and applications using this API definition are not\nsubject to the GPL license requirements and may be distributed under terms of your choosing.\n\nThis exception is similar in spirit to the Linux Kernel's approach to userspace API headers and\nthe GCC Runtime Library Exception. The Linux Kernel developers have explicitly stated that\nuser programs that merely use the kernel interfaces (syscalls, ioctl definitions, etc.) are not\nderivative works of the kernel and are not subject to the terms of the GPL.\n\nThis exception is intended to allow wider use of this API specification without imposing GPL\nrequirements on applications that merely interact with the API, regardless of whether they\ncommunicate through network calls or other mechanisms.\n","version":"1.0.0-rc.167","contact":{"name":"Filip Leonarski (Paul Scherrer Institute)","email":"filip.leonarski@psi.ch"},"license":{"name":"GPL-3.0","url":"https://www.gnu.org/licenses/gpl-3.0.html"}},"servers":[{"url":"http://localhost:5232","description":"Test Jungfraujoch system"}],"components":{"parameters":{"binning":{"in":"query","name":"binning","required":false,"schema":{"default":1,"type":"integer"},"description":"Binning of frames for the plot (0 = default binning)"},"experimental_coord":{"in":"query","name":"experimental_coord","required":false,"schema":{"type":"boolean","default":false},"description":"If measurement has goniometer axis defined, plot X-axis will represent rotation angle\nIf measurement has grid scan defined, plot X-axis and Y-axis will represent grid position, Z will be used as the final value\nFor still measurement the number is ignored\n"},"azint_unit":{"in":"query","name":"azint_unit","required":false,"schema":{"type":"string","enum":["Q_recipA","d_A","two_theta_deg"],"default":"Q_recipA"},"description":"Unit used for azim int.\n"},"fill_value":{"in":"query","name":"fill","required":false,"schema":{"type":"number","format":"float"},"description":"Fill value for elements that were missed during data collection\n"},"plot_type":{"in":"query","name":"type","required":true,"description":"Type of requested plot","schema":{"type":"string","enum":["bkg_estimate","spindle_blind_fraction","azint","azint_1d","spot_count","spot_count_low_res","spot_count_indexed","spot_count_ice","indexing_rate","indexing_lattice_count","indexing_unit_cell_length","indexing_unit_cell_angle","profile_radius","mosaicity","b_factor","error_pixels","saturated_pixels","image_collection_efficiency","receiver_delay","receiver_free_send_buf","strong_pixels","roi_sum","roi_mean","roi_max_count","roi_pixels","roi_weighted_x","roi_weighted_y","packets_received","max_pixel_value","resolution_estimate","pixel_sum","processing_time","beam_center_x","beam_center_y","integrated_reflections","image_scale_factor","image_scale_cc","compression_ratio","ice_ring_ratio","ice_ring_score","protein_score","ice_score"]}},"roi":{"in":"query","name":"roi","required":false,"schema":{"type":"string","minLength":1},"description":"Name of ROI for which plot is requested"},"image_id":{"in":"query","name":"id","required":false,"schema":{"type":"integer","format":"int64","default":-1,"minimum":-2},"description":"Image ID in the image buffer. Special values: -1 - last image in the buffer, -2: last indexed image in the buffer"},"saturation":{"in":"query","name":"saturation","required":false,"schema":{"type":"number","format":"float","minimum":-32767,"maximum":32767},"description":"Saturation value to set contrast in the preview image; if not provided, then autocontrast procedure is used"},"background":{"in":"query","name":"background","required":false,"schema":{"type":"number","format":"float","default":0,"minimum":-32767,"maximum":32767},"description":"Background value to set contrast in the preview image"},"show_spots":{"in":"query","name":"show_spots","schema":{"type":"boolean","default":true},"description":"Show spot finding results on the image"},"show_predictions":{"in":"query","name":"show_predictions","schema":{"type":"boolean","default":false},"description":"Show Bragg spot predictions on the image (if available for the image)"},"show_beam_center":{"in":"query","name":"show_beam_center","schema":{"type":"boolean","default":true},"description":"Show beam center on the image"},"show_roi":{"in":"query","name":"show_roi","schema":{"type":"bLine truncated
const __redoc_state = {"menu":{"activeItemIdx":-1},"spec":{"data":{"openapi":"3.0.3","info":{"title":"Jungfraujoch","description":"API to control Jungfraujoch developed by the Paul Scherrer Institute (Switzerland).\nJungfraujoch is a data acquisition and analysis system for pixel array detectors, primarly PSI JUNGFRAU.\nJungfraujoch uses FPGA boards to acquire data at high data rates.\n\n# License Clarification\n\nWhile this API definition is licensed under GPL-3.0, **the GPL copyleft provisions do not apply**\nwhen this file is used solely to generate OpenAPI clients or when implementing applications that\ninteract with the API. Generated client code and applications using this API definition are not\nsubject to the GPL license requirements and may be distributed under terms of your choosing.\n\nThis exception is similar in spirit to the Linux Kernel's approach to userspace API headers and\nthe GCC Runtime Library Exception. The Linux Kernel developers have explicitly stated that\nuser programs that merely use the kernel interfaces (syscalls, ioctl definitions, etc.) are not\nderivative works of the kernel and are not subject to the terms of the GPL.\n\nThis exception is intended to allow wider use of this API specification without imposing GPL\nrequirements on applications that merely interact with the API, regardless of whether they\ncommunicate through network calls or other mechanisms.\n","version":"1.0.0-rc.167","contact":{"name":"Filip Leonarski (Paul Scherrer Institute)","email":"filip.leonarski@psi.ch"},"license":{"name":"GPL-3.0","url":"https://www.gnu.org/licenses/gpl-3.0.html"}},"servers":[{"url":"http://localhost:5232","description":"Test Jungfraujoch system"}],"components":{"parameters":{"binning":{"in":"query","name":"binning","required":false,"schema":{"default":1,"type":"integer"},"description":"Binning of frames for the plot (0 = default binning)"},"experimental_coord":{"in":"query","name":"experimental_coord","required":false,"schema":{"type":"boolean","default":false},"description":"If measurement has goniometer axis defined, plot X-axis will represent rotation angle\nIf measurement has grid scan defined, plot X-axis and Y-axis will represent grid position, Z will be used as the final value\nFor still measurement the number is ignored\n"},"azint_unit":{"in":"query","name":"azint_unit","required":false,"schema":{"type":"string","enum":["Q_recipA","d_A","two_theta_deg"],"default":"Q_recipA"},"description":"Unit used for azim int.\n"},"fill_value":{"in":"query","name":"fill","required":false,"schema":{"type":"number","format":"float"},"description":"Fill value for elements that were missed during data collection\n"},"plot_type":{"in":"query","name":"type","required":true,"description":"Type of requested plot","schema":{"type":"string","enum":["bkg_estimate","spindle_blind_fraction","azint","azint_1d","spot_count","spot_count_low_res","spot_count_indexed","spot_count_ice","indexing_rate","indexing_lattice_count","indexing_unit_cell_length","indexing_unit_cell_angle","profile_radius","mosaicity","b_factor","error_pixels","saturated_pixels","image_collection_efficiency","receiver_delay","receiver_free_send_buf","strong_pixels","roi_sum","roi_mean","roi_max_count","roi_pixels","roi_weighted_x","roi_weighted_y","packets_received","max_pixel_value","resolution_estimate","pixel_sum","processing_time","beam_center_x","beam_center_y","integrated_reflections","image_scale_factor","image_scale_cc","compression_ratio","ice_ring_ratio","ice_ring_score","protein_score","ice_score"]}},"roi":{"in":"query","name":"roi","required":false,"schema":{"type":"string","minLength":1},"description":"Name of ROI for which plot is requested"},"image_id":{"in":"query","name":"id","required":false,"schema":{"type":"integer","format":"int64","default":-1,"minimum":-2},"description":"Image ID in the image buffer. Special values: -1 - last image in the buffer, -2: last indexed image in the buffer"},"saturation":{"in":"query","name":"saturation","required":false,"schema":{"type":"number","format":"float","minimum":-32767,"maximum":32767},"description":"Saturation value to set contrast in the preview image; if not provided, then autocontrast procedure is used"},"background":{"in":"query","name":"background","required":false,"schema":{"type":"number","format":"float","default":0,"minimum":-32767,"maximum":32767},"description":"Background value to set contrast in the preview image"},"show_spots":{"in":"query","name":"show_spots","schema":{"type":"boolean","default":true},"description":"Show spot finding results on the image"},"show_predictions":{"in":"query","name":"show_predictions","schema":{"type":"boolean","default":false},"description":"Show Bragg spot predictions on the image (if available for the image)"},"show_beam_center":{"in":"query","name":"show_beam_center","schema":{"type":"boolean","default":true},"description":"Show beam center on the image"},"show_roi":{"in":"query","name":"show_roi","schema":{"type":"bLine truncated
var container = document.getElementById('redoc');
Redoc.hydrate(__redoc_state, container);
@@ -7,9 +7,10 @@ Settings for analysis mode Grid and nothing else: how the per-image protein scor
Name | Type | Description | Notes
------------ | ------------- | ------------- | -------------
**protein_score_threshold** | **float** | A raster cell counts as protein above this. The per-image protein score saturates, so this only has to separate \&quot;something diffracted here\&quot; from \&quot;nothing did\&quot;. | [default to 0.5]
**grow_score_threshold** | **float** | A patch is grown out to this score once it has started, so a crystal is not broken in two by a single cell that fell just under protein_score_threshold. Growth can never start on its own - a patch that never reaches the seed threshold is discarded - so lowering this cannot turn weak background into a crystal. | [default to 0.35]
**min_blob_cells** | **int** | How many cells above that threshold make a shape rather than a coincidence. Two cells can be the two ends of a single hit lying on a cell boundary; three is the smallest patch that is not. | [default to 3]
**decisive_single_cell_score** | **float** | ...unless one cell on its own is decisive. The rule above is about coincidences, and a lone cell scoring near the top of a saturating score is not one - a crystal smaller than the grid step lights exactly one cell, and refusing it would lose precisely the samples a fine raster is run to find. Set well above protein_score_threshold: this admits the obvious case, it does not lower the general threshold by the back door. | [default to 0.9]
**max_crystals** | **int** | Most crystals reported. A raster over a loop full of shards can label dozens of blobs, and past the first few the list is no longer a ranking anyone acts on. Crystals are sorted by score, so this keeps the best. | [default to 10]
**decisive_single_cell_score** | **float** | ...unless one cell on its own is decisive. The rule above is about coincidences, and a lone cell scoring near the top of a saturating score is not one - a crystal smaller than the grid step lights exactly one cell, and refusing it would lose precisely the samples a fine raster is run to find. The bar is the patch PEAK, not its mean. 0.6 is measured: over 67 labelled rasters the peak-score populations do not overlap - no water raster reaches 0.15 and no ice raster 0.50, while the weakest confirmed-protein raster peaks at 0.67 - so 0.6 is the middle of that gap. | [default to 0.6]
**max_crystals** | **int** | Most crystals reported, best first. ABSENT MEANS NO CAP, which is the default: a crystal that was found and then dropped is information the caller cannot get back. Set it where a loop full of shards would otherwise label dozens of blobs that nobody acts on. | [optional]
**indexing** | **bool** | Whether each raster cell is indexed as well as scored. On by default: a raster runs at up to 100 Hz, which the FFT indexer keeps up with, and it is additive - blobs are still found on the protein score, so indexing changes nothing about which cells are called crystals and only adds what was found in them. The lattice count per cell is the cheapest multi-lattice or cracked-crystal signal there is, and on a fixed-target serial experiment with a known cell a raster that indexes is most of the measurement. Turn it off for a very large raster where the GPU is the constraint. | [default to True]
## Example
+16 -6
View File
@@ -2022,6 +2022,14 @@ export type grid_scan_analysis_settings = {
*
*/
protein_score_threshold: number;
/**
* A patch is grown out to this score once it has started, so a crystal is not broken in two
* by a single cell that fell just under protein_score_threshold. Growth can never start on
* its own - a patch that never reaches the seed threshold is discarded - so lowering this
* cannot turn weak background into a crystal.
*
*/
grow_score_threshold: number;
/**
* How many cells above that threshold make a shape rather than a coincidence. Two cells can
* be the two ends of a single hit lying on a cell boundary; three is the smallest patch that
@@ -2033,18 +2041,20 @@ export type grid_scan_analysis_settings = {
* ...unless one cell on its own is decisive. The rule above is about coincidences, and a
* lone cell scoring near the top of a saturating score is not one - a crystal smaller than
* the grid step lights exactly one cell, and refusing it would lose precisely the samples a
* fine raster is run to find. Set well above protein_score_threshold: this admits the
* obvious case, it does not lower the general threshold by the back door.
* fine raster is run to find. The bar is the patch PEAK, not its mean.
* 0.6 is measured: over 67 labelled rasters the peak-score populations do not overlap - no
* water raster reaches 0.15 and no ice raster 0.50, while the weakest confirmed-protein
* raster peaks at 0.67 - so 0.6 is the middle of that gap.
*
*/
decisive_single_cell_score: number;
/**
* Most crystals reported. A raster over a loop full of shards can label dozens of blobs, and
* past the first few the list is no longer a ranking anyone acts on. Crystals are sorted by
* score, so this keeps the best.
* Most crystals reported, best first. ABSENT MEANS NO CAP, which is the default: a crystal
* that was found and then dropped is information the caller cannot get back. Set it where a
* loop full of shards would otherwise label dozens of blobs that nobody acts on.
*
*/
max_crystals: number;
max_crystals?: number;
/**
* Whether each raster cell is indexed as well as scored. On by default: a raster runs at up
* to 100 Hz, which the FFT indexer keeps up with, and it is additive - blobs are still found
+3 -2
View File
@@ -886,9 +886,10 @@ export const zCalibrationSettings = z.object({
*/
export const zGridScanAnalysisSettings = z.object({
protein_score_threshold: z.number().gte(0).lte(1).default(0.5),
grow_score_threshold: z.number().gte(0).lte(1).default(0.35),
min_blob_cells: z.coerce.bigint().gte(BigInt(1)).max(BigInt('9223372036854775807'), { error: 'Invalid value: Expected int64 to be <= 9223372036854775807' }).default(BigInt(3)),
decisive_single_cell_score: z.number().gte(0).lte(1).default(0.9),
max_crystals: z.coerce.bigint().gte(BigInt(1)).max(BigInt('9223372036854775807'), { error: 'Invalid value: Expected int64 to be <= 9223372036854775807' }).default(BigInt(10)),
decisive_single_cell_score: z.number().gte(0).lte(1).default(0.6),
max_crystals: z.coerce.bigint().gte(BigInt(1)).max(BigInt('9223372036854775807'), { error: 'Invalid value: Expected int64 to be <= 9223372036854775807' }).optional(),
indexing: z.boolean().default(true)
});
+16 -12
View File
@@ -73,7 +73,7 @@ std::string RenderRasterReport(const std::string &input_file,
const RasterSettings &settings,
const RunProvenance &provenance) {
std::ostringstream os;
const ScanSummary summary = Summarize(scan, settings.analysis.protein_score_threshold);
const ScanSummary summary = Summarize(scan, settings.analysis.GetProteinScoreThreshold());
os << BANNER << "\n"
<< " RUGNUX RASTER REPORT\n"
@@ -122,11 +122,12 @@ std::string RenderRasterReport(const std::string &input_file,
<< " ICE_ABOVE_THRESHOLD counts the cells whose ICE score passes the protein threshold - the one\n"
<< " number the run already has, rather than a second one invented for ice - so it says how much\n"
<< " of the loop is ice rather than sample.\n\n";
Key(os, "PROTEIN_SCORE_THRESHOLD", fmt::format("{:.2f}", settings.analysis.protein_score_threshold));
Key(os, "GROW_SCORE_THRESHOLD", fmt::format("{:.2f}", settings.analysis.grow_score_threshold));
Key(os, "MIN_BLOB_CELLS", settings.analysis.min_blob_cells);
Key(os, "DECISIVE_PROTEIN_SCORE", fmt::format("{:.2f}", settings.analysis.decisive_protein_score));
Key(os, "MAX_CRYSTALS", settings.analysis.max_crystals);
Key(os, "PROTEIN_SCORE_THRESHOLD", fmt::format("{:.2f}", settings.analysis.GetProteinScoreThreshold()));
Key(os, "GROW_SCORE_THRESHOLD", fmt::format("{:.2f}", settings.analysis.GetGrowScoreThreshold()));
Key(os, "MIN_BLOB_CELLS", settings.analysis.GetMinBlobCells());
Key(os, "DECISIVE_PROTEIN_SCORE", fmt::format("{:.2f}", settings.analysis.GetDecisiveSingleCellScore()));
Key(os, "MAX_CRYSTALS", settings.analysis.GetMaxCrystals()
? std::to_string(*settings.analysis.GetMaxCrystals()) : std::string("none"));
Key(os, "IMAGES_SCORED", summary.scored);
Key(os, "IMAGES_ABOVE_THRESHOLD", summary.above);
Key(os, "FRACTION_ABOVE_THRESHOLD", fmt::format("{:.4f}", Fraction(summary.above, summary.scored)));
@@ -173,7 +174,7 @@ std::string RenderRasterJson(const std::string &input_file,
const GridScanResult &crystals,
const RasterSettings &settings,
const RunProvenance &provenance) {
const ScanSummary summary = Summarize(scan, settings.analysis.protein_score_threshold);
const ScanSummary summary = Summarize(scan, settings.analysis.GetProteinScoreThreshold());
nlohmann::json out;
out["raster_report_version"] = RASTER_REPORT_VERSION;
@@ -200,11 +201,14 @@ std::string RenderRasterJson(const std::string &input_file,
out["grid"] = g;
nlohmann::json s;
s["protein_score_threshold"] = settings.analysis.protein_score_threshold;
s["grow_score_threshold"] = settings.analysis.grow_score_threshold;
s["min_blob_cells"] = settings.analysis.min_blob_cells;
s["decisive_protein_score"] = settings.analysis.decisive_protein_score;
s["max_crystals"] = settings.analysis.max_crystals;
s["protein_score_threshold"] = settings.analysis.GetProteinScoreThreshold();
s["grow_score_threshold"] = settings.analysis.GetGrowScoreThreshold();
s["min_blob_cells"] = settings.analysis.GetMinBlobCells();
s["decisive_protein_score"] = settings.analysis.GetDecisiveSingleCellScore();
if (const auto cap = settings.analysis.GetMaxCrystals())
s["max_crystals"] = *cap;
else
s["max_crystals"] = nullptr;
s["beam_size_x_um"] = settings.beam_size_x_um;
s["beam_size_y_um"] = settings.beam_size_y_um;
s["beam_size_source"] = settings.beam_size_source;
+8 -2
View File
@@ -2005,7 +2005,11 @@ ProcessResult Rugnux::RunPipeline(RugnuxObserver *observer, bool write_output, b
// all, which is the one hypothesis that survives a header the profile cannot correct.
const bool calibration = (config_.mode == AnalysisMode::PowderCalibration);
const bool calibration_spots = calibration && config_.calibration_method == CalibrationMethod::Spots;
const bool per_image_analysis = full || calibration;
// Whether the per-image spot engine runs at all. Asked of the stages table rather than of the
// mode, because three different modes need it for three different reasons - MX to index and
// integrate, powder calibration to place the beam centre from the ring spots, and Grid to score
// every cell - and a fourth would otherwise have to be remembered here as well.
const bool per_image_analysis = AnalysisModeStages(config_.mode).spot_finding;
const bool write_files = write_output && !config_.output_prefix.empty();
// Output/runtime invariants. Algorithm settings (indexing, scaling, integration, polarization,
@@ -2139,7 +2143,9 @@ ProcessResult Rugnux::RunPipeline(RugnuxObserver *observer, bool write_output, b
}
const char *mode_name = full ? "full analysis"
: calibration ? "powder calibration" : "azimuthal integration";
: calibration ? "powder calibration"
: config_.mode == AnalysisMode::Grid ? "grid scan"
: "azimuthal integration";
logger.Info("Processing {} images (range {}-{}, stride {}) using {} threads [{}]",
images_to_process, start_image, end_image, config_.stride, config_.nthreads, mode_name);
LogXDSGeometry(experiment_);
+1 -1
View File
@@ -2180,7 +2180,7 @@ static int RunRugnux(int argc, char **argv) {
raster_settings.beam_size_y_um = beam_size_y_um.value_or(0.0f);
ProcessConfig config;
config.mode = ProcessMode::FullAnalysis;
config.mode = AnalysisMode::Grid;
config.start_image = start_image;
config.end_image = end_image;
config.stride = image_stride;
+2 -1
View File
@@ -87,7 +87,8 @@ TEST_CASE("AnalysisMode_GridScanSettingsDefaults", "[AnalysisMode]") {
// otherwise the decisive rule would just be a lower general threshold.
CHECK(s.GetDecisiveSingleCellScore() > s.GetProteinScoreThreshold());
CHECK(s.GetMinBlobCells() >= 1);
CHECK(s.GetMaxCrystals() >= 1);
// No cap by default: a crystal found and then dropped cannot be recovered by the caller.
CHECK_FALSE(s.GetMaxCrystals().has_value());
GridScanAnalysisSettings set;
set.ProteinScoreThreshold(0.7f).MinBlobCells(5).DecisiveSingleCellScore(0.95f)
+6 -5
View File
@@ -72,7 +72,8 @@ TEST_CASE("RasterReport_Render", "[Diagnostics]") {
CHECK(report.find("GROW_SCORE_THRESHOLD= 0.35\n") != std::string::npos);
CHECK(report.find("MIN_BLOB_CELLS= 3\n") != std::string::npos);
CHECK(report.find("DECISIVE_PROTEIN_SCORE= 0.60\n") != std::string::npos);
CHECK(report.find("MAX_CRYSTALS= 0\n") != std::string::npos);
// Unset means no cap; "0" would read as "report no crystals".
CHECK(report.find("MAX_CRYSTALS= none\n") != std::string::npos);
CHECK(report.find("CRYSTAL_COUNT= 1\n") != std::string::npos);
CHECK(report.find("END OF REPORT") != std::string::npos);
}
@@ -196,7 +197,7 @@ TEST_CASE("RasterReport_ThreeCrystalsAndTheCap", "[Diagnostics]") {
CHECK(all.crystals[2].score == Catch::Approx(0.75).margin(1e-5));
// The cap keeps the strongest, not the first found: the 0.85 patch is the last one in grid order.
settings.analysis.max_crystals = 2;
settings.analysis.MaxCrystals(2);
const GridScanResult capped = AnalyzeGridScan(scan, grid, settings.beam_size_x_um,
settings.beam_size_y_um, settings.analysis);
REQUIRE(capped.crystals.size() == 2);
@@ -225,7 +226,7 @@ TEST_CASE("RasterReport_OneDecisiveCellIsACrystal", "[Diagnostics]") {
// Raise the bar past the one cell that passed and nothing is left; a patch that meets the cell
// minimum is unaffected by the bar, which is what makes this an OR and not a second gate.
settings.analysis.decisive_protein_score = 0.99f;
settings.analysis.DecisiveSingleCellScore(0.99f);
CHECK(AnalyzeGridScan(scan, grid, settings.beam_size_x_um, settings.beam_size_y_um,
settings.analysis).crystals.empty());
@@ -250,7 +251,7 @@ TEST_CASE("RasterReport_HysteresisHealsASplit", "[Diagnostics]") {
CHECK(healed.crystals[0].n_images == 7); // the bridging cell is part of the crystal
// Growing no further than the seed level is the behaviour hysteresis replaced, and it splits.
settings.analysis.grow_score_threshold = settings.analysis.protein_score_threshold;
settings.analysis.GrowScoreThreshold(settings.analysis.GetProteinScoreThreshold());
const GridScanResult split = AnalyzeGridScan(scan, grid, settings.beam_size_x_um,
settings.beam_size_y_um, settings.analysis);
CHECK(split.crystals.size() == 2);
@@ -266,7 +267,7 @@ TEST_CASE("RasterReport_GrowthCannotStartOnItsOwn", "[Diagnostics]") {
CHECK(AnalyzeGridScan(scan, grid, settings.beam_size_x_um, settings.beam_size_y_um,
settings.analysis).crystals.empty());
settings.analysis.grow_score_threshold = 0.05f;
settings.analysis.GrowScoreThreshold(0.05f);
CHECK(AnalyzeGridScan(scan, grid, settings.beam_size_x_um, settings.beam_size_y_um,
settings.analysis).crystals.empty());
}