Skip to content

Commit 765a477

Browse files
committed
Add so you can drag-n-drop a DRF CSV file (made by InterSpec) onto app and use it.
Also added writing uncertainties to DRF output CSV file, and reading them back in.
1 parent d031eee commit 765a477

File tree

4 files changed

+95
-95
lines changed

4 files changed

+95
-95
lines changed

InterSpec/DetectorEdit.h

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,16 @@ class DetectorEdit : public Wt::WContainerWidget
220220
// on deplandcies)
221221
static std::shared_ptr<DetectorPeakResponse> initARelEffDetector( const SpecUtils::DetectorType type, InterSpec *interspec );
222222

223+
224+
/** Checks if file at passed in path is a TSV/CSV file that contains
225+
coefficients for the exp( c0 + c1*logx + c2*logx^2 + ...) equation.
226+
If so, returns detector. If not, returns nullptr.
227+
228+
ToDo: Currently reads in most of the information exported in the CSV from MakeDrf tool, but maybe not all.
229+
*/
230+
static std::shared_ptr<DetectorPeakResponse> parseRelEffCsvFile( const std::string filePath );
231+
232+
223233
//Callbacks for when detector is changed or modified
224234
void gadrasDetectorSelectCallback();
225235
void relEffDetectorSelectCallback();
@@ -259,23 +269,13 @@ class DetectorEdit : public Wt::WContainerWidget
259269
//a row is selected, so update det and charts
260270
void dbTableSelectionChanged();
261271

272+
262273
protected:
263274
void setAcceptButtonEnabled( const bool enable );
264275

265276
/** Called when user changes value in m_uploadedDetName; sets m_detector name. */
266277
void handleUserChangedUploadedDrfName();
267278

268-
/** Checks if file at passed in path is a TSV/CSV file that contains
269-
coeffeicents for the exp( c0 + c1*logx + c2*logx^2 + ...) equation.
270-
If so, returns detector. If not, returns nullptr.
271-
272-
ToDo: Currently reads in most of the information exported in the CSV from
273-
MakeDrf tool, except the uncertainities - should add this in. Also, need
274-
to cleanup the GUI during loading of this one CSV that has all the info
275-
(def not correct, should hide detector diameter and option to upload
276-
Detector.dat).
277-
*/
278-
static std::shared_ptr<DetectorPeakResponse> checkIfFileIsRelEff( const std::string tsvfilepath );
279279

280280
protected:
281281
WContainerWidget *m_footer;

src/DetectorEdit.cpp

Lines changed: 32 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2663,7 +2663,7 @@ void DetectorEdit::updateChart()
26632663
} //DetectorEdit::updateChart()
26642664

26652665

2666-
std::shared_ptr<DetectorPeakResponse> DetectorEdit::checkIfFileIsRelEff( const std::string filename )
2666+
std::shared_ptr<DetectorPeakResponse> DetectorEdit::parseRelEffCsvFile( const std::string filename )
26672667
{
26682668
#ifdef _WIN32
26692669
const std::wstring wfilename = SpecUtils::convert_from_utf8_to_utf16(filename);
@@ -2716,7 +2716,7 @@ std::shared_ptr<DetectorPeakResponse> DetectorEdit::checkIfFileIsRelEff( const s
27162716

27172717
try
27182718
{
2719-
vector<float> coefs( 8, 0.0f );
2719+
vector<float> coefs( 8, 0.0f ), coef_uncerts;
27202720
for( int i = 0; i < 8; ++i )
27212721
{
27222722
string field = fields.at(3+i);
@@ -2740,9 +2740,36 @@ std::shared_ptr<DetectorPeakResponse> DetectorEdit::checkIfFileIsRelEff( const s
27402740
const string name = (fields[0].empty() ? drfname : fields[0]);
27412741
const float energUnits = ((foundKeV && !foundMeV) ? 1.0f : 1000.0f);
27422742
float lowerEnergy = 0.0f, upperEnergy = 0.0f;
2743+
2744+
// Lets try to get coefs uncertainties
2745+
if( !SpecUtils::safe_get_line(csvfile, line, 2048) )
2746+
{
2747+
try
2748+
{
2749+
vector<string> uncert_strs;
2750+
split_escaped_csv( uncert_strs, line );
2751+
if( !uncert_strs.empty()
2752+
&& SpecUtils::istarts_with(uncert_strs[0], "# 1 sigma Uncert")
2753+
&& (uncert_strs.size() >= (3 + coefs.size())) )
2754+
{
2755+
coef_uncerts.resize( coefs.size(), 0.0f );
2756+
for( int i = 0; i < coefs.size(); ++i )
2757+
{
2758+
string field = uncert_strs.at(3+i);
2759+
coef_uncerts[i] = (field.empty() ? 0.0f : std::stof(field));
2760+
}
2761+
}//if( it looks like we found the uncertainty line )
2762+
}catch( std::exception &e )
2763+
{
2764+
cerr << "Error caught parsing DRF eff uncertainties: " << e.what() << endl;
2765+
coef_uncerts.clear();
2766+
}
2767+
}//if( we got another line we'll check if its the uncertainties )
2768+
2769+
27432770
auto det = std::make_shared<DetectorPeakResponse>( fields[0], drfdescrip );
27442771

2745-
det->fromExpOfLogPowerSeriesAbsEff( coefs, {}, dist, 2.0f*radius, energUnits,
2772+
det->fromExpOfLogPowerSeriesAbsEff( coefs, coef_uncerts, dist, 2.0f*radius, energUnits,
27462773
lowerEnergy, upperEnergy );
27472774

27482775
//Look for the line that gives the appropriate energy range.
@@ -2801,7 +2828,7 @@ std::shared_ptr<DetectorPeakResponse> DetectorEdit::checkIfFileIsRelEff( const s
28012828
}//while( more lines )
28022829

28032830
return nullptr;
2804-
}//checkIfFileIsRelEff(...)
2831+
}//parseRelEffCsvFile(...)
28052832

28062833

28072834

@@ -2855,7 +2882,7 @@ void DetectorEdit::fileUploadedCallback( const UploadCallbackReason context )
28552882
if( !m_efficiencyCsvUpload->empty() )
28562883
{
28572884
const string filename = m_efficiencyCsvUpload->spoolFileName();
2858-
auto det = DetectorEdit::checkIfFileIsRelEff( filename );
2885+
auto det = DetectorEdit::parseRelEffCsvFile( filename );
28592886

28602887
if( det )
28612888
{

src/MakeDrf.cpp

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2864,11 +2864,20 @@ void MakeDrf::writeCsvSummary( std::ostream &out,
28642864
out << "," << ( (i==0 ? log(solidAngleAt25cm) : 0.0) + effEqnCoefs[i]); //todo: make sure its not
28652865
for( size_t i = effEqnCoefs.size(); i < 12; ++i )
28662866
out << ",";
2867-
out << "25," << (0.5*diam/PhysicalUnits::cm) << "," << solidAngleAt25cm << endline
2868-
<< endline
2869-
<< endline;
2867+
out << "25," << (0.5*diam/PhysicalUnits::cm) << "," << solidAngleAt25cm << endline;
2868+
out << "# 1 sigma Uncertainties,";
2869+
if( releffuncert >= 0.0 )
2870+
out << 100*(releffuncert / NaI3x3IntrinsicEff) << "%";
2871+
out << ",";
2872+
for( size_t i = 0; i < effEqnCoefsUncerts.size(); ++i )
2873+
out << "," << effEqnCoefsUncerts[i];
2874+
if( effChi2 > 0 )
2875+
out << endline << "# Chi2 / DOF = " << effChi2 << " / " << (effDof-1)
2876+
<< " = " << (effDof >= 1 ? (effChi2/(effDof-1.0)) : 0.0);
2877+
out << endline << endline;
2878+
28702879

2871-
//Then need to give FWHM equation form and coefficienct, if avaialble.
2880+
//Then need to give FWHM equation form and coefficient, if available.
28722881
if( fwhmCoefs.size() )
28732882
{
28742883
out << "# Full width half maximum (FWHM) follows equation: ";

src/SpecMeasManager.cpp

Lines changed: 39 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,7 @@
108108
#include "InterSpec/HelpSystem.h"
109109
#include "SpecUtils/Filesystem.h"
110110
#include "SpecUtils/StringAlgo.h"
111+
#include "InterSpec/DetectorEdit.h"
111112
#include "InterSpec/SimpleDialog.h"
112113
#include "InterSpec/InterSpecApp.h"
113114
#include "InterSpec/DataBaseUtils.h"
@@ -1273,35 +1274,16 @@ bool SpecMeasManager::handleNonSpectrumFile( const std::string &displayName,
12731274
return (pos != char_end);
12741275
};//header_contains lambda
12751276

1276-
#define USE_SIMPLE_DIALOG_FOR_NOT_SPEC 1
12771277

1278-
#if( USE_SIMPLE_DIALOG_FOR_NOT_SPEC )
12791278
SimpleDialog *dialog = new SimpleDialog();
1280-
dialog->addButton( "Close" );
1279+
WPushButton *closeButton = dialog->addButton( "Close" );
12811280
WGridLayout *stretcher = new WGridLayout();
12821281
stretcher->setContentsMargins( 0, 0, 0, 0 );
12831282
dialog->contents()->setLayout( stretcher );
12841283
WText *title = new WText( "Not a spectrum file" );
12851284
title->addStyleClass( "title" );
12861285
stretcher->addWidget( title, 0, 0 );
12871286

1288-
#else
1289-
1290-
AuxWindow *w = new AuxWindow( "Not a spectrum file",
1291-
(Wt::WFlags<AuxWindowProperties>(AuxWindowProperties::IsModal)
1292-
| AuxWindowProperties::TabletNotFullScreen
1293-
| AuxWindowProperties::SetCloseable
1294-
| AuxWindowProperties::DisableCollapse) );
1295-
w->centerWindow();
1296-
w->rejectWhenEscapePressed( true );
1297-
WPushButton *b = w->addCloseButtonToFooter();
1298-
b->clicked().connect( w, &AuxWindow::hide );
1299-
w->finished().connect( boost::bind( &AuxWindow::deleteAuxWindow, w ) );
1300-
WGridLayout *stretcher = w->stretcher();
1301-
if( !m_viewer->isMobile() && m_viewer->renderedWidth() > 400 && m_viewer->renderedHeight() > 250 )
1302-
w->resize( 400, 250 );
1303-
#endif
1304-
13051287
// const string filename = SpecUtils::filename(displayName);
13061288

13071289
//Check if ICD2 file
@@ -1322,11 +1304,8 @@ bool SpecMeasManager::handleNonSpectrumFile( const std::string &displayName,
13221304
"If you believe this to be a legitimate spectrum file, please email it to <a href=\"mailto:interspec@sandia.gov\" target=\"_blank\">interspec@sandia.gov</a> to support this file type." );
13231305
stretcher->addWidget( t, stretcher->rowCount(), 0, AlignCenter | AlignMiddle );
13241306
t->setTextAlignment( Wt::AlignCenter );
1325-
#if( USE_SIMPLE_DIALOG_FOR_NOT_SPEC )
13261307
dialog->show();
1327-
#else
1328-
w->show();
1329-
#endif
1308+
13301309
return true;
13311310
}
13321311
}//if( might be ICD2 )
@@ -1396,9 +1375,6 @@ bool SpecMeasManager::handleNonSpectrumFile( const std::string &displayName,
13961375
WText *t = new WText( msg );
13971376
stretcher->addWidget( t, stretcher->rowCount(), 0, AlignCenter | AlignMiddle );
13981377
t->setTextAlignment( Wt::AlignCenter );
1399-
#if( !USE_SIMPLE_DIALOG_FOR_NOT_SPEC )
1400-
w->show();
1401-
#endif
14021378

14031379
return true;
14041380
}//if( iszip )
@@ -1413,9 +1389,6 @@ bool SpecMeasManager::handleNonSpectrumFile( const std::string &displayName,
14131389
WText *t = new WText( msg );
14141390
stretcher->addWidget( t, stretcher->rowCount(), 0, AlignCenter | AlignMiddle );
14151391
t->setTextAlignment( Wt::AlignCenter );
1416-
#if( !USE_SIMPLE_DIALOG_FOR_NOT_SPEC )
1417-
w->show();
1418-
#endif
14191392

14201393
return true;
14211394
}//if( israr || istar || iszip7 || isgz )
@@ -1427,9 +1400,6 @@ bool SpecMeasManager::handleNonSpectrumFile( const std::string &displayName,
14271400
WText *t = new WText( msg );
14281401
stretcher->addWidget( t, stretcher->rowCount(), 0, AlignCenter | AlignMiddle );
14291402
t->setTextAlignment( Wt::AlignCenter );
1430-
#if( !USE_SIMPLE_DIALOG_FOR_NOT_SPEC )
1431-
w->show();
1432-
#endif
14331403

14341404
return true;
14351405
}//if( ispdf | isps | istif )
@@ -1458,24 +1428,15 @@ bool SpecMeasManager::handleNonSpectrumFile( const std::string &displayName,
14581428
vector<uint8_t> totaldata( filesize );
14591429
const bool success = infile.read( (char *)&(totaldata[0]), filesize ).good();
14601430

1461-
if( !m_viewer->isMobile() )
1462-
{
1463-
#if( !USE_SIMPLE_DIALOG_FOR_NOT_SPEC )
1464-
w->resize( WLength::Auto, WLength::Auto );
1465-
w->setMaximumSize( 0.6*m_viewer->renderedWidth(), 0.8*m_viewer->renderedHeight() );
1466-
#endif
1467-
}
14681431

14691432
if( success )
14701433
{
14711434
resource->setData( totaldata );
14721435
image->setImageLink( WLink(resource) );
1473-
#if( USE_SIMPLE_DIALOG_FOR_NOT_SPEC )
14741436
const int ww = m_viewer->renderedWidth();
14751437
const int wh = m_viewer->renderedHeight();
14761438
if( (ww > 120) && (wh > 120) )
14771439
image->setMaximumSize( WLength(0.45*ww,WLength::Unit::Pixel), WLength(wh - 120, WLength::Unit::Pixel) );
1478-
#endif
14791440
stretcher->addWidget( image.release(), stretcher->rowCount(), 0, AlignCenter | AlignMiddle );
14801441
}else
14811442
{
@@ -1489,13 +1450,7 @@ bool SpecMeasManager::handleNonSpectrumFile( const std::string &displayName,
14891450
errort->setTextAlignment( Wt::AlignCenter );
14901451
stretcher->addWidget( errort, stretcher->rowCount(), 0, AlignCenter | AlignMiddle );
14911452
}//if( filesize < max_disp_size ) / else
1492-
1493-
#if( !USE_SIMPLE_DIALOG_FOR_NOT_SPEC )
1494-
w->show();
1495-
w->resizeToFitOnScreen();
1496-
w->centerWindowHeavyHanded();
1497-
#endif
1498-
1453+
14991454
return true;
15001455
}//if( isgif || isjpg || ispng || isbmp )
15011456

@@ -1520,11 +1475,8 @@ bool SpecMeasManager::handleNonSpectrumFile( const std::string &displayName,
15201475
orig_peaks, PeakSearchGuiUtils::PeakTemplateFitSrc::CsvFile, seessionid );
15211476
} ) );
15221477

1523-
#if( USE_SIMPLE_DIALOG_FOR_NOT_SPEC )
15241478
delete dialog;
1525-
#else
1526-
delete w;
1527-
#endif
1479+
15281480
return true;
15291481
}catch( exception &e )
15301482
{
@@ -1537,38 +1489,55 @@ bool SpecMeasManager::handleNonSpectrumFile( const std::string &displayName,
15371489
errort->setTextAlignment( Wt::AlignCenter );
15381490
stretcher->addWidget( errort, stretcher->rowCount(), 0, AlignCenter | AlignMiddle );
15391491

1540-
#if( !USE_SIMPLE_DIALOG_FOR_NOT_SPEC )
1541-
w->show();
1542-
w->resizeToFitOnScreen();
1543-
w->centerWindowHeavyHanded();
1544-
#endif
1545-
15461492
return true;
15471493
}//try / catch get candidate peaks )
15481494
}//if( we could possible care about propagating peaks from a CSV file )
15491495

15501496

1551-
/*
15521497
// Check if this is an InterSpec exported DRF CSV
15531498
if( header_contains( "# Detector Response Function" ) )
15541499
{
1555-
auto det = DetectorEdit::checkIfFileIsRelEff( fileLocation );
1500+
shared_ptr<DetectorPeakResponse> det = DetectorEdit::parseRelEffCsvFile( fileLocation );
15561501

1557-
if( det )
1502+
if( det && det->isValid() )
15581503
{
1559-
// Generate a eff plot, and basic info, and display.
1560-
// Then ask user if they want to use DRF; if so save to `InterSpec::writableDataDirectory() + "UploadedDrfs"`
1504+
// TODO: generate a eff plot, and basic info, and display; probably by refactoring DetectorEdit::updateChart()
1505+
// TODO: Ask user if they want to use DRF; if so save to `InterSpec::writableDataDirectory() + "UploadedDrfs"`
1506+
// TODO: handle CSV/TSV files that have multiple DRFs
1507+
// TODO: handle GADRAS style Efficiency.csv files
1508+
// TODO: allow users to rename the DRF.
15611509

1562-
#if( USE_SIMPLE_DIALOG_FOR_NOT_SPEC )
1563-
delete dialog;
1564-
#else
1565-
delete w;
1566-
#endif
1510+
const string name = Wt::Utils::htmlEncode( det->name() );
1511+
1512+
string msg = "<p style=\"white-space: nowrap;\">"
1513+
"This file looks to be a Detector Response Function."
1514+
"</p>"
1515+
"<p style=\"text-align: left; white-space: nowrap;\">"
1516+
"Name: " + name +
1517+
"</p>"
1518+
"<p>Would you like to use this DRF?</p>"
1519+
;
1520+
1521+
WText *t = new WText( WString::fromUTF8(msg) );
1522+
stretcher->addWidget( t, stretcher->rowCount(), 0, AlignCenter | AlignMiddle );
1523+
t->setTextAlignment( Wt::AlignCenter );
1524+
1525+
dialog->addButton( "No" ); //no further action necessary if user clicks no; dialog will close
1526+
closeButton->setText( "Yes" );
1527+
closeButton->clicked().connect( std::bind( [det](){
1528+
InterSpec *interspec = InterSpec::instance();
1529+
if( interspec )
1530+
{
1531+
auto sql = interspec->sql();
1532+
auto user = interspec->m_user;
1533+
DetectorEdit::updateLastUsedTimeOrAddToDb( det, user.id(), sql );
1534+
interspec->detectorChanged().emit( det ); //This loads it to the foreground spectrum file
1535+
}
1536+
} ) );
15671537

15681538
return true;
15691539
}
15701540
}//if( maybe a drf )
1571-
*/
15721541

15731542

15741543
/*
@@ -1600,12 +1569,7 @@ bool SpecMeasManager::handleNonSpectrumFile( const std::string &displayName,
16001569
}//if( header_contains( "Relative Eff" ) && header_contains( "#credit" ) )
16011570
*/
16021571

1603-
1604-
#if( USE_SIMPLE_DIALOG_FOR_NOT_SPEC )
16051572
delete dialog;
1606-
#else
1607-
delete w;
1608-
#endif
16091573

16101574
return false;
16111575
}//void handleNonSpectrumFile(...)

0 commit comments

Comments
 (0)