void AMExternalScanDataSourceAB::copyValues(int dataSourceIndex) { AMDataSource* ds = scan_->dataSourceAt(dataSourceIndex); const AMnDIndex size = ds->size(); switch(ds->rank()) { case 0: values_.clear(); values_ << ds->value(AMnDIndex()); break; case 1: { values_.resize(size.i()); for(int i=0; i<size.i(); i++) values_[i] = ds->value(i); break; } case 2: { values_.resize(size.i()*size.j()); for(int i=0; i<size.i(); i++) for(int j=0; j<size.j(); j++) values_[i*size.j() + j] = ds->value(AMnDIndex(i,j)); break; } case 3: { values_.resize(size.i()*size.j()*size.k()); for(int i=0; i<size.i(); i++) for(int j=0; j<size.j(); j++) for(int k=0; k<size.k(); k++) values_[i*size.j()*size.k() + j*size.k() + k] = ds->value(AMnDIndex(i,j,k)); break; } case 4: { values_.resize(size.i()*size.j()*size.k()*size.l()); for(int i=0; i<size.i(); i++) for(int j=0; j<size.j(); j++) for(int k=0; k<size.k(); k++) for(int l=0; l<size.l(); l++) values_[i*size.j()*size.k()*size.l() + j*size.k()*size.l() + k*size.l() + l] = ds->value(AMnDIndex(i,j,k,l)); break; } case 5: { values_.resize(size.i()*size.j()*size.k()*size.l()*size.m()); for(int i=0; i<size.i(); i++) for(int j=0; j<size.j(); j++) for(int k=0; k<size.k(); k++) for(int l=0; l<size.l(); l++) for(int m=0; m<size.m(); m++) values_[i*size.j()*size.k()*size.l()*size.m() + j*size.k()*size.l()*size.m() + k*size.l()*size.m() + l*size.m() + m] = ds->value(AMnDIndex(i,j,k,l,m)); /// \todo oh god, we really need a block copy or a multi-dimensional iterator for AMDataSource::value()... break; } } }
void REIXSXESScanController::onNewImageValues() { QVector<int> imageData = REIXSBeamline::bl()->mcpDetector()->imageData(); if(!scan_->rawData()->setValue(AMnDIndex(), 0, imageData.constData())) AMErrorMon::report(AMErrorReport(this, AMErrorReport::Debug, 37, "Error setting the new values from the MCP Detector. The size of the image didn't match what it should be. This is probably a problem with the network connection to the detector, or a bug in the detector driver.")); if(!scan_->rawData()->setValue(AMnDIndex(), 1, AMnDIndex(), double(REIXSBeamline::bl()->mcpDetector()->totalCounts()))) AMErrorMon::debug(this, 377, "Error setting new values for the MCP Detector total counts. Please report this bug to the REIXS Acquaman developers."); }
QPair<double, double> AM2DScanView::getCurrentExclusiveDataSourceRange(const AMnDIndex &start, const AMnDIndex &end) const { if (start == end && start.rank() == 2 && end.rank() == 2){ QPair<double, double> range = exclusive2DScanBar_->range(); double val = double(currentExclusiveDataSource_->value(start)); if ((val != -1 && range.first > val) || range.first == -1) range.first = val; if (range.second < val) range.second = val; return range; } else { int totalSize = 0; AMnDIndex startIndex = start; AMnDIndex endIndex = end; if (startIndex.rank() == 0 || endIndex.rank() == 0){ startIndex = AMnDIndex(0, 0); endIndex = AMnDIndex(currentExclusiveDataSource_->size(0)-1, currentExclusiveDataSource_->size(1)-1); totalSize = startIndex.totalPointsTo(endIndex); } else totalSize = start.totalPointsTo(end); if (totalSize > 0){ QVector<double> data(totalSize); currentExclusiveDataSource_->values(startIndex, endIndex, data.data()); double min = data.at(0); double max = data.at(0); foreach (double value, data){ if ((value != -1 && min > value) || min == -1) min = value; if (max < value) max = value; } return qMakePair(min, max); } else return qMakePair(-1.0, -1.0);
void AM3DAdditionAB::computeCachedValues() const { AMnDIndex start = AMnDIndex(); AMnDIndex end = AMnDIndex(); if (dirtyIndices_.isEmpty()){ start = AMnDIndex(rank(), AMnDIndex::DoInit); end = size()-1; } else { start = dirtyIndices_.first(); end = dirtyIndices_.last(); end[rank()-1] = size(rank()-1); } int totalSize = start.totalPointsTo(end); int flatStartIndex = start.flatIndexInArrayOfSize(size()); QVector<double> data = QVector<double>(totalSize); sources_.at(0)->values(start, end, data.data()); // Do the first data source separately to initialize the values. memcpy(cachedData_.data()+flatStartIndex, data.constData(), totalSize*sizeof(double)); cachedData_ = data; // Iterate through the rest of the sources. for (int i = 1, count = sources_.size(); i < count; i++){ sources_.at(i)->values(start, end, data.data()); for (int j = 0; j < totalSize; j++) cachedData_[flatStartIndex+j] += data.at(j); } if (dirtyIndices_.isEmpty()) cachedDataRange_ = AMUtility::rangeFinder(cachedData_); else{ AMRange cachedRange = AMUtility::rangeFinder(cachedData_.mid(flatStartIndex, totalSize)); if (cachedDataRange_.minimum() > cachedRange.minimum()) cachedDataRange_.setMinimum(cachedRange.minimum()); if (cachedDataRange_.maximum() < cachedRange.maximum()) cachedDataRange_.setMaximum(cachedRange.maximum()); } cacheUpdateRequired_ = false; dirtyIndices_.clear(); }
bool AM3DDeadTimeAB::values(const AMnDIndex &indexStart, const AMnDIndex &indexEnd, double *outputValues) const { if(indexStart.rank() != 3 || indexEnd.rank() != 3) return false; if(!isValid()) return false; #ifdef AM_ENABLE_BOUNDS_CHECKING if((unsigned)indexEnd.i() >= (unsigned)axes_.at(0).size || (unsigned)indexStart.i() > (unsigned)indexEnd.i() || (unsigned)indexEnd.j() >= (unsigned)axes_.at(1).size || (unsigned)indexStart.j() > (unsigned)indexEnd.j() || (unsigned)indexEnd.k() >= (unsigned)axes_.at(2).size || (unsigned)indexStart.k() > (unsigned)indexEnd.k()) return false; #endif int totalSize = indexStart.totalPointsTo(indexEnd); AMnDIndex start2D = AMnDIndex(indexStart.i(), indexStart.j()); AMnDIndex end2D = AMnDIndex(indexEnd.i(), indexEnd.j()); int icrOcrTotalSize = start2D.totalPointsTo(end2D); QVector<double> data = QVector<double>(totalSize); QVector<double> icr = QVector<double>(icrOcrTotalSize); QVector<double> ocr = QVector<double>(icrOcrTotalSize); spectra_->values(indexStart, indexEnd, data.data()); icr_->values(start2D, end2D, icr.data()); ocr_->values(start2D, end2D, ocr.data()); for (int i = 0, iSize = indexEnd.i()-indexStart.i()+1; i < iSize; i++){ for (int j = 0, jSize = indexEnd.j()-indexStart.j()+1; j < jSize; j++){ // If ocr is equal to 0 then that will cause division by zero. Since these are both count rates, they should both be greater than zero. if (icr.at(i*jSize+j) <= 0 || ocr.at(i*jSize+j) <= 0){ for (int k = 0, kSize = indexEnd.k()-indexStart.k()+1; k < kSize; k++) outputValues[i*jSize*kSize+j*kSize+k] = 0; } else { double factor = icr.at(i*jSize+j)/ocr.at(i*jSize+j); for (int k = 0, kSize = indexEnd.k()-indexStart.k()+1; k < kSize; k++) outputValues[i*jSize*kSize+j*kSize+k] = data.at(i*jSize*kSize+j*kSize+k)*factor; } } } return true; }
void AMDetectorAcquisitionAction::onAcquisitionSucceeded(){ disconnect(detector_, 0, this, 0); if(generateScanActionMessages_){ QList<int> dimensionSizes; QStringList dimensionNames; QStringList dimensionUnits; QList<AMAxisInfo> axes = detector_->axes(); for(int x = 0; x < axes.count(); x++){ dimensionSizes.append(axes.at(x).size); dimensionNames.append(axes.at(x).name); dimensionUnits.append(axes.at(x).units); } QList<double> detectorData; const double *detectorDataPointer = detector_->data(); if(detector_->rank() == 0) detectorData.append(detectorDataPointer[0]); else{ int totalPoints = AMnDIndex(detector_->rank(), AMnDIndex::DoInit, 0).totalPointsTo(detector_->size())-1; for(int x = 0; x < totalPoints; x++) detectorData.append(detectorDataPointer[x]); } AMAgnosticDataAPIDataAvailableMessage dataAvailableMessage(detector_->name(), detectorData, dimensionSizes, dimensionNames, dimensionUnits); AMAgnosticDataAPISupport::handlerFromLookupKey("ScanActions")->postMessage(dataAvailableMessage); } setSucceeded(); }
AMRange AMDataSource::dataRange() const { QVector<double> sourceData = QVector<double>(size().product()); values(AMnDIndex(rank(), AMnDIndex::DoInit), size()-1, sourceData.data()); return AMUtility::rangeFinder(sourceData); }
AMNumber AMDeadTimeAB::value(const AMnDIndex &indexes) const { if(indexes.rank() != 1) return AMNumber(AMNumber::DimensionError); if(!isValid()) return AMNumber(AMNumber::InvalidError); if (indexes.i() >= spectra_->size(0)) return AMNumber(AMNumber::OutOfBoundsError); if ((int)spectra_->value(indexes.i()) == 0) return 0; else return double(icr_->value(AMnDIndex()))/double(ocr_->value(AMnDIndex()))*(int)spectra_->value(indexes.i()); }
double AMDeadTimeButton::getCounts() const { double result = 0; if (inputCountSource_) result = double(inputCountSource_->value(AMnDIndex())); return result; }
double AMDeadTimeButton::getCountRate() const { double result = 0; if (inputCountSource_ && acquireTimeControl_) result = double(inputCountSource_->value(AMnDIndex())) / acquireTimeControl_->value(); return result; }
AMnDIndex AMDetector::size() const { AMnDIndex index = AMnDIndex(axes_.size(), AMnDIndex::DoNotInit); for (int i = 0, size = index.rank(); i < size; i++) index[i] = axes_.at(i).size; return index; }
double AMDeadTimeButton::getPercent() const { double result = 0; if (outputCountSource_ && inputCountSource_) result = 100*(1 - double(outputCountSource_->value(AMnDIndex()))/double(inputCountSource_->value(AMnDIndex()))); return result; }
void AMNormalizationAB::setInputDataSourcesImplementation(const QList<AMDataSource *> &dataSources) { // disconnect connections from old sources, if they exist. if(!sources_.isEmpty()) { for (int i = 0; i < sources_.size(); i++){ disconnect(sources_.at(i)->signalSource(), SIGNAL(valuesChanged(AMnDIndex,AMnDIndex)), this, SLOT(onInputSourceValuesChanged(AMnDIndex,AMnDIndex))); disconnect(sources_.at(i)->signalSource(), SIGNAL(sizeChanged(int)), this, SLOT(onInputSourceSizeChanged())); disconnect(sources_.at(i)->signalSource(), SIGNAL(stateChanged(int)), this, SLOT(onInputSourceStateChanged())); } } if(dataSources.isEmpty()) { sources_.clear(); axes_.clear(); setDescription("-- No input data --"); } // we know that this will only be called with valid input source /* else { sources_ = dataSources; axes_.clear(); for (int i = 0, size = sources_.at(0)->rank(); i < size; i++) axes_.append(sources_.at(0)->axisInfoAt(i)); cacheUpdateRequired_ = true; cachedData_ = QVector<double>(size().product()); setDescription(QString("Sum of spectra from %1 maps").arg(sources_.size())); for (int i = 0; i < sources_.size(); i++){ connect(sources_.at(i)->signalSource(), SIGNAL(valuesChanged(AMnDIndex,AMnDIndex)), this, SLOT(onInputSourceValuesChanged(AMnDIndex,AMnDIndex))); connect(sources_.at(i)->signalSource(), SIGNAL(sizeChanged(int)), this, SLOT(onInputSourceSizeChanged())); connect(sources_.at(i)->signalSource(), SIGNAL(stateChanged(int)), this, SLOT(onInputSourceStateChanged())); } } */ else { sources_ = dataSources; setInputSources(); } reviewState(); emitSizeChanged(); emitValuesChanged(AMnDIndex(0), size()-1); emitAxisInfoChanged(); emitInfoChanged(); }
AMNumber AM3DDeadTimeAB::value(const AMnDIndex &indexes) const { if(indexes.rank() != 3) return AMNumber(AMNumber::DimensionError); if(!isValid()) return AMNumber(AMNumber::InvalidError); #ifdef AM_ENABLE_BOUNDS_CHECKING if (indexes.i() >= spectra_->size(0) || indexes.j() >= spectra_->size(1) || indexes.k() >= spectra_->size(2)) return AMNumber(AMNumber::OutOfBoundsError); #endif if ((int)spectra_->value(indexes) == 0 || double(ocr_->value(AMnDIndex(indexes.i(), indexes.j()))) == 0) return 0; else return double(icr_->value(AMnDIndex(indexes.i(), indexes.j())))/double(ocr_->value(AMnDIndex(indexes.i(), indexes.j())))*(int)spectra_->value(indexes); }
bool AMDeadTimeAB::values(const AMnDIndex &indexStart, const AMnDIndex &indexEnd, double *outputValues) const { if(indexStart.rank() != 1 || indexEnd.rank() != 1) return false; if(!isValid()) return false; if((unsigned)indexEnd.i() >= (unsigned)axes_.at(0).size || (unsigned)indexStart.i() > (unsigned)indexEnd.i()) return false; int totalSize = indexStart.totalPointsTo(indexEnd); QVector<double> data = QVector<double>(totalSize); spectra_->values(indexStart, indexEnd, data.data()); double icr = double(icr_->value(AMnDIndex())); double ocr = double(ocr_->value(AMnDIndex())); // If ocr is equal to 0 then that will cause division by zero. Since these are both count rates, they should both be greater than zero. if (icr <= 0 || ocr <= 0){ for (int i = 0; i < totalSize; i++) outputValues[i] = 0; } else { double factor = icr/ocr; for (int i = 0; i < totalSize; i++) outputValues[i] = data.at(i)*factor; } return true; }
void AMDetectorReadAction::internalSetSucceeded(){ disconnect(detector_, 0, this, 0); if(generateScanActionMessages_){ QList<int> dimensionSizes; QStringList dimensionNames; QStringList dimensionUnits; QList<AMAxisInfo> axes = detector_->axes(); for(int x = 0; x < axes.count(); x++){ dimensionSizes.append(axes.at(x).size); dimensionNames.append(axes.at(x).name); dimensionUnits.append(axes.at(x).units); } QList<double> detectorData; int detectorDataPointerSize; if(detector_->readMode() == AMDetectorDefinitions::SingleRead) detectorDataPointerSize = detector_->size().product(); else detectorDataPointerSize = detector_->lastContinuousSize(); QVector<double> detectorDataPointer = QVector<double>(detectorDataPointerSize); detector_->data(detectorDataPointer.data()); if(detector_->rank() == 0 && detector_->readMode() == AMDetectorDefinitions::SingleRead) detectorData.append(detectorDataPointer[0]); else if(detector_->rank() == 0 && detector_->readMode() == AMDetectorDefinitions::ContinuousRead){ int totalPoints = detector_->lastContinuousSize(); if(totalPoints < 0) totalPoints = 0; for(int x = 0; x < totalPoints; x++) detectorData.append(detectorDataPointer[x]); } else{ int totalPoints = AMnDIndex(detector_->rank(), AMnDIndex::DoInit, 0).totalPointsTo(detector_->size())-1; for(int x = 0; x < totalPoints; x++) detectorData.append(detectorDataPointer[x]); } AMAgnosticDataAPIDataAvailableMessage dataAvailableMessage(detector_->name(), detectorData, dimensionSizes, dimensionNames, dimensionUnits); AMAgnosticDataAPISupport::handlerFromLookupKey("ScanActions")->postMessage(dataAvailableMessage); } setSucceeded(); }
AMnDIndex AM2DScanView::getIndex(const QPointF &point) const { int x = -1; int y = -1; AMDataSource *datasource = currentScan_->dataSourceAt(currentScan_->indexOfDataSource(scansModel_->exclusiveDataSourceName())); // This assumes 2D maps where the size is greater than 1x1, 1xN, or Nx1. double delX = (double(datasource->axisValue(0, 1)) - double(datasource->axisValue(0, 0)))/2; double delY = (double(datasource->axisValue(1, 1)) - double(datasource->axisValue(1, 0)))/2; for (int i = 0; i < currentScan_->scanSize(0); i++) if (fabs(point.x() - double(datasource->axisValue(0, i))) < delX) x = i; for (int i = 0; i < currentScan_->scanSize(1); i++) if (fabs(point.y() - double(datasource->axisValue(1, i))) < delY) y = i; return AMnDIndex(x, y); }
void AMAdditionAB::computeCachedValues() const { AMnDIndex start = AMnDIndex(rank(), AMnDIndex::DoInit, 0); AMnDIndex end = size()-1; int totalSize = start.totalPointsTo(end); QVector<double> data = QVector<double>(totalSize); sources_.at(0)->values(start, end, data.data()); // Do the first data source separately to initialize the values. cachedData_ = data; // Iterate through the rest of the sources. for (int i = 1, count = sources_.size(); i < count; i++) { sources_.at(i)->values(start, end, data.data()); for (int j = 0; j < totalSize; j++) cachedData_[j] += data.at(j); } cachedDataRange_ = AMUtility::rangeFinder(cachedData_); cacheUpdateRequired_ = false; }
bool AMDetector::reading2D(const AMnDIndex &startIndex, const AMnDIndex &endIndex, double *outputValues) const { if(!checkValid(startIndex, endIndex)) return false; if (endIndex.i() < startIndex.i() || endIndex.j() < startIndex.j()) return false; int iSize = size(0); for (int j = startIndex.j(); j <= endIndex.j(); j++) { for (int i = startIndex.i(); i <= endIndex.i(); i++) { AMNumber retVal = reading(AMnDIndex(i, j)); if(!retVal.isValid()) return false; outputValues[i+j*iSize] = double(retVal); } } return true; }
void AM4DBinningABEditor::updateSeriesData() { AMDataSource *source = analysisBlock_->inputDataSourceAt(0); if (source){ int sumAxis = analysisBlock_->sumAxis(); int sumAxisSize = source->size(sumAxis); QVector<double> xAxis(sumAxisSize); QVector<double> yAxis(sumAxisSize, 0); for (int i = 0; i < sumAxisSize; i++) xAxis[i] = double(source->axisValue(sumAxis, i)); switch (sumAxis){ case 0:{ for (int i = 0, iSize = analysisBlock_->size(0); i < iSize; i++){ for (int j = 0, jSize = analysisBlock_->size(1); j < jSize; j++){ for (int k = 0, kSize = analysisBlock_->size(2); k < kSize; k++){ QVector<double> temp(sumAxisSize); source->values(AMnDIndex(0, i, j, k), AMnDIndex(sumAxisSize-1, i, j, k), temp.data()); for (int l = 0; l < sumAxisSize; l++) yAxis[l] += temp.at(l); } } } break; } case 1:{ for (int i = 0, iSize = analysisBlock_->size(0); i < iSize; i++){ for (int j = 0, jSize = analysisBlock_->size(1); j < jSize; j++){ for (int k = 0, kSize = analysisBlock_->size(2); k < kSize; k++){ QVector<double> temp(sumAxisSize); source->values(AMnDIndex(i, 0, j, k), AMnDIndex(i, sumAxisSize-1, j, k), temp.data()); for (int l = 0; l < sumAxisSize; l++) yAxis[l] += temp.at(l); } } } break; } case 2:{ for (int i = 0, iSize = analysisBlock_->size(0); i < iSize; i++){ for (int j = 0, jSize = analysisBlock_->size(1); j < jSize; j++){ for (int k = 0, kSize = analysisBlock_->size(2); k < kSize; k++){ QVector<double> temp(sumAxisSize); source->values(AMnDIndex(i, j, 0, k), AMnDIndex(i, j, sumAxisSize-1, k), temp.data()); for (int l = 0; l < sumAxisSize; l++) yAxis[l] += temp.at(l); } } } break; } case 3:{ for (int i = 0, iSize = analysisBlock_->size(0); i < iSize; i++){ for (int j = 0, jSize = analysisBlock_->size(1); j < jSize; j++){ for (int k = 0, kSize = analysisBlock_->size(2); k < kSize; k++){ QVector<double> temp(sumAxisSize); source->values(AMnDIndex(i, j, k, 0), AMnDIndex(i, j, k, sumAxisSize-1), temp.data()); for (int l = 0; l < sumAxisSize; l++) yAxis[l] += temp.at(l); } } } break; } } seriesData_->setValues(xAxis, yAxis); } }
bool ALSBL8XASFileLoaderPlugin::load(AMScan *scan, const QString &userDataFolder, AMErrorMon *errorMonitor){ if(columns2fileFormatHeaders_.count() == 0) { columns2fileFormatHeaders_.set("eV", "Mono Energy"); columns2fileFormatHeaders_.set("ringCurrent", "Beam Current"); columns2fileFormatHeaders_.set("I0", "Counter 0"); columns2fileFormatHeaders_.set("TEY", "Counter 1"); columns2fileFormatHeaders_.set("TFY", "Counter 2"); } 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") ); QFileInfo sourceFileInfo(scan->filePath()); if(sourceFileInfo.isRelative()){ sourceFileInfo.setFile(userDataFolder + "/" + scan->filePath()); } // 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(sourceFileInfo.filePath()); if(!f.open(QIODevice::ReadOnly)) { errorMonitor->exteriorReport(AMErrorReport(0, AMErrorReport::Serious, ALSBL8XASFileLoaderPLUGIN_CANNOT_OPEN_FILE, "ALSBL8XASFileLoader parse error while loading scan data from file. Missing file.")); return false; } QTextStream fs(&f); // find out what columns exist. Looking for line starting with 'Time (s)' while(!fs.atEnd() && !line.startsWith("Time (s)")) line = fs.readLine(); if(fs.atEnd()) { errorMonitor->exteriorReport(AMErrorReport(0, AMErrorReport::Serious, ALSBL8XASFileLoaderPLUGIN_BAD_FORMAT_NO_EVENT1_HEADER, "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) { errorMonitor->exteriorReport(AMErrorReport(0, AMErrorReport::Serious, ALSBL8XASFileLoaderPLUGIN_BAD_FORMAT_NO_ENERGY_COLUMN, "ALSBL8XASFileLoader parse error while loading scan data from file. I couldn't find the energy (eV) column.")); return false; // bad format. No primary column } 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(); } } /// Not supposed to create the raw data sources. Do an integrity check on the pre-existing data sources instead... If there's a raw data source, but it's pointing to a non-existent measurement in the data store, that's a problem. Remove it. \todo Is there any way to incorporate this at a higher level, so that import-writers don't need to bother? for(int i=0; i<scan->rawDataSources()->count(); i++) { if(scan->rawDataSources()->at(i)->measurementId() >= scan->rawData()->measurementCount()) { errorMonitor->exteriorReport(AMErrorReport(scan, AMErrorReport::Debug, ALSBL8XASFileLoaderPLUGIN_DATA_COLUMN_MISMATCH, QString("The data in the file didn't match the raw data columns we were expecting. Removing the raw data column '%1')").arg(scan->rawDataSources()->at(i)->name()))); scan->deleteRawDataSource(i); } } return true; }
bool AMExporter2DAscii::prepareDataSources() { // This is a much stricter function than AMExporterGeneralAscii. Only 2D data sources are allowed (and when we figure out the spectra files, then also 3D). mainTableDataSources_.clear(); mainTableIncludeX_.clear(); separateSectionDataSources_.clear(); separateSectionIncludeX_.clear(); separateFileDataSources_.clear(); separateFileIncludeX_.clear(); if (option_->includeAllDataSources() && option_->firstColumnOnly()){ bool includeFirstColumn = true; for (int i = 0; i < currentScan_->dataSourceCount(); i++){ switch(currentScan_->dataSourceAt(i)->rank()){ // No 0D or 1D data sources. case 0: case 1: return false; case 2: mainTableDataSources_ << i; mainTableIncludeX_ << includeFirstColumn; // X and Y. if (includeFirstColumn) includeFirstColumn = false; break; case 3: if (option_->includeHigherDimensionSources()) separateFileDataSources_ << i; break; } } int xRange = currentScan_->scanSize(0); int yRange = currentScan_->scanSize(1); QVector<double> fillerData = QVector<double>(yRange); currentScan_->dataSourceAt(0)->values(AMnDIndex(xRange-1,0), AMnDIndex(xRange-1, yRange-1), fillerData.data()); for (int j = 0; j < yRange && yRange_ == -1; j++) if (int(fillerData.at(j)) == -1) yRange_ = j+1; // The +1 is because we want the next row. if (yRange_ != -1){ fillerData = QVector<double>(xRange); currentScan_->dataSourceAt(0)->values(AMnDIndex(0, yRange_-1), AMnDIndex(xRange-1, yRange_-1), fillerData.data()); for (int i = 0; i < xRange && xIndex_ == -1; i++) if (int(fillerData.at(i)) == -1) xIndex_ = i; } } // There isn't much to a simple 2D map. Put the X and Y in the first column and then put all the rest of the data. I don't have any other options right now. else return false; return true; }
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; }
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)); } }
void AMExporter2DAscii::writeMainTable() { QTextStream ts(file_); // 1. Column header. if(option_->columnHeaderIncluded()) { ts << "# "; for(int c=0; c<mainTableDataSources_.count(); c++) { setCurrentDataSource(mainTableDataSources_.at(c)); if(mainTableIncludeX_.at(c)) ts << currentScan_->rawData()->scanAxisAt(0).name << option_->columnDelimiter() << currentScan_->rawData()->scanAxisAt(1).name << option_->columnDelimiter(); ts << parseKeywordString(option_->columnHeader()) << option_->columnDelimiter(); } } ts << option_->newlineDelimiter() << option_->columnHeaderDelimiter() << option_->newlineDelimiter(); // 2. rows int yRange = yRange_ == -1 ? currentScan_->scanSize(1) : (yRange_-1); int xRange = currentScan_->scanSize(0); for(int y = 0; y < yRange; y++) { for (int x = 0; x < xRange; x++){ // over rows within columns for(int c=0; c<mainTableDataSources_.count(); c++) { setCurrentDataSource(mainTableDataSources_.at(c)); AMDataSource* ds = currentScan_->dataSourceAt(currentDataSourceIndex_); // print x and y column? if(mainTableIncludeX_.at(c)) { ts << ds->axisValue(0, x).toString(); ts << option_->columnDelimiter(); ts << ds->axisValue(1, y).toString(); ts << option_->columnDelimiter(); } ts << ds->value(AMnDIndex(x, y)).toString(); ts << option_->columnDelimiter(); } ts << option_->newlineDelimiter(); } } if (yRange_ != -1 && xIndex_ != -1){ for (int i = 0; i < xIndex_; i++){ // over rows within columns for(int c=0; c<mainTableDataSources_.count(); c++) { setCurrentDataSource(mainTableDataSources_.at(c)); AMDataSource* ds = currentScan_->dataSourceAt(currentDataSourceIndex_); // print x and y column? if(mainTableIncludeX_.at(c)) { ts << ds->axisValue(0,i).toString(); ts << option_->columnDelimiter(); ts << ds->axisValue(1, yRange_-1).toString(); ts << option_->columnDelimiter(); } ts << ds->value(AMnDIndex(i, yRange_-1)).toString(); ts << option_->columnDelimiter(); } ts << option_->newlineDelimiter(); } } ts << option_->newlineDelimiter(); }
void AMExporterGeneralAscii::writeMainTable() { QTextStream ts(file_); // 1. Column header. int maxTableRows = 0; if(option_->columnHeaderIncluded()) { for(int c=0; c<mainTableDataSources_.count(); c++) { setCurrentDataSource(mainTableDataSources_.at(c)); AMDataSource* ds = currentScan_->dataSourceAt(currentDataSourceIndex_); if(ds->size(0) > maxTableRows) maxTableRows = ds->size(0); // convenient... lets figure this out while we're looping through anyway // 1D data sources: if(ds->rank() == 1) { if(mainTableIncludeX_.at(c)) ts << parseKeywordString(option_->columnHeader()) << ".X" << option_->columnDelimiter(); ts << parseKeywordString(option_->columnHeader()) << option_->columnDelimiter(); } else { // 2D if(mainTableIncludeX_.at(c)) ts << parseKeywordString(option_->columnHeader()) << ".X" << option_->columnDelimiter(); // need a loop over the second axis columns for(int cc=0; cc<ds->size(1); cc++) { setCurrentColumnIndex(cc); ts << parseKeywordString(option_->columnHeader()) << "[" << ds->axisValue(1, cc).toString() << ds->axisInfoAt(1).units << "]" << option_->columnDelimiter(); } } } ts << option_->newlineDelimiter() << option_->columnHeaderDelimiter() << option_->newlineDelimiter(); } // 2. rows for(int r=0; r<maxTableRows; r++) { // over rows within columns for(int c=0; c<mainTableDataSources_.count(); c++) { setCurrentDataSource(mainTableDataSources_.at(c)); AMDataSource* ds = currentScan_->dataSourceAt(currentDataSourceIndex_); bool doPrint = (ds->size(0) > r); // print x column? if(mainTableIncludeX_.at(c)) { if(doPrint) ts << ds->axisValue(0,r).toString(); ts << option_->columnDelimiter(); } // 1D data sources: if(ds->rank() == 1) { if(doPrint) ts << ds->value(r).toString(); ts << option_->columnDelimiter(); } else if(ds->rank() == 2) { // need a loop over the second axis columns for(int cc=0; cc<ds->size(1); cc++) { if(doPrint) ts << ds->value(AMnDIndex(r,cc)).toString(); ts << option_->columnDelimiter(); } } } ts << option_->newlineDelimiter(); } }
bool AMExporter2DAscii::writeSeparateFiles(const QString &destinationFolderPath) { if (option_->higherDimensionsInRows()){ for (int s = 0, sSize = separateFileDataSources_.size(); s < sSize; s++) { setCurrentDataSource(separateFileDataSources_.at(s)); // sets currentDataSourceIndex_ AMDataSource* source = currentScan_->dataSourceAt(currentDataSourceIndex_); QFile output; QString separateFileName = parseKeywordString( destinationFolderPath % "/" % option_->separateSectionFileName() ); separateFileName = removeNonPrintableCharacters(separateFileName); if(!openFile(&output, separateFileName)) { AMErrorMon::report(AMErrorReport(this, AMErrorReport::Alert, -4, "Export failed (partially): You selected to create separate files for certain data sets. Could not open the file '" % separateFileName % "' for writing. Check that you have permission to save files there, and that a file with that name doesn't already exists.")); return false; } int spectraSize = source->size(2); QString columnDelimiter = option_->columnDelimiter(); QString newLineDelimiter = option_->newlineDelimiter(); QTextStream out(&output); int yRange = yRange_ == -1 ? currentScan_->scanSize(1) : (yRange_-1); int xRange = currentScan_->scanSize(0); for (int y = 0; y < yRange; y++){ for (int x = 0; x < xRange; x++){ QVector<double> data(spectraSize); source->values(AMnDIndex(x, y, 0), AMnDIndex(x, y, spectraSize-1), data.data()); for (int i = 0; i < spectraSize; i++) out << data.at(i) << columnDelimiter; out << newLineDelimiter; } } if (yRange_ != -1 && xIndex_ != -1){ for (int i = 0; i < xIndex_; i++){ QVector<double> data(spectraSize); source->values(AMnDIndex(i, yRange_-1, 0), AMnDIndex(i, yRange_-1, spectraSize-1), data.data()); for (int i = 0; i < spectraSize; i++) out << data.at(i) << columnDelimiter; out << newLineDelimiter; } out << newLineDelimiter; } output.close(); } } else{ for (int s = 0, sSize = separateFileDataSources_.size(); s < sSize; s++) { setCurrentDataSource(separateFileDataSources_.at(s)); // sets currentDataSourceIndex_ AMDataSource* source = currentScan_->dataSourceAt(currentDataSourceIndex_); QFile output; QString separateFileName = parseKeywordString( destinationFolderPath % "/" % option_->separateSectionFileName() ); separateFileName = removeNonPrintableCharacters(separateFileName); if(!openFile(&output, separateFileName)) { AMErrorMon::report(AMErrorReport(this, AMErrorReport::Alert, -4, "Export failed (partially): You selected to create separate files for certain data sets. Could not open the file '" % separateFileName % "' for writing. Check that you have permission to save files there, and that a file with that name doesn't already exists.")); return false; } int spectraSize = source->size(2); QString columnDelimiter = option_->columnDelimiter(); QString newLineDelimiter = option_->newlineDelimiter(); QTextStream out(&output); int yRange = yRange_ == -1 ? currentScan_->scanSize(1) : (yRange_-1); int xRange = currentScan_->scanSize(0); for (int i = 0; i < spectraSize; i++){ for (int y = 0; y < yRange; y++) for (int x = 0; x < xRange; x++) out << double(source->value(AMnDIndex(x, y, i))) << columnDelimiter; if (yRange_ != -1 && xIndex_ != -1){ for (int x = 0; x < xIndex_; x++) out << double(source->value(AMnDIndex(x, yRange_-1, i))) << columnDelimiter; } out << newLineDelimiter; } output.close(); } } return true; }
void AMExporterGeneralAscii::writeSeparateSections() { QTextStream ts(file_); for(int s=0; s<separateSectionDataSources_.count(); s++) { ts << option_->newlineDelimiter(); setCurrentDataSource(separateSectionDataSources_.at(s)); // sets currentDataSourceIndex_ AMDataSource* ds = currentScan_->dataSourceAt(currentDataSourceIndex_); // section header? if(option_->sectionHeaderIncluded()) { ts << parseKeywordString(option_->sectionHeader()); ts << option_->newlineDelimiter(); } // column header? if(option_->columnHeaderIncluded()) { // 1D data sources: if(ds->rank() == 0) { ts << parseKeywordString(option_->columnHeader()) << option_->columnDelimiter(); } else if(ds->rank() == 1) { if(separateSectionIncludeX_.at(s)) ts << parseKeywordString(option_->columnHeader()) << ".X" << option_->columnDelimiter(); ts << parseKeywordString(option_->columnHeader()) << option_->columnDelimiter(); } else if(ds->rank() == 2) { // 2D if(separateSectionIncludeX_.at(s)) ts << parseKeywordString(option_->columnHeader()) << ".X" << option_->columnDelimiter(); // need a loop over the second axis columns for(int cc=0; cc<ds->size(1); cc++) { setCurrentColumnIndex(cc); ts << parseKeywordString(option_->columnHeader()) << "[" << ds->axisValue(1, cc).toString() << ds->axisInfoAt(1).units << "]" << option_->columnDelimiter(); } } ts << option_->newlineDelimiter() << option_->columnHeaderDelimiter() << option_->newlineDelimiter(); } // table switch(ds->rank()) { case 0: ts << ds->value(AMnDIndex()).toString() << option_->columnDelimiter() << option_->newlineDelimiter(); break; case 1: { int maxTableRows = ds->size(0); for(int r=0; r<maxTableRows; r++) { if(separateSectionIncludeX_.at(s)) { ts << ds->axisValue(0,r).toString() << option_->columnDelimiter(); } ts << ds->value(r).toString() << option_->columnDelimiter() << option_->newlineDelimiter(); } } break; case 2: { int maxTableRows = ds->size(0); for(int r=0; r<maxTableRows; r++) { if(separateSectionIncludeX_.at(s)) ts << ds->axisValue(0,r).toString() << option_->columnDelimiter(); // need a loop over the second axis columns for(int cc=0; cc<ds->size(1); cc++) { ts << ds->value(AMnDIndex(r,cc)).toString() << option_->columnDelimiter(); } ts << option_->newlineDelimiter(); } } break; default: /// \todo Implement 3D break; } } }
void VESPERSExporterSMAK::writeMainTable() { QTextStream ts(file_); // 1. Column header. if(option_->columnHeaderIncluded()) { ts << "# "; for(int c=0; c<mainTableDataSources_.count(); c++) { setCurrentDataSource(mainTableDataSources_.at(c)); if(mainTableIncludeX_.at(c)) ts << "H" << option_->columnDelimiter() << "V" << option_->columnDelimiter(); ts << parseKeywordString(option_->columnHeader()) << option_->columnDelimiter(); } } ts << option_->newlineDelimiter() << option_->columnHeaderDelimiter() << option_->newlineDelimiter(); // 2. rows VESPERS2DScanConfiguration *config = qobject_cast<VESPERS2DScanConfiguration *>(const_cast<AMScanConfiguration *>(currentScan_->scanConfiguration())); if (!config) return; QString suffix; if (config->ccdDetector().testFlag(VESPERS::Roper)) suffix = "spe"; else if (config->ccdDetector().testFlag(VESPERS::Mar)) suffix = "tif"; else if (config->ccdDetector().testFlag(VESPERS::Pilatus)) suffix = "tif"; QString ccdFileName = config->ccdFileName(); int yRange = yRange_ == -1 ? currentScan_->scanSize(1) : (yRange_-1); int xRange = currentScan_->scanSize(0); for(int y = 0; y < yRange; y++) { for (int x = 0; x < xRange; x++){ // over rows within columns for(int c=0; c<mainTableDataSources_.count(); c++) { setCurrentDataSource(mainTableDataSources_.at(c)); AMDataSource* ds = currentScan_->dataSourceAt(currentDataSourceIndex_); int precision = option_->exportPrecision(ds->name()); // print x and y column? if(mainTableIncludeX_.at(c)) { ts << ds->axisValue(0,x).toString(precision); ts << option_->columnDelimiter(); ts << ds->axisValue(1, y).toString(precision); ts << option_->columnDelimiter(); } if(ds->name().contains("FileNumber")) ts << QString("%1_%2.%3").arg(ccdFileName).arg(int(ds->value(AMnDIndex(x, y)))-1).arg(suffix); // The -1 is because the value stored here is the NEXT number in the scan. Purely a nomenclature setup from the EPICS interface. else ts << ds->value(AMnDIndex(x, y)).toString(precision); ts << option_->columnDelimiter(); } ts << option_->newlineDelimiter(); } } if (yRange_ != -1 && xIndex_ != -1){ for (int x = 0; x < xIndex_; x++){ // over rows within columns for(int c=0; c<mainTableDataSources_.count(); c++) { setCurrentDataSource(mainTableDataSources_.at(c)); AMDataSource* ds = currentScan_->dataSourceAt(currentDataSourceIndex_); int precision = option_->exportPrecision(ds->name()); // print x and y column? if(mainTableIncludeX_.at(c)) { ts << ds->axisValue(0,x).toString(precision); ts << option_->columnDelimiter(); ts << ds->axisValue(1, yRange_-1).toString(precision); ts << option_->columnDelimiter(); } if(ds->name().contains("FileNumber")) ts << QString("%1_%2.%3").arg(ccdFileName).arg(int(ds->value(AMnDIndex(x, yRange_-1)))-1).arg(suffix); // The -1 is because the value stored here is the NEXT number in the scan. Purely a nomenclature setup from the EPICS interface. else ts << ds->value(AMnDIndex(x, yRange_-1)).toString(precision); ts << option_->columnDelimiter(); } ts << option_->newlineDelimiter(); } } ts << option_->newlineDelimiter(); }
bool AMExporterGeneralAscii::writeSeparateFiles(const QString& destinationFolderPath) { for(int s=0; s<separateFileDataSources_.count(); s++) { setCurrentDataSource(separateFileDataSources_.at(s)); // sets currentDataSourceIndex_ AMDataSource* ds = currentScan_->dataSourceAt(currentDataSourceIndex_); QFile file; QString separateFileName = parseKeywordString( destinationFolderPath % "/" % option_->separateSectionFileName() ); if(!openFile(&file, separateFileName)) { AMErrorMon::report(AMErrorReport(this, AMErrorReport::Alert, -4, "Export failed (partially): You selected to create separate files for certain data sets. Could not open the file '" % separateFileName % "' for writing. Check that you have permission to save files there, and that a file with that name doesn't already exists.")); return false; } QTextStream ts(&file); // section header? if(option_->sectionHeaderIncluded()) { ts << parseKeywordString(option_->sectionHeader()); ts << option_->newlineDelimiter(); } // column header? if(option_->columnHeaderIncluded()) { // 1D data sources: if(ds->rank() == 0) { ts << parseKeywordString(option_->columnHeader()) << option_->columnDelimiter(); } else if(ds->rank() == 1) { if(separateFileIncludeX_.at(s)) ts << parseKeywordString(option_->columnHeader()) << ".X" << option_->columnDelimiter(); ts << parseKeywordString(option_->columnHeader()) << option_->columnDelimiter(); } else if(ds->rank() == 2) { // 2D if(separateFileIncludeX_.at(s)) ts << parseKeywordString(option_->columnHeader()) << ".X" << option_->columnDelimiter(); // need a loop over the second axis columns for(int cc=0; cc<ds->size(1); cc++) { setCurrentColumnIndex(cc); ts << parseKeywordString(option_->columnHeader()) << "[" << ds->axisValue(1, cc).toString() << ds->axisInfoAt(1).units << "]" << option_->columnDelimiter(); } } ts << option_->newlineDelimiter() << option_->columnHeaderDelimiter() << option_->newlineDelimiter(); } // table switch(ds->rank()) { case 0: ts << ds->value(AMnDIndex()).toString() << option_->columnDelimiter() << option_->newlineDelimiter(); break; case 1: { int maxTableRows = ds->size(0); for(int r=0; r<maxTableRows; r++) { if(separateFileIncludeX_.at(s)) { ts << ds->axisValue(0,r).toString() << option_->columnDelimiter(); } ts << ds->value(r).toString() << option_->columnDelimiter() << option_->newlineDelimiter(); } } break; case 2: { int maxTableRows = ds->size(0); for(int r=0; r<maxTableRows; r++) { if(separateFileIncludeX_.at(s)) ts << ds->axisValue(0,r).toString() << option_->columnDelimiter(); // need a loop over the second axis columns for(int cc=0; cc<ds->size(1); cc++) { ts << ds->value(AMnDIndex(r,cc)).toString() << option_->columnDelimiter(); } ts << option_->newlineDelimiter(); } } break; default: /// \todo Implement 3D break; } } return true; }