Skip to content

Commit

Permalink
refs #6543 Reading old (and wrong) libisis format
Browse files Browse the repository at this point in the history
  • Loading branch information
abuts committed Feb 15, 2013
1 parent 01098cc commit f0be7db
Show file tree
Hide file tree
Showing 3 changed files with 207 additions and 10 deletions.
Expand Up @@ -78,7 +78,7 @@ class DLLExport LoadDetectorInfo : public API::Algorithm
double phi; ///<phi
/// Constructor
detectorInfo(): detID(-1), pressure(-1.0), wallThick(DBL_MAX), l2(DBL_MAX),
theta(DBL_MAX), phi(DBL_MAX) {}
theta(DBL_MAX), phi(DBL_MAX) {}
};
/// will store a pointer to the user selected workspace
API::MatrixWorkspace_sptr m_workspace;
Expand All @@ -96,8 +96,6 @@ class DLLExport LoadDetectorInfo : public API::Algorithm
bool m_error;
/// An estimate of the percentage of the algorithm runtimes that has been completed
double m_FracCompl;
/// If set to true then update the detector positions base on the information in the given file
bool m_moveDets;
/// Store the sample position as we may need it repeatedly
Kernel::V3D m_samplePos;
/// A pointer to the parameter map for the workspace
Expand All @@ -108,9 +106,14 @@ class DLLExport LoadDetectorInfo : public API::Algorithm
// Implement abstract Algorithm methods
void init();
void exec();
protected: // for testing
void readDAT(const std::string& fName);
void readRAW(const std::string& fName);
void readNXS(const std::string& fName);
/// If set to true then update the detector positions base on the information in the given file
bool m_moveDets;
private:
void readLibisisNXS(::NeXus::File *hFile, std::vector<detectorInfo> &detStruct,std::vector<int32_t>&detType,std::vector<float> &detOffset);

void setDetectorParams(const detectorInfo &params, detectorInfo &changed);
void adjDelayTOFs(double lastOffset, bool &differentDelays, const std::vector<detid_t> &detectIDs=std::vector<detid_t>(), const std::vector<float> &delays=std::vector<float>());
Expand Down
181 changes: 179 additions & 2 deletions Code/Mantid/Framework/DataHandling/src/LoadDetectorInfo.cpp
Expand Up @@ -15,6 +15,9 @@
#include <sstream>
#include "LoadRaw/isisraw2.h"

#include <Poco/File.h>
#include <MantidNexusCPP/NeXusFile.hpp>

namespace Mantid
{
namespace DataHandling
Expand Down Expand Up @@ -61,15 +64,16 @@ void LoadDetectorInfo::init()
exts.push_back(".dat");
exts.push_back(".raw");
exts.push_back(".sca");
exts.push_back(".nxs");
declareProperty(new FileProperty("DataFilename","", FileProperty::Load, exts),
"A .DAT or .raw file that contains information about the detectors in the\n"
"workspace. Partial pressures of 3He will be loaded assuming units of\n"
"atmospheres, offset times in the same units as the workspace X-values and\n"
"and wall thicknesses in metres.");

declareProperty("RelocateDets", false,
"If true then update the detector positions with those from the input file, default=false.",
Direction::Input);
"If true then update the detector positions with those from the input file, default=false.",
Direction::Input);
}

/** Executes the algorithm
Expand Down Expand Up @@ -121,6 +125,12 @@ void LoadDetectorInfo::exec()
readRAW(filename);
}

if ( filename.find(".nxs") == filename.size()-4 ||
filename.find(".NXS") == filename.size()-4)
{
readNXS(filename);
}

if (m_error)
{
g_log.warning() << "Note workspace " << getPropertyValue("Workspace") << " has been changed so if you intend to fix detector mismatch problems by running "
Expand Down Expand Up @@ -797,5 +807,172 @@ void LoadDetectorInfo::sometimesLogSuccess(const detectorInfo &params, bool &nee
needToLog = false;
}

/**The methor reads selected part of detector.nxs file and apply correspondent changes to the detectors */
void LoadDetectorInfo::readNXS(const std::string& fName)
{
Poco::File nxsFile(fName);
if(!nxsFile.exists() || !nxsFile.isFile())
throw std::invalid_argument(" file "+fName+" does not exist");

auto hFile = new ::NeXus::File(fName,NXACC_READ);
if(!hFile)
throw std::runtime_error(" Can not open file "+fName+" as nexus file");

hFile->openGroup("full_reference_detector","NXIXTdetector");
std::vector<detectorInfo> detStruct;
std::vector<int32_t> detType;
std::vector<float> detOffset;
this->readLibisisNXS(hFile,detStruct,detType,detOffset);
hFile->closeGroup();
delete hFile;

size_t nDetectors = detStruct.size();
float detectorOffset = UNSETOFFSET;
bool differentOffsets = false;
std::vector<detid_t> detectorList;
detectorList.reserve(nDetectors);
std::vector<detid_t> missingDetectors;
detectorInfo log;

bool noneSet = true;
size_t detectorProblemCount(0);
for(size_t i=0;i<nDetectors;i++)
{

// check we have a supported code
switch (detType[i])
{
// these first two codes are detectors that we'll process, the code for this is below
case PSD_GAS_TUBE : break;
case NON_PSD_GAS_TUBE : break;

// the following detectors codes specify little or no analysis
case MONITOR_DEVICE :
// throws invalid_argument if the detection delay time is different for different monitors
noteMonitorOffset(detOffset[i], detStruct[i].detID);
// skip the rest of this loop and move on to the next detector
continue;

// the detector is set to dummy, we won't report any error for this we'll just do nothing
case DUMMY_DECT : continue;

//we can't use data for detectors with other codes because we don't know the format, ignore the data and write to g_log.warning() once at the end
default :
detectorProblemCount ++;
g_log.debug() << "Ignoring data for a detector with code " << detType[i] << std::endl;
continue;
}

// gas filled detector specific code now until the end of this method

// normally all the offsets are the same and things work faster, check for this
if ( detOffset[i] != detectorOffset )
{// could mean different detectors have different offsets and we need to do things thoroughly
if ( detectorOffset != UNSETOFFSET )
{
differentOffsets = true;
}
detectorOffset = detOffset[i];
}


try
{
setDetectorParams(detStruct[i], log);
sometimesLogSuccess(log, noneSet);
detectorList.push_back(detStruct[i].detID);
}
catch (Exception::NotFoundError &)
{// there are likely to be some detectors that we can't find in the instrument definition and we can't save parameters for these. We can't do anything about this just report the problem at the end
missingDetectors.push_back(detStruct[i].detID);
continue;
}

// report progress and check for a user cancel message at regualar intervals

if ( i % 1000 == 0 )
{
progress(static_cast<double>(i));
interruption_point();
}
}

sometimesLogSuccess(log, noneSet = true);
g_log.debug() << "Adjusting time of flight X-values by detector delay times" << std::endl;
adjDelayTOFs(detectorOffset, differentOffsets, detectorList, detOffset);

if ( detectorProblemCount > 0 )
{
g_log.warning() << "Data for " << detectorProblemCount << " detectors that are neither monitors or psd gas tubes, the data have been ignored" << std::endl;
}
logErrorsFromRead(missingDetectors);
g_log.debug() << "Successfully read DAT file " << fName << std::endl;
}

void LoadDetectorInfo::readLibisisNXS(::NeXus::File *hFile, std::vector<detectorInfo> &detStruct, std::vector<int32_t>&detType,std::vector<float> &detOffset)
{

std::vector<double> delayTime;
std::vector<int32_t> detID;
// read detector ID
hFile->openData("det_no");
hFile->getData<int32_t>(detID);
hFile->closeData();
// read detector type
hFile->openData("det_type");
hFile->getData<int32_t>(detType);
hFile->closeData();

// read the detector's type
hFile->openData("delay_time");
hFile->getData<double>(delayTime);
hFile->closeData();

size_t nDetectors = delayTime.size();
std::vector<double> L2,Phi,Theta;
if(m_moveDets)
{
// the secondary flight path -- sample to detector
hFile->readData<double>("L2",L2);
// detector's polar angle Theta (2Theta in Brag's terminology)
hFile->readData<double>("theta",Theta);
// detector's polar angle, phi
hFile->readData<double>("phi",Phi);
}
else
{
L2.assign(nDetectors,DBL_MAX);
Phi.assign(nDetectors,DBL_MAX);
Theta.assign(nDetectors,DBL_MAX);
}
//We need He3 pressue and wall thikness
double pressure(0.0008),wallThickness(111.);
hFile->openGroup("det_he3","NXIXTdet_he3");
hFile->readData<double>("gas_pressure",pressure);
hFile->readData<double>("wall_thickness",wallThickness);
hFile->closeGroup();


if(nDetectors!=L2.size()||nDetectors!=Phi.size()||nDetectors!=Theta.size()||nDetectors!=detID.size())
throw std::runtime_error("The size of nexus data columns is not equal to each other");

detStruct.resize(nDetectors);
detOffset.resize(nDetectors);
for(size_t i=0;i<nDetectors;i++)
{
detStruct[i].detID = detID[i];
detStruct[i].l2 = L2[i];
detStruct[i].theta = Theta[i];
detStruct[i].phi = Phi[i];
detStruct[i].pressure = pressure;
detStruct[i].wallThick = wallThickness;

detOffset[i] = float(delayTime[i]);
}

}



} // namespace DataHandling
} // namespace Mantid
25 changes: 21 additions & 4 deletions Code/Mantid/Framework/DataHandling/test/LoadDetectorInfoTest.h
Expand Up @@ -44,6 +44,17 @@ namespace SmallTestDatFile
const int NDETECTS = 6;
}


class LoadDetectorIndoTestHelper : public LoadDetectorInfo
{
public:
void readNXS(const std::string &fName,bool moveDetectors = true)
{
this->m_moveDets = moveDetectors;
LoadDetectorInfo::readNXS(fName);
}
};

namespace
{
std::string delta[] = {"4", "4.500", "4.500", "4.500", "-6.00", "0.000"};
Expand Down Expand Up @@ -202,13 +213,13 @@ class LoadDetectorInfoTest : public CxxTest::TestSuite
V3D expected;
if( j == 1 ) // Monitors are fixed and unaffected
{
expected = V3D(0,0,0);
expected = V3D(0,0,0);
}
else
{
expected.spherical(boost::lexical_cast<double>(det_l2[j]),
boost::lexical_cast<double>(det_theta[j]),
boost::lexical_cast<double>(det_phi[j]));
expected.spherical(boost::lexical_cast<double>(det_l2[j]),
boost::lexical_cast<double>(det_theta[j]),
boost::lexical_cast<double>(det_phi[j]));
}
TS_ASSERT_EQUALS(expected, pos);

Expand Down Expand Up @@ -358,6 +369,12 @@ class LoadDetectorInfoTest : public CxxTest::TestSuite
AnalysisDataService::Instance().remove(m_MariWS);
}

void testLoadNXS()
{
LoadDetectorIndoTestHelper loader;
TS_ASSERT_THROWS(loader.readNXS("NonExistingFile"),std::invalid_argument);
TS_ASSERT_THROWS_NOTHING(loader.readNXS("detector_121.nxs"));
}
void loadRawFile()
{
LoadRaw3 loader;
Expand Down

0 comments on commit f0be7db

Please sign in to comment.