Newer
Older
Roman Tolchenov
committed
#include "MantidDataHandling/ManagedRawFileWorkspace2D.h"
#include "MantidKernel/Exception.h"
#include "MantidAPI/RefAxis.h"
#include "MantidAPI/LocatedDataRef.h"
#include "MantidAPI/WorkspaceIterator.h"
#include "MantidAPI/WorkspaceIteratorCode.h"
#include "MantidAPI/WorkspaceProperty.h"
#include "MantidAPI/WorkspaceFactory.h"
Roman Tolchenov
committed
#include "MantidKernel/UnitFactory.h"
Roman Tolchenov
committed
#include "MantidKernel/ConfigService.h"
Roman Tolchenov
committed
#include "LoadRaw/isisraw2.h"
Roman Tolchenov
committed
#include <boost/timer.hpp>
#include <boost/filesystem.hpp>
Roman Tolchenov
committed
//DECLARE_WORKSPACE(ManagedRawFileWorkspace2D)
namespace Mantid
{
namespace DataHandling
{
// Get a reference to the logger
Kernel::Logger& ManagedRawFileWorkspace2D::g_log = Kernel::Logger::get("ManagedRawFileWorkspace2D");
Roman Tolchenov
committed
// Initialise the instance count
int ManagedRawFileWorkspace2D::g_uniqueID = 1;
Roman Tolchenov
committed
/// Constructor
Roman Tolchenov
committed
ManagedRawFileWorkspace2D::ManagedRawFileWorkspace2D():
isisRaw(new ISISRAW2),m_fileRaw(NULL),m_readIndex(0)
Roman Tolchenov
committed
{
}
///Destructor
ManagedRawFileWorkspace2D::~ManagedRawFileWorkspace2D()
{
delete isisRaw;
if (m_fileRaw) fclose(m_fileRaw);
Roman Tolchenov
committed
removeTempFile();
Roman Tolchenov
committed
}
/** Sets the RAW file for this workspace.
\param fileName The path to the RAW file.
Roman Tolchenov
committed
\param opt Caching option. 0 - cache on local drive if raw file is very slow to read.
1 - cache anyway, 2 - never cache.
Roman Tolchenov
committed
*/
Roman Tolchenov
committed
void ManagedRawFileWorkspace2D::setRawFile(const std::string& fileName,int opt)
Roman Tolchenov
committed
{
m_filenameRaw = fileName;
Roman Tolchenov
committed
m_fileRaw = fopen(m_filenameRaw.c_str(),"rb");
if (m_fileRaw == NULL)
Roman Tolchenov
committed
{
g_log.error("Unable to open file " + m_filenameRaw);
throw Kernel::Exception::FileError("Unable to open File:" , m_filenameRaw);
}
Roman Tolchenov
committed
if ( needCache(opt) )
{
openTempFile();
}
isisRaw->ioRAW(m_fileRaw, true);
Roman Tolchenov
committed
m_numberOfBinBoundaries = isisRaw->t_ntc1 + 1;
m_numberOfPeriods = isisRaw->t_nper;
initialize(isisRaw->t_nsp1,m_numberOfBinBoundaries,isisRaw->t_ntc1);
int noOfBlocks = m_noVectors / m_vectorsPerBlock;
if ( noOfBlocks * m_vectorsPerBlock != m_noVectors ) ++noOfBlocks;
m_changedBlock.resize(noOfBlocks,false);
float* timeChannels = new float[m_numberOfBinBoundaries];
isisRaw->getTimeChannels(timeChannels, m_numberOfBinBoundaries);
isisRaw->skipData(0);
Roman Tolchenov
committed
fgetpos(m_fileRaw, &m_data_pos); //< Save the data start position.
Roman Tolchenov
committed
m_timeChannels.reset(new std::vector<double>(timeChannels, timeChannels + m_numberOfBinBoundaries));
Roman Tolchenov
committed
getAxis(0)->unit() = Kernel::UnitFactory::Instance().create("TOF");
Roman Tolchenov
committed
}
static double dblSqrt(double in)
{
return sqrt(in);
}
// readData(int) should be changed to readNextSpectrum() returning the spectrum index
// and skipData to skipNextSpectrum()
//void ManagedRawFileWorkspace2D::readSpectrum(int index)const
Roman Tolchenov
committed
void ManagedRawFileWorkspace2D::readDataBlock(DataObjects::ManagedDataBlock2D *newBlock,int startIndex)const
Roman Tolchenov
committed
{
Roman Tolchenov
committed
Poco::ScopedLock<Poco::FastMutex> mutex(m_mutex);
Roman Tolchenov
committed
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
if (!m_fileRaw)
{
g_log.error("Raw file was not open.");
throw std::runtime_error("Raw file was not open.");
}
int blockIndex = startIndex / m_vectorsPerBlock;
// Modified data is stored in ManagedWorkspace2D flat file.
if (m_changedBlock[blockIndex])
{
ManagedWorkspace2D::readDataBlock(newBlock,startIndex);
return;
}
if (startIndex > m_readIndex)
{
while(startIndex > m_readIndex)
{
isisRaw->skipData(m_readIndex+1);// Adding 1 because we dropped the first spectrum.
++m_readIndex;
}
}
else
{
int nwords = 0;
while(startIndex < m_readIndex)
{
--m_readIndex;
nwords += 4*isisRaw->ddes[m_readIndex+1].nwords;
}
if (fseek(m_fileRaw,-nwords,SEEK_CUR) != 0)
{
Roman Tolchenov
committed
fclose(m_fileRaw);
removeTempFile();
Roman Tolchenov
committed
g_log.error("Error reading RAW file.");
throw std::runtime_error("ManagedRawFileWorkspace2D: Error reading RAW file.");
}
}
int endIndex = startIndex+m_vectorsPerBlock < m_noVectors?startIndex+m_vectorsPerBlock:m_noVectors;
if (endIndex >= m_noVectors) endIndex = m_noVectors;
Roman Tolchenov
committed
for(int index = startIndex;index<endIndex;index++,m_readIndex++)
Roman Tolchenov
committed
{
isisRaw->readData(m_readIndex+1);
std::vector<double> y(isisRaw->dat1 + 1, isisRaw->dat1 + m_numberOfBinBoundaries);
std::vector<double> e(m_numberOfBinBoundaries-1);
std::transform(y.begin(), y.end(), e.begin(), dblSqrt);
Roman Tolchenov
committed
newBlock->setX(index,m_timeChannels);
newBlock->setData(index,y,e);
Roman Tolchenov
committed
}
newBlock->hasChanges(false);
}
Roman Tolchenov
committed
void ManagedRawFileWorkspace2D::writeDataBlock(DataObjects::ManagedDataBlock2D *toWrite)
Roman Tolchenov
committed
{
Roman Tolchenov
committed
Poco::ScopedLock<Poco::FastMutex> mutex(m_mutex);
Roman Tolchenov
committed
ManagedWorkspace2D::writeDataBlock(toWrite);
int blockIndex = toWrite->minIndex() / m_vectorsPerBlock;
m_changedBlock[blockIndex] = toWrite->hasChanges();
Roman Tolchenov
committed
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
}
/**
Decides if the raw file must be copied to a cache file on the local drive to improve reading time.
*/
bool ManagedRawFileWorkspace2D::needCache(int opt)
{
if (opt == 1) return true;
if (opt == 2) return false;
FILE * ff = fopen(m_filenameRaw.c_str(),"rb");
if (ff)
{
size_t n = 100000;
char *buf = new char[n];
boost::timer tim;
size_t i = fread(buf,sizeof(char),n,ff);
double elapsed = tim.elapsed();
fclose(ff);
delete[] buf;
if (i > 0)
{
return elapsed > 0.01;
}
}
return false;
}
void ManagedRawFileWorkspace2D::openTempFile()
{
// Look for the (optional) path from the configuration file
std::string path = Kernel::ConfigService::Instance().getString("ManagedWorkspace.FilePath");
if ( !path.empty() )
{
if ( ( *(path.rbegin()) != '/' ) && ( *(path.rbegin()) != '\\' ) )
{
path.push_back('/');
}
}
boost::filesystem::path source(m_filenameRaw);
std::stringstream filename;
filename << "WS2D_" <<boost::filesystem::basename(source)<<'_'<< ManagedRawFileWorkspace2D::g_uniqueID<<".raw";
// Increment the instance count
++ManagedRawFileWorkspace2D::g_uniqueID;
m_tempfile = path + filename.str();
boost::filesystem::path dest(m_tempfile);
boost::filesystem::copy_file(source,dest);
FILE *fileRaw = fopen(m_tempfile.c_str(),"rb");
if (fileRaw)
{
fclose(m_fileRaw);
m_fileRaw = fileRaw;
}
}
void ManagedRawFileWorkspace2D::removeTempFile()const
{
if (!m_tempfile.empty()) remove(m_tempfile.c_str());
Roman Tolchenov
committed
}
} // namespace DataHandling
} //NamespaceMantid
///\endcond TEMPLATE