bool ALSBL8XASFileLoader::loadFromFile(const QString& filepath, bool setMetaData, bool setRawDataSources, bool createDefaultAnalysisBlocks) { // not initialized to have a scan target, or scan target is not an AMXASScan... AMXASScan* scan = qobject_cast<AMXASScan*>(scan_); if(!scan) return false; // Clear the old scan axes to ensure we don't have any extras. scan->clearRawDataCompletely(); scan->rawData()->addScanAxis( AMAxisInfo("eV", 0, "Incident Energy", "eV") ); // information about the scan we hope to locate: QString comments; double integrationTime; // used in parsing the data file QString line; QStringList lp; // names of the columns, taken from headers in the data file. QStringList colNames1; // open the file: QFile f(filepath); if(!f.open(QIODevice::ReadOnly)) { AMErrorMon::report(AMErrorReport(0, AMErrorReport::Serious, -1, "ALSBL8XASFileLoader parse error while loading scan data from file. Missing file.")); return false; } QTextStream fs(&f); if(setMetaData) { // Start reading the file. look for the count-time line. while( !fs.atEnd() && !(line = fs.readLine()).startsWith("Count Time (s):") ) ; if(fs.atEnd()) { AMErrorMon::report(AMErrorReport(0, AMErrorReport::Debug, -2, "ALSBL8XASFileLoader parse error while loading scan data from file. Could not find the count time (integration time).")); fs.seek(0); // return false; // bad format; missing the count time string } else { // read it integrationTime = line.split(':').at(1).trimmed().toDouble(); } // Keep reading the file. look for the comment line. while( !fs.atEnd() && !(line = fs.readLine()).startsWith("Description Length:") ) ; if(fs.atEnd()) { AMErrorMon::report(AMErrorReport(0, AMErrorReport::Debug, -2, "ALSBL8XASFileLoader parse error while loading scan data from file. Could not find the description.")); fs.seek(0); // return false; // bad format; missing the comment string } else { // read the comment bool descriptionLengthOk; int descriptionLength = line.split(':').at(1).trimmed().toInt(&descriptionLengthOk); // read this many characters now... if(descriptionLengthOk) comments = fs.read(descriptionLength); } } // find out what columns exist. Looking for line starting with 'Time (s)' line.clear(); while(!fs.atEnd() && !line.startsWith("Time (s)")) line = fs.readLine(); if(fs.atEnd()) { AMErrorMon::report(AMErrorReport(0, AMErrorReport::Serious, -2, "ALSBL8XASFileLoader parse error while loading scan data from file. Missing the Column Header line.")); return false; // bad format; missing the column header } colNames1 = line.split(QChar('\t')); // translate header names into meaningful column names (ex: "Counter 0" ---> "I0".... "Counter1"--->"tey") for(int i=0; i<colNames1.count(); i++) header2columnName(colNames1[i]); // ensure that we have the basic "eV" column int eVIndex = colNames1.indexOf("eV"); if(eVIndex < 0) { AMErrorMon::report(AMErrorReport(0, AMErrorReport::Serious, -3, "ALSBL8XASFileLoader parse error while loading scan data from file. I couldn't find the energy (eV) column.")); return false; // bad format; no primary column } // clear the existing raw data (and raw data sources, if we're supposed to) if(setRawDataSources) scan->clearRawDataPointsAndMeasurementsAndDataSources(); else scan->clearRawDataPointsAndMeasurements(); // There is a rawData scan axis called "eV" created in the constructor. AMAxisInfo("eV", 0, "Incident Energy", "eV") /// \todo What if there isn't? Should we check, and create the axis if none exist? What if there's more than one scan axis? Can't remove from AMDataStore... [The rest of this code assumes a single scan axis] // add scalar (0D) measurements to the raw data store, for each data column. Also add raw data sources to the scan, which expose this data. foreach(QString colName, colNames1) { if(colName != "eV" && colName != "Event-ID") { scan->rawData()->addMeasurement(AMMeasurementInfo(colName, colName)); /// \todo nice descriptions for the common column names; not just 'tey' or 'tfy'. } } int eVAxisIndex = 0; // counter for each datapoint along the scan axis. // read all the data. Add to data columns or scan properties depending on the event-ID. while(!fs.atEnd()) { line = fs.readLine(); // Data line. If there are the correct number of columns: if( (lp = line.split('\t', QString::SkipEmptyParts)).count() == colNames1.count() ) { // append a new datapoint to the data tree (supply primary eV value here) scan->rawData()->beginInsertRows(1, -1); scan->rawData()->setAxisValue(0, eVAxisIndex, lp.at(eVIndex).toDouble()); // insert eV // add all columns (but ignore the eV column) int measurementId = 0; for(int i=1; i<colNames1.count(); i++) { if(i!=eVIndex) scan->rawData()->setValue(eVAxisIndex, measurementId++, AMnDIndex(), lp.at(i).toDouble()); } eVAxisIndex++; scan->rawData()->endInsertRows(); } } if(setMetaData) { scan->setNotes(comments); // for a date-time, there is no information saved inside the file format, so the best we can do is look at the file's creation date-time... QFileInfo fi(filepath); scan->setDateTime(fi.lastModified()); /// \todo integration time... do what with? } // If we need to create the raw data sources... if(setRawDataSources) { // expose the raw data that might be useful to the users foreach(QString visibleColumn, defaultUserVisibleColumns_) { int measurementId = scan->rawData()->idOfMeasurement(visibleColumn); if(measurementId >= 0) scan->addRawDataSource(new AMRawDataSource(scan->rawData(), measurementId)); } }
bool VESPERSXASDataLoader::loadFromFile(const QString &filepath, bool setMetaData, bool setRawDataSources, bool createDefaultAnalysisBlocks) { // Currently don't have meta data. Q_UNUSED(setMetaData) Q_UNUSED(setRawDataSources) Q_UNUSED(createDefaultAnalysisBlocks) AMXASScan *scan = qobject_cast<AMXASScan *>(scan_); if (!scan) { AMErrorMon::alert(0, 0, "VESPERS XAS File Loader: Could not load XAS data into a non-XAS scan."); return false; } // Clear the old scan axes to ensure we don't have any extras. scan->clearRawDataCompletely(); scan->rawData()->addScanAxis( AMAxisInfo("eV", 0, "Incident Energy", "eV") ); QFile file(filepath); if(!file.open(QIODevice::ReadOnly)) { AMErrorMon::error(0, -1, "XASFileLoader parse error while loading scan data from file."); return false; } QFile spectra; QVector<int> data; QTextStream in(&file); QString line; QStringList lineTokenized; // Need to determine if the single element or four element vortex detector was used. Also need to determine which ion chambers were used for I0 and It. // First two lines are useless. line = in.readLine(); line = in.readLine(); line = in.readLine(); if (line.contains("#(2)")) line = in.readLine(); bool usingVortex = line.contains("IOC1607-004") || line.contains("dxp1607-B21-04"); if (usingVortex) { data.resize(2048); QString temp(filepath); temp.chop(4); spectra.setFileName(temp+"_spectra.dat"); if(!spectra.open(QIODevice::ReadOnly)) { AMErrorMon::error(0, -1, QString("XASFileLoader parse error while loading scan spectra data from %1.").arg(spectra.fileName())); return false; } } else spectra.setFileName(""); QTextStream spectraStream(&spectra); QString spectraLine; QStringList spectraTokenized; while ((line = in.readLine()).contains("#")) { //Do nothing } // Clear any old data so we can start fresh. scan->clearRawDataPointsAndMeasurements(); // Some setup variables. int axisValueIndex = 0; if (usingVortex) { for (int i = 0; i < scan_->rawDataSourceCount()-1; i++) scan_->rawData()->addMeasurement(AMMeasurementInfo(scan_->rawDataSources()->at(i)->name(), scan_->rawDataSources()->at(i)->description())); QList<AMAxisInfo> axisInfo; AMAxisInfo ai("Energy", 2048, "Energy", "eV"); ai.increment = 10; ai.start = AMNumber(0); ai.isUniform = true; axisInfo << ai; scan_->rawData()->addMeasurement(AMMeasurementInfo(scan_->rawDataSources()->at(scan_->rawDataSourceCount()-1)->name(), scan_->rawDataSources()->at(scan_->rawDataSourceCount()-1)->description(), "eV", axisInfo)); } else { for (int i = 0; i < scan_->rawDataSourceCount(); i++) scan_->rawData()->addMeasurement(AMMeasurementInfo(scan_->rawDataSources()->at(i)->name(), scan_->rawDataSources()->at(i)->description())); } while (!in.atEnd()) { lineTokenized << line.split(", "); scan->rawData()->beginInsertRows(1, -1); scan_->rawData()->setAxisValue(0, axisValueIndex, lineTokenized.at(1).toDouble()); // This isn't the most efficient way of putting the spectra data in, but it will do for the time being. if (usingVortex) { // Only going to rawDataSourceCount-1 because the last raw data source is the 2D spectra scan and requires its own method of entering the data. for (int i = 0; i < scan_->rawDataSourceCount()-1; i++) scan_->rawData()->setValue(axisValueIndex, i, AMnDIndex(), lineTokenized.at(i+2).toDouble()); spectraTokenized.clear(); spectraLine = spectraStream.readLine(); spectraTokenized << spectraLine.split(","); for (int j = 0; j < 2048; j++) data[j] = spectraTokenized.at(j).toInt(); scan_->rawData()->setValue(axisValueIndex, scan_->rawDataSourceCount()-1, data.constData()); } else { // In transmission, there is no 2D spectra. Go through all the data sources. for (int i = 0; i < scan_->rawDataSourceCount(); i++) scan_->rawData()->setValue(axisValueIndex, i, AMnDIndex(), lineTokenized.at(i+2).toDouble()); } scan->rawData()->endInsertRows(); axisValueIndex++; line = in.readLine(); lineTokenized.clear(); } file.close(); if (usingVortex) spectra.close(); return true; }