Skip to content

Commit

Permalink
Finish allowing use of Source.lib files for detector characterization.
Browse files Browse the repository at this point in the history
Added being able to drag-n-drop Source.lib files onto the app while the Make Detector Response tool is open.  If you do this, you can have it auto-populate the source information.
Also added documentation on using these files.
  • Loading branch information
wcjohns committed May 23, 2024
1 parent 667dfdb commit 47bcc6f
Show file tree
Hide file tree
Showing 11 changed files with 493 additions and 84 deletions.
9 changes: 8 additions & 1 deletion InterSpec/InterSpec.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ class PopupDivMenu;
class SimpleDialog;
class EnergyCalTool;
class GammaXsWindow;
class MakeDrfWindow;
class OneOverR2Calc;
class SpectrumChart;
class UseInfoWindow;
Expand Down Expand Up @@ -601,7 +602,12 @@ class InterSpec : public Wt::WContainerWidget
void setToolTabsVisible( bool show );
bool toolTabsVisible() const;

void showMakeDrfWindow();
/** Makes a MakeDrf Window and returns it, or if one was already present, returns it. */
MakeDrfWindow *showMakeDrfWindow();
/** Returns the pointer to current MakeDrf Window. Will by nullptr if not currently showing */
MakeDrfWindow *makeDrfWindow();
void handleCloseMakeDrfWindow( MakeDrfWindow *window );

DrfSelectWindow *showDrfSelectWindow();
void closeDrfSelectWindow();

Expand Down Expand Up @@ -1477,6 +1483,7 @@ class InterSpec : public Wt::WContainerWidget
OneOverR2Calc *m_1overR2Calc;
UnitsConverterTool *m_unitsConverter;
FluxToolWindow *m_fluxTool;
MakeDrfWindow *m_makeDrfTool;


#if( USE_GOOGLE_MAP || USE_LEAFLET_MAP )
Expand Down
30 changes: 23 additions & 7 deletions InterSpec/MakeDrf.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,23 @@ namespace Wt

namespace { class DrfPeak; }

class MakeDrf;
struct SrcLibLineInfo;

/** Create a AuxWindow with the MakeDrf widget as the primary content. */
class MakeDrfWindow : public AuxWindow
{
public:
MakeDrfWindow( InterSpec *viewer,
MaterialDB *materialDB,
Wt::WSuggestionPopup *materialSuggest );

MakeDrf *tool();

protected:
MakeDrf *m_tool;
};//class MakeDrfWindow


class MakeDrf : public Wt::WContainerWidget
{
Expand All @@ -62,13 +79,6 @@ class MakeDrf : public Wt::WContainerWidget

virtual ~MakeDrf();

/** Create a AuxWindow with the MakeDrf widget as the primary content.
Returns pointer to the created AuxWindow, but is will already be shown,
and have the signals to delete it when closed hooked up, so you probably
wont need the window.
*/
static AuxWindow *makeDrfWindow( InterSpec *viewer, MaterialDB *materialDB,
Wt::WSuggestionPopup *materialSuggest );

/** Creates a "Save As..." dialog. If the current DRF is not valid, the
dialog that will pop up will state as such.
Expand Down Expand Up @@ -123,6 +133,12 @@ class MakeDrf : public Wt::WContainerWidget
*/
double detectorDiameter() const;

/** Called when user drag-n-drops a Source.lib onto app.
Auto-populates all sources to the first matching nuclide in the library.
*/
void useSourceLibrary( const std::vector<std::shared_ptr<const SrcLibLineInfo>> &srcs,
const bool auto_populate );
protected:
void handleSourcesUpdates();
void handleSqrtEqnOrderChange();
Expand Down
26 changes: 24 additions & 2 deletions InterSpec/MakeDrfSrcDef.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@

#include <string>
#include <vector>
#include <istream>

#include <boost/date_time/posix_time/posix_time.hpp>

Expand Down Expand Up @@ -110,8 +111,14 @@ struct SrcLibLineInfo
If any field is not valid (except comment can be blank), the line wont be included in the results.
*/
static std::vector<SrcLibLineInfo> sources_in_lib( std::istream &strm );

/** A convenience function for above, that takes a file path, instead of a stream. */
static std::vector<SrcLibLineInfo> sources_in_lib( const std::string &filename );

/** Checks if first valid-ish line is a valid source, and if so, returns true. */
static bool is_candidate_src_lib( std::istream &strm );

/** Grabs sources in all Source.lib files in user and application data directories. */
static std::vector<SrcLibLineInfo> sources_in_all_libs();
};//struct SrcLibLineInfo
Expand Down Expand Up @@ -243,6 +250,13 @@ class MakeDrfSrcDef : public Wt::WContainerWidget
/** Returns the sources defined in Sources.lib, for this nuclide. */
const std::vector<SrcLibLineInfo> &lib_srcs_for_nuc();

/** Adds sources from a Source.lib file to this widget.
\param srcs The sources to add to the menu of `m_lib_src_btn` - only sources matching this sources nuclide will be added.
\param auto_populate If true, then the information will be set for the first matching nuclide found in `srcs`.
*/
void addSourceLibrary( std::vector<std::shared_ptr<const SrcLibLineInfo>> srcs,
const bool auto_populate );
protected:
/** Creates the widget, but doesnt fill out any of the information. */
void create();
Expand Down Expand Up @@ -274,17 +288,19 @@ class MakeDrfSrcDef : public Wt::WContainerWidget
/** Returns user entered activity. Throws exception if invalid. */
double enteredActivity() const;

void updateSourceLibNuclides();

Wt::WTable *m_table;

/** The name of the nuclide this source represents. */
const SandiaDecay::Nuclide *m_nuclide;

/** Pointer to shielding material database, garunteed non-null.
/** Pointer to shielding material database, guaranteed non-null.
Not owned by this object.
*/
MaterialDB *m_materialDB;

/** The material suggestion widget shared everywher within InterSpec.
/** The material suggestion widget shared everywhere within InterSpec.
Not owned by this object.
*/
Wt::WSuggestionPopup *m_materialSuggest;
Expand Down Expand Up @@ -334,6 +350,12 @@ class MakeDrfSrcDef : public Wt::WContainerWidget
/** The sources in Source.lib that are for this nuclide. */
std::vector<SrcLibLineInfo> m_lib_srcs_for_nuc;

/** All sources from Source.lib files found on the device. */
std::vector<SrcLibLineInfo> m_lib_srcs_from_file;

/** Sources added by dragging-n-dropping Source.lib onto app - via `addSourceLibrary(...)` */
std::vector<std::shared_ptr<const SrcLibLineInfo>> m_lib_srcs_added;

/** Button that lets you select sources that might be in Source.lib files */
Wt::WPushButton *m_lib_src_btn;

Expand Down
3 changes: 3 additions & 0 deletions InterSpec/SpecMeasManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,9 @@ class SpecMeasManager : public Wt::WObject
/** Handles the Shielding/Source fit XML file */
bool handleShieldingSourceFile( std::istream &input, SimpleDialog *dialog );

/** Handles Source.lib files dropped onto the app. */
bool handleSourceLibFile( std::istream &input, SimpleDialog *dialog );

/** Handles the user dropping a .ECC file produced from ISOCS. */
bool handleEccFile( std::istream &input, SimpleDialog *dialog );

Expand Down
10 changes: 9 additions & 1 deletion InterSpec_resources/app_text/SpecMeasManager.xml
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,14 @@
<message id="smm-act-shield-use">Use this Activity/Shielding fit setup?</message>
<message id="smm-err-act-shield">Sorry, there was an error loading Activity/Shielding Fit model: {1}</message>

<!-- Text for dialog when user drag-n-drop a Source.lib file onto app, and the Make Detector Response tool is open -->
<message id="smm-source-lib-title">Characterization source library file</message>
<message id="smm-source-source-use">
This will use this Source.lib file in the Make Detector Response tool.
<br />
Would you like to auto-populate sources with first matching nuclide in library?
</message>

<!-- Other errors -->
<message id="smm-upload-timeout">File upload has maybe timed-out - 120 seconds without receiving file data.</message>
<message id="smm-finishing-upload">Finishing upload</message>
Expand Down Expand Up @@ -260,4 +268,4 @@
<message id="smm-qr-sequence-multi">QR Code {1} of {2}</message>
<message id="smm-next-qr">Next QR code</message>

</messages>
</messages>
9 changes: 8 additions & 1 deletion InterSpec_resources/app_text/SpecMeasManager_fr.xml
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,13 @@
<message id="smm-act-shield-use">Utiliser cette configuration d'ajustement Activité/Blindage ?</message>
<message id="smm-err-act-shield">Désolé, il y a eu une erreur lors du chargement du modèle d'ajustement Activité/Blindage : {1}</message>

<message id="smm-source-lib-title">Fichier de bibliothèque de sources de caractérisation</message>
<message id="smm-source-source-use">
Cela utilisera ce fichier Source.lib dans l'outil de création de réponse du détecteur.
<br />
Souhaitez-vous remplir automatiquement les sources avec le premier nucléide correspondant dans la bibliothèque ?
</message>

<message id="smm-upload-timeout">Le téléchargement du fichier a peut-être expiré - 120 secondes sans réception de données de fichier.</message>
<message id="smm-finishing-upload">Finalisation du téléchargement</message>
<message id="smm-finishing-copying">Finalisation de la copie du fichier</message>
Expand Down Expand Up @@ -259,4 +266,4 @@
<message id="smm-qr-sequence-multi">Code QR {1} sur {2}</message>
<message id="smm-next-qr">Code QR suivant</message>

</messages>
</messages>
61 changes: 61 additions & 0 deletions InterSpec_resources/static_text/make_drf_help.xml
Original file line number Diff line number Diff line change
Expand Up @@ -340,6 +340,66 @@ icon will display additional tips for each item in this dialog.
</p>
</div>

<div style="display:table-row">
<h4>Using a Source.lib file to define sources</h4>
If you commonly use the same radioactive check sources to perform detector characterizations,
you can avoid manually entering source information every time you do a characterization, by
defining a <code>Source.lib</code> file, which is a text file that source information for
multiple sources.

<p>
The file is formatted like:
<pre>
[nuclide]_[serial num 1] [activity in bq] [activity reference date] [comment]
[nuclide]_[serial num 2] [activity in bq] [activity reference date] [comment]
...
</pre>
<br />
With a concrete example looking like:
<pre>
22NA_01551910 5.107E+04 25-Aug-2022 West Rad Lab
137Cs_1513a11 8.31E+04 12-Jul-2018 red src, ActivityUncert=8.31E+05
241Am_a5fi451 3.7E+05 02-Jan-2001 ActivityUncert=1.85E+06, Distance=50cm
...
</pre>

<br />
Where the source name (first field of each line) <em>must</em> be a nuclide, followed by an underscore
(no spaces between), followed by source serial/tracking number or similar (with no spaces in it).
<br />
The source activity (second field) is the activity in becquerel, on the date given (third field).
<br />
The fourth field (i.e., the remaining portion of the line) is an optional comment that can describe
the source location, owner, etc. It can also contain expressions, like seen above, that give
activity uncertainty (again, in becquerel), and distance. If you include this optional information
in the comment portion of the line, the information will be auto-filled out into the GUI when the
source is selected.
<br />Spaces or tabs can be used to delimit fields on each line.
</p>


<p>
You can add this text file, named exactly <code>Source.lib</code>, to the
<code>InterSpec</code> user data directory, or the <code>data</code> directory within the
apps distribution -
see &quot;<b>Help</b>&quot;&rarr;&quot;<b>About InterSpec...</b>&quot;&rarr;&quot;<b>Data</b>&quot;
for these locations.
<br />
When this file is found, a small icon, <img src="InterSpec_resources/images/db_small.png" width=16 height=16 />,
will appear in the lower-left area of each source input whose nuclide is defined in <code>Source.lib</code>.
Clicking on this icon will create a popup menu with all sources defined - if you select a source in
this menu, that sources information will be filled out on the input.
</p>
<p>Or, while the &quot;<b>Make Detector Response Function</b>&quot; is open, you can drag-n-drop a
<code>Source.lib</code> file (the name doesn't matter in this case, just the contents must be
formatted as described above) onto <code>InterSpec</code>, in which case you will then be prompted
if you would like to auto-populate this source information into the inputs. If you select &quot;Yes&quot;, the
first matching nuclide in the <code>Source.lib</code> file will be filled out into each input.
If you select &quot;No&quot;, then you can access the added source informations in pop-up menu of
each source.
</p>
</div>

<div style="display: table-row; clear: both;">
<h4>Miscellaneous Information:</h4>
<ul>
Expand Down Expand Up @@ -394,4 +454,5 @@ icon will display additional tips for each item in this dialog.
<div style="clear: both" />
</div>


</div>
47 changes: 44 additions & 3 deletions src/InterSpec.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -428,6 +428,7 @@ InterSpec::InterSpec( WContainerWidget *parent )
m_1overR2Calc( nullptr ),
m_unitsConverter( nullptr ),
m_fluxTool( nullptr ),
m_makeDrfTool( nullptr ),
#if( USE_GOOGLE_MAP || USE_LEAFLET_MAP )
m_mapMenuItem( nullptr ),
#if( USE_LEAFLET_MAP )
Expand Down Expand Up @@ -9280,13 +9281,53 @@ void InterSpec::deleteDoseCalcTool()
}//void deleteDoseCalcTool();


void InterSpec::showMakeDrfWindow()
MakeDrfWindow *InterSpec::showMakeDrfWindow()
{
AuxWindow *window = MakeDrf::makeDrfWindow( this, m_materialDB.get(), m_shieldingSuggestion );
new UndoRedoManager::BlockGuiUndoRedo( window ); // BlockGuiUndoRedo is WObject, so this `new` doesnt leak
assert( !m_makeDrfTool );
if( !m_makeDrfTool )
{
// Disable the "Make Detector Response" Tools menu item
assert( m_toolsMenuPopup );
for( WMenuItem *item : m_toolsMenuPopup->items() )
{
if( item->text().key() == "app-mi-tools-make-drf" )
item->setDisabled( true );
}//for( loop over "Tools" menu items )

m_makeDrfTool = new MakeDrfWindow( this, m_materialDB.get(), m_shieldingSuggestion );
m_makeDrfTool->finished().connect( boost::bind( &InterSpec::handleCloseMakeDrfWindow, this, m_makeDrfTool ) );
new UndoRedoManager::BlockGuiUndoRedo( m_makeDrfTool ); // BlockGuiUndoRedo is WObject, so this `new` doesnt leak
}//if( !m_makeDrfTool )

return m_makeDrfTool;
}//void showDrfSelectWindow()


MakeDrfWindow *InterSpec::makeDrfWindow()
{
return m_makeDrfTool;
}


void InterSpec::handleCloseMakeDrfWindow( MakeDrfWindow *window )
{
assert( window == m_makeDrfTool );
if( !window || (window != m_makeDrfTool) )
return;

// Enable the "Make Detector Response" Tools menu item
assert( m_toolsMenuPopup );
for( WMenuItem *item : m_toolsMenuPopup->items() )
{
if( item->text().key() == "app-mi-tools-make-drf" )
item->setDisabled( false );
}//for( loop over "Tools" menu items )

m_makeDrfTool = nullptr;
AuxWindow::deleteAuxWindow( window );
}//void handleCloseMakeDrfWindow( MakeDrfWindow *window )


DrfSelectWindow *InterSpec::showDrfSelectWindow()
{
auto redu = [this](){
Expand Down
Loading

0 comments on commit 47bcc6f

Please sign in to comment.