Example #1
0
AMNumber AM3DAdditionAB::value(const AMnDIndex &indexes) const
{
	if(indexes.rank() != 3)
		return AMNumber(AMNumber::DimensionError);

	if(!isValid())
		return AMNumber(AMNumber::InvalidError);

	for (int i = 0; i < sources_.size(); i++)
		if (indexes.i() >= sources_.at(i)->size(0) || indexes.j() >= sources_.at(i)->size(1) || indexes.k() >= sources_.at(i)->size(2))
			return AMNumber(AMNumber::OutOfBoundsError);

    if (cacheUpdateRequired_)
        computeCachedValues();

    return cachedData_.at(indexes.i()*size(1)*size(2)+indexes.j()*size(2)+indexes.k());
}
bool AM3DDeadTimeCorrectionAB::values(const AMnDIndex &indexStart, const AMnDIndex &indexEnd, double *outputValues) const
{
	if(indexStart.rank() != 3 || indexEnd.rank() != 3)
		return false;

	if(!isValid())
		return false;

	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;

	int totalSize = indexStart.totalPointsTo(indexEnd);

	QVector<double> data = QVector<double>(totalSize);
	QVector<double> icr = QVector<double>(totalSize);
	QVector<double> ocr = QVector<double>(totalSize);
	spectra_->values(indexStart, indexEnd, data.data());
	icr_->values(indexStart, indexEnd, icr.data());
	ocr_->values(indexStart, indexEnd, 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++){

			for (int k = 0, kSize = indexEnd.k()-indexStart.k()+1; k < kSize; k++){

				int index = i + j*iSize + k*iSize*jSize;

				// 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(index) <= 0 || ocr.at(index) <= 0)
					outputValues[index] = 0;

				else
					outputValues[index] = data.at(index)*icr.at(index)/ocr.at(index);
			}
		}
	}

	return true;
}
Example #3
0
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);
}
Example #4
0
bool AM3DAdditionAB::values(const AMnDIndex &indexStart, const AMnDIndex &indexEnd, double *outputValues) const
{
	if(indexStart.rank() != 3 || indexEnd.rank() != 3)
		return false;

	if(!isValid())
		return false;

	for (int i = 0; i < sources_.size(); i++)
		if ((unsigned)indexEnd.i() >= (unsigned)axes_.at(0).size || (unsigned)indexEnd.j() >= (unsigned)axes_.at(1).size || (unsigned)indexEnd.k() >= (unsigned)axes_.at(2).size)
			return false;

	if ((unsigned)indexStart.i() > (unsigned)indexEnd.i() || (unsigned)indexStart.j() > (unsigned)indexEnd.j())
		return false;

	if (cacheUpdateRequired_)
		computeCachedValues();

	int totalSize = indexStart.totalPointsTo(indexEnd);
	memcpy(outputValues, cachedData_.constData()+indexStart.flatIndexInArrayOfSize(size()), totalSize*sizeof(double));

	return true;
}
Example #5
0
bool AM2DAdditionAB::values(const AMnDIndex &indexStart, const AMnDIndex &indexEnd, double *outputValues) const
{
	if(indexStart.rank() != 2 || indexEnd.rank() != 2)
		return false;

	if(!isValid())
		return false;

#ifdef AM_ENABLE_BOUNDS_CHECKING
	for (int i = 0; i < sources_.size(); i++)
		if ((unsigned)indexEnd.i() >= (unsigned)axes_.at(0).size || (unsigned)indexEnd.j() >= (unsigned)axes_.at(1).size)
			return false;

	if ((unsigned)indexStart.i() > (unsigned)indexEnd.i() || (unsigned)indexStart.j() > (unsigned)indexEnd.j())
		return false;
#endif

	int totalSize = indexStart.totalPointsTo(indexEnd);

	QVector<double> data = QVector<double>(totalSize);
	sources_.at(0)->values(indexStart, indexEnd, data.data());

	// Do the first data source separately to initialize the values.
	for (int i = 0; i < totalSize; i++)
		outputValues[i] = data.at(i);

	// Iterate through the rest of the sources.
	for (int i = 1, count = sources_.size(); i < count; i++){

		sources_.at(i)->values(indexStart, indexEnd, data.data());

		for (int j = 0; j < totalSize; j++)
			outputValues[j] += data.at(j);
	}

	return true;
}
Example #6
0
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;
}
AMNumber AM2DDeadTimeCorrectionAB::value(const AMnDIndex &indexes) const
{
	if(indexes.rank() != 2)
		return AMNumber(AMNumber::DimensionError);

	if(!isValid())
		return AMNumber(AMNumber::InvalidError);

	if (indexes.i() >= spectra_->size(0)
			|| indexes.j() >= spectra_->size(1))
		return AMNumber(AMNumber::OutOfBoundsError);

	if ((int)spectra_->value(indexes) == 0 || double(ocr_->value(indexes)) == 0)
		return 0;
	else
		return double(icr_->value(indexes))/double(ocr_->value(indexes))*(int)spectra_->value(indexes);
}
Example #8
0
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;
}
Example #9
0
AMNumber AM2DAdditionAB::value(const AMnDIndex &indexes) const
{
	if(indexes.rank() != 2)
		return AMNumber(AMNumber::DimensionError);

	if(!isValid())
		return AMNumber(AMNumber::InvalidError);

#ifdef AM_ENABLE_BOUNDS_CHECKING
	for (int i = 0; i < sources_.size(); i++)
		if (indexes.i() >= sources_.at(i)->size(0) || indexes.j() >= sources_.at(i)->size(1))
			return AMNumber(AMNumber::OutOfBoundsError);
#endif

	double val = 0;

	for (int i = 0; i < sources_.size(); i++)
		val += (double)sources_.at(i)->value(indexes);

	return val;
}
Example #10
0
/* This base-class implementation simply calls value() repeatedly and should absolutely be re-implemented for better performance. */
bool AMDataSource::values(const AMnDIndex &indexStart, const AMnDIndex &indexEnd, double *outputValues) const
{
    static bool programmerWarningIssued = false;
    if(!programmerWarningIssued) {
        AMErrorMon::debug(0, AMDATASOURCE_VALUES_BASE_IMPLEMENTATION_CALLED, QString("AMDataSource: Warning: Data source '%1' is using the base implementation of AMDataSource::values(), which is very inefficient. Re-implement values() to improve performance.  (This warning will only be given once.)").arg(name()));
        programmerWarningIssued = true;	// one problem with this warning method: if multiple classes have this problem, it will only be given once, and the subsequent classes will not be named.
    }

    int _rank = rank();

    if(indexStart.rank() != _rank || indexEnd.rank() != _rank)
        return false;

#ifdef AM_ENABLE_BOUNDS_CHECKING
    for(int mu=0; mu<_rank; ++mu) {
        if(indexEnd.at(mu) >= size(mu))
            return false;
        if(indexEnd.at(mu) < indexStart.at(mu))
            return false;
    }
#endif

    switch(_rank) {
    case 0:
        *outputValues = double(value(indexStart));
        break;

    case 1: {
        for(int i=indexStart.i(); i<=indexEnd.i(); ++i)
            *(outputValues++) = double(value(AMnDIndex(i)));
        break;
    }

    case 2: {
        for(int i=indexStart.i(); i<=indexEnd.i(); ++i)
            for(int j=indexStart.j(); j<=indexEnd.j(); ++j)
                *(outputValues++) = double(value(AMnDIndex(i,j)));
        break;
    }

    case 3: {
        for(int i=indexStart.i(); i<=indexEnd.i(); ++i)
            for(int j=indexStart.j(); j<=indexEnd.j(); ++j)
                for(int k=indexStart.k(); k<=indexEnd.k(); ++k)
                    *(outputValues++) = double(value(AMnDIndex(i,j,k)));
        break;
    }

    case 4: {
        for(int i=indexStart.i(); i<=indexEnd.i(); ++i)
            for(int j=indexStart.j(); j<=indexEnd.j(); ++j)
                for(int k=indexStart.k(); k<=indexEnd.k(); ++k)
                    for(int l=indexStart.l(); l<=indexEnd.l(); ++l)
                        *(outputValues++) = double(value(AMnDIndex(i,j,k,l)));
        break;
    }

    default: {
        valuesImplementationRecursive(indexStart, indexEnd, AMnDIndex(_rank, AMnDIndex::DoNotInit), 0, &outputValues);
        break;
    }
    }
    return true;
}
Example #11
0
bool AMnDDeadTimeAB::values(const AMnDIndex &indexStart, const AMnDIndex &indexEnd, double *outputValues) const
{
	if(indexStart.rank() != rank() || indexEnd.rank() != indexStart.rank())
		return false;

	if(!isValid())
		return false;

#ifdef AM_ENABLE_BOUNDS_CHECKING
	for (int i = 0, size = axes_.size(); i < size; i++)
		if (indexEnd.at(i) >= axes_.at(i).size || (unsigned)indexStart.at(i) > (unsigned)indexEnd.at(i))
			return false;
#endif

	switch(rank()){

	case 0:	// Can't happen.
		break;

	case 1:{

		int totalSize = indexStart.totalPointsTo(indexEnd);
		double inputCounts = inputCounts_->value(AMnDIndex());
		double outputCounts = outputCounts_->value(AMnDIndex());

		if (outputCounts == 0){

			QVector<double> data = QVector<double>(totalSize, 0);
			outputValues = data.data();
		}

		else {

			double scalingFactor = qAbs(inputCounts/outputCounts);

			QVector<double> data = QVector<double>(totalSize);
			spectrum_->values(indexStart, indexEnd, data.data());

			for (int i = 0, size = data.size(); i < size; i++)
				outputValues[i] = data.at(i)*scalingFactor;
		}

		break;
	}

	case 2:{

		int totalSize = indexStart.totalPointsTo(indexEnd);
		int crTotalSize = AMnDIndex(indexStart.i()).totalPointsTo(AMnDIndex(indexEnd.i()));

		QVector<double> data = QVector<double>(totalSize);
		QVector<double> inputCounts = QVector<double>(crTotalSize);
		QVector<double> outputCounts = QVector<double>(crTotalSize);
		spectrum_->values(indexStart, indexEnd, data.data());
		inputCounts_->values(indexStart.i(), indexEnd.i(), inputCounts.data());
		outputCounts_->values(indexStart.i(), indexEnd.i(), outputCounts.data());

		for (int i = 0, iSize = indexEnd.i() - indexStart.i()+1; i < iSize; i++){

			// If outputCounts is equal to 0 then that will cause division by zero.
			if (outputCounts.at(i) <= 0){

				for (int j = 0, jSize = indexEnd.j()-indexStart.j()+1; j < jSize; j++)
					outputValues[i*jSize+j] = 0;
			}

			else {

				double factor = qAbs(inputCounts.at(i)/outputCounts.at(i));

				for (int j = 0, jSize = indexEnd.j()-indexStart.j()+1; j < jSize; j++)
					outputValues[i*jSize+j] = data.at(i*jSize+j)*factor;
			}
		}

		break;
	}

	case 3:{

		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> inputCounts = QVector<double>(icrOcrTotalSize);
		QVector<double> outputCounts = QVector<double>(icrOcrTotalSize);
		spectrum_->values(indexStart, indexEnd, data.data());
		inputCounts_->values(start2D, end2D, inputCounts.data());
		outputCounts_->values(start2D, end2D, outputCounts.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++){

				int scaleFactorIndex = i*jSize+j;

				// If outputCounts is equal to 0 then that will cause division by zero.
				if (outputCounts.at(scaleFactorIndex) <= 0){

					for (int k = 0, kSize = indexEnd.k()-indexStart.k()+1; k < kSize; k++)
						outputValues[i*jSize*kSize+j*kSize+k] = 0;
				}

				else {

					double scaleFactor = qAbs(inputCounts.at(scaleFactorIndex)/outputCounts.at(scaleFactorIndex));

					for (int k = 0, kSize = indexEnd.k()-indexStart.k()+1; k < kSize; k++){

						int spectrumIndex = i*jSize*kSize+j*kSize+k;
						outputValues[spectrumIndex] = data.at(spectrumIndex)*scaleFactor;
					}
				}
			}
		}

		break;
	}

	case 4:{

		int totalSize = indexStart.totalPointsTo(indexEnd);
		AMnDIndex start3D = AMnDIndex(indexStart.i(), indexStart.j());
		AMnDIndex end3D = AMnDIndex(indexEnd.i(), indexEnd.j());
		int icrOcrTotalSize = start3D.totalPointsTo(end3D);

		QVector<double> data = QVector<double>(totalSize);
		QVector<double> inputCounts = QVector<double>(icrOcrTotalSize);
		QVector<double> outputCounts = QVector<double>(icrOcrTotalSize);
		spectrum_->values(indexStart, indexEnd, data.data());
		inputCounts_->values(start3D, end3D, inputCounts.data());
		outputCounts_->values(start3D, end3D, outputCounts.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++){

				for (int k = 0, kSize = indexEnd.k()-indexStart.k()+1; k < kSize; k++){

					int scaleFactorIndex = i*jSize*kSize+j*kSize+k;

					// If outputCounts is equal to 0 then that will cause division by zero.
					if (outputCounts.at(scaleFactorIndex) <= 0){

						for (int l = 0, lSize = indexEnd.l()-indexStart.l()+1; l < lSize; l++)
							outputValues[i*jSize*kSize*lSize+j*kSize*lSize+k*lSize+l] = 0;
					}

					else {

						double scaleFactor = qAbs(inputCounts.at(scaleFactorIndex)/outputCounts.at(scaleFactorIndex));

						for (int l = 0, lSize = indexEnd.l()-indexStart.l()+1; l < lSize; l++){

							int spectrumIndex = i*jSize*kSize*lSize+j*kSize*lSize+k*lSize+l;
							outputValues[spectrumIndex] = data.at(spectrumIndex)*scaleFactor;
						}
					}
				}
			}
		}

		break;
	}
	}

	return true;
}
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;
	}
	}
}
AMNumber AMExternalScanDataSourceAB::value(const AMnDIndex &indexes) const
{
	if(!isValid())
		return AMNumber::InvalidError;

	if(indexes.rank() != axes_.count())
		return AMNumber::DimensionError;

	switch(axes_.count()) {
	case 0:
		return values_.at(0);

	case 1:
#ifdef AM_ENABLE_BOUNDS_CHECKING
		if((unsigned)indexes.i() >= (unsigned)axes_.at(0).size)
				return AMNumber::OutOfBoundsError;
#endif
		return values_.at(indexes.i());

	case 2:
#ifdef AM_ENABLE_BOUNDS_CHECKING
		if(((unsigned)indexes.i() >= (unsigned)axes_.at(0).size ||
				(unsigned)indexes.j() >= (unsigned)axes_.at(1).size))
			return AMNumber::OutOfBoundsError;
#endif
		return values_.at(indexes.i()*axes_.at(1).size
						  + indexes.j());

	case 3: {
#ifdef AM_ENABLE_BOUNDS_CHECKING
		if(((unsigned)indexes.i() >= (unsigned)axes_.at(0).size ||
				(unsigned)indexes.j() >= (unsigned)axes_.at(1).size ||
				(unsigned)indexes.k() >= (unsigned)axes_.at(2).size))
			return AMNumber::OutOfBoundsError;
#endif

		int flatIndex = indexes.k();
		int stride = axes_.at(2).size;
		flatIndex += indexes.j()*stride;
		stride *= axes_.at(1).size;
		flatIndex += indexes.i()*stride;
		return values_.at(flatIndex);
	}

	case 4: {
#ifdef AM_ENABLE_BOUNDS_CHECKING
		if(((unsigned)indexes.i() >= (unsigned)axes_.at(0).size ||
				(unsigned)indexes.j() >= (unsigned)axes_.at(1).size ||
				(unsigned)indexes.k() >= (unsigned)axes_.at(2).size ||
				(unsigned)indexes.l() >= (unsigned)axes_.at(3).size))
			return AMNumber::OutOfBoundsError;
#endif

		int flatIndex = indexes.l();
		int stride = axes_.at(3).size;
		flatIndex += indexes.k()*stride;
		stride *= axes_.at(2).size;
		flatIndex += indexes.j()*stride;
		stride *= axes_.at(1).size;
		flatIndex += indexes.i();
		return values_.at(flatIndex);
	}

	case 5: {
#ifdef AM_ENABLE_BOUNDS_CHECKING
		if(((unsigned)indexes.i() >= (unsigned)axes_.at(0).size ||
				(unsigned)indexes.j() >= (unsigned)axes_.at(1).size ||
				(unsigned)indexes.k() >= (unsigned)axes_.at(2).size ||
				(unsigned)indexes.l() >= (unsigned)axes_.at(3).size ||
				(unsigned)indexes.m() >= (unsigned)axes_.at(4).size))
			return AMNumber::OutOfBoundsError;
#endif

		int flatIndex = indexes.m();
		int stride = axes_.at(4).size;
		flatIndex += indexes.l()*stride;
		stride *= axes_.at(3).size;
		flatIndex += indexes.k()*stride;
		stride *= axes_.at(2).size;
		flatIndex += indexes.j()*stride;
		stride *= axes_.at(1).size;
		flatIndex += indexes.i()*stride;

		return values_.at(flatIndex);
	}
	default:
		return AMNumber::InvalidError;
	}
}
Example #14
0
void AMInMemoryDataStore::measurementValues(const AMIMDSMeasurement& measurement, const AMnDIndex& fullSize, const AMnDIndex& indexStart, const AMnDIndex& indexEnd, double* outputValues) const {

	/// \todo Use memcpy once we move to a packed 64-bit size for AMNumber storage.

	switch(indexStart.rank()) {
	case 0: {
		outputValues[0] = double(measurement.at(0));
		break;
	}

	case 1: {
		for(int i=indexStart.i(); i<=indexEnd.i(); ++i)
			*(outputValues++) = double(measurement.at(i));
		break;
	}

	case 2: {
		for(int i=indexStart.i(); i<=indexEnd.i(); ++i) {
			int ic = i*fullSize.j();
			for(int j=indexStart.j(); j<=indexEnd.j(); ++j) {
				*(outputValues++) = double(measurement.at(ic+j));
			}
		}
		break;
	}

	case 3: {
		for(int i=indexStart.i(); i<=indexEnd.i(); ++i) {
			int ic = i*fullSize.j()*fullSize.k();
			for(int j=indexStart.j(); j<=indexEnd.j(); ++j) {
				int jc = j*fullSize.k();
				for(int k=indexStart.k(); k<=indexEnd.k(); ++k) {
					*(outputValues++) = double(measurement.at(ic+jc+k));
				}
			}
		}
		break;
	}

	case 4: {
		for(int i=indexStart.i(); i<=indexEnd.i(); ++i) {
			int ic = i*fullSize.j()*fullSize.k()*fullSize.l();
			for(int j=indexStart.j(); j<=indexEnd.j(); ++j) {
				int jc = j*fullSize.k()*fullSize.l();
				for(int k=indexStart.k(); k<=indexEnd.k(); ++k) {
					int kc = k*fullSize.l();
					for(int l=indexStart.l(); l<=indexEnd.l(); ++l) {
						*(outputValues++) = double(measurement.at(ic+jc+kc+l));
					}
				}
			}
		}
		break;
	}

	default: {
		// general recursive case:
		measurementValuesImplementationRecursive(measurement, indexStart, indexEnd, fullSize, &outputValues, 0, 0);
		break;
	}
	}
}
Example #15
0
bool AMInMemoryDataStore::values(const AMnDIndex &scanIndexStart, const AMnDIndex &scanIndexEnd, int measurementId, const AMnDIndex &measurementIndexStart, const AMnDIndex &measurementIndexEnd, double *outputValues) const {

	if(scanIndexStart.rank() != axes_.count() || scanIndexEnd.rank() != axes_.count())
		return false;
	if(measurementId >= measurements_.count())
		return false;

	const AMMeasurementInfo& mi = measurements_.at(measurementId);
	if(measurementIndexStart.rank() != mi.rank() || measurementIndexEnd.rank() != mi.rank())
		return false;

#ifdef AM_ENABLE_BOUNDS_CHECKING
	// check bounds for scan axes
	for(int mu=axes_.count()-1; mu >= 0; --mu) {
		if(scanIndexEnd.at(mu) < scanIndexStart.at(mu))
			return false;
		if(scanIndexEnd.at(mu) >= axes_.at(mu).size)
			return false;
	}

	// check bounds for measurement axes
	for(int mu=mi.rank()-1; mu >= 0; --mu) {
		if(measurementIndexEnd.at(mu) < measurementIndexStart.at(mu))
			return false;
		if(measurementIndexEnd.at(mu) >= mi.size(mu))
			return false;
	}
#endif

	// Determine the full size of the measurement (not necessarily the size of the block that we want to read out).
	AMnDIndex measurementSize = mi.size();
	int flatMeasurementSize = measurementSize.product();

	// specific cases of scan rank:
	switch(scanIndexStart.rank()) {
	case 0: {
		// null scan space; just copy in the measurement block

		if(measurementIndexStart.rank() == 0) {	// If measurements are scalar values, can optimize.
			outputValues[0] = double(scalarScanPoint_.at(measurementId).at(0));
		}

		else {
			// need to find out how many points one measurement block takes
			int measurementSpaceSize = measurementIndexStart.totalPointsTo(measurementIndexEnd);

			if(measurementSpaceSize == flatMeasurementSize)	// if asking for the whole measurement, can optimize.
				measurementValues(scalarScanPoint_.at(measurementId), flatMeasurementSize, outputValues);
			else
				measurementValues(scalarScanPoint_.at(measurementId), measurementSize, measurementIndexStart, measurementIndexEnd, outputValues);
		}
		break;
	}

	case 1:{
		if(measurementIndexStart.rank() == 0) {	// If measurements are scalar values, can optimize.
			for(int i=scanIndexStart.i(); i<=scanIndexEnd.i(); ++i)
				*(outputValues++) = double(scanPoints_.at(i).at(measurementId).at(0));
		}

		else {
			// need to find out how many points one measurement block takes
			int measurementSpaceSize = measurementIndexStart.totalPointsTo(measurementIndexEnd);

			if(measurementSpaceSize == flatMeasurementSize)	// if asking for the whole measurement, can optimize.
				for(int i=scanIndexStart.i(); i<=scanIndexEnd.i(); ++i) {
					measurementValues(scanPoints_.at(i).at(measurementId), flatMeasurementSize, outputValues);
					outputValues += measurementSpaceSize;
				}
			else
				for(int i=scanIndexStart.i(); i<=scanIndexEnd.i(); ++i) {
					measurementValues(scanPoints_.at(i).at(measurementId), measurementSize, measurementIndexStart, measurementIndexEnd, outputValues);
					outputValues += measurementSpaceSize;
				}
		}
		break;
	}

	case 2:{
		if(measurementIndexStart.rank() == 0) {	// If measurements are scalar values, can optimize.
			for(int i=scanIndexStart.i(); i<=scanIndexEnd.i(); ++i) {
				int ic = i*scanSize_.j();
				for(int j=scanIndexStart.j(); j<=scanIndexEnd.j(); ++j) {
					*(outputValues++) = double(scanPoints_.at(ic+j).at(measurementId).at(0));
				}
			}
		}

		else {
			// need to find out how many points one measurement block takes
			int measurementSpaceSize = measurementIndexStart.totalPointsTo(measurementIndexEnd);

			if(measurementSpaceSize == flatMeasurementSize) {	// if asking for the whole measurement, can optimize.
				for(int i=scanIndexStart.i(); i<=scanIndexEnd.i(); ++i) {
					int ic = i*scanSize_.j();
					for(int j=scanIndexStart.j(); j<=scanIndexEnd.j(); ++j) {
						measurementValues(scanPoints_.at(ic+j).at(measurementId), flatMeasurementSize, outputValues);
						outputValues += measurementSpaceSize;
					}
				}
			}
			else {
				for(int i=scanIndexStart.i(); i<=scanIndexEnd.i(); ++i) {
					int ic = i*scanSize_.j();
					for(int j=scanIndexStart.j(); j<=scanIndexEnd.j(); ++j) {
						measurementValues(scanPoints_.at(ic+j).at(measurementId), measurementSize, measurementIndexStart, measurementIndexEnd, outputValues);
						outputValues += measurementSpaceSize;
					}
				}
			}
		}
		break;
	}

	case 3:{
		if(measurementIndexStart.rank() == 0) {	// If measurements are scalar values, can optimize.
			for(int i=scanIndexStart.i(); i<=scanIndexEnd.i(); ++i) {
				int ic = i*scanSize_.j()*scanSize_.k();
				for(int j=scanIndexStart.j(); j<=scanIndexEnd.j(); ++j) {
					int jc = j*scanSize_.k();
					for(int k=scanIndexStart.k(); k<=scanIndexEnd.k(); ++k) {
						*(outputValues++) = double(scanPoints_.at(ic+jc+k).at(measurementId).at(0));
					}
				}
			}
		}

		else {
			// need to find out how many points one measurement block takes
			int measurementSpaceSize = measurementIndexStart.totalPointsTo(measurementIndexEnd);

			if(measurementSpaceSize == flatMeasurementSize) {	// if asking for the whole measurement, can optimize.
				for(int i=scanIndexStart.i(); i<=scanIndexEnd.i(); ++i) {
					int ic = i*scanSize_.j()*scanSize_.k();
					for(int j=scanIndexStart.j(); j<=scanIndexEnd.j(); ++j) {
						int jc = j*scanSize_.k();
						for(int k=scanIndexStart.k(); k<=scanIndexEnd.k(); ++k) {
							measurementValues(scanPoints_.at(ic+jc+k).at(measurementId), flatMeasurementSize, outputValues);
							outputValues += measurementSpaceSize;
						}
					}
				}
			}
			else {
				for(int i=scanIndexStart.i(); i<=scanIndexEnd.i(); ++i) {
					int ic = i*scanSize_.j()*scanSize_.k();
					for(int j=scanIndexStart.j(); j<=scanIndexEnd.j(); ++j) {
						int jc = j*scanSize_.k();
						for(int k=scanIndexStart.k(); k<=scanIndexEnd.k(); ++k) {
							measurementValues(scanPoints_.at(ic+jc+k).at(measurementId), measurementSize, measurementIndexStart, measurementIndexEnd, outputValues);
							outputValues += measurementSpaceSize;
						}
					}
				}
			}
		}
		break;
	}

	case 4:{
		if(measurementIndexStart.rank() == 0) {	// If measurements are scalar values, can optimize.
			for(int i=scanIndexStart.i(); i<=scanIndexEnd.i(); ++i) {
				int ic = i*scanSize_.j()*scanSize_.k()*scanSize_.l();
				for(int j=scanIndexStart.j(); j<=scanIndexEnd.j(); ++j) {
					int jc = j*scanSize_.k()*scanSize_.l();
					for(int k=scanIndexStart.k(); k<=scanIndexEnd.k(); ++k) {
						int kc = k*scanSize_.l();
						for(int l=scanIndexStart.l(); l<=scanIndexEnd.l(); ++l) {
							*(outputValues++) = double(scanPoints_.at(ic+jc+kc+l).at(measurementId).at(0));
						}
					}
				}
			}
		}

		else {
			int measurementSpaceSize = measurementIndexStart.totalPointsTo(measurementIndexEnd);

			if(measurementSpaceSize == flatMeasurementSize) {	// if asking for the whole measurement, can optimize.
				for(int i=scanIndexStart.i(); i<=scanIndexEnd.i(); ++i) {
					int ic = i*scanSize_.j()*scanSize_.k()*scanSize_.l();
					for(int j=scanIndexStart.j(); j<=scanIndexEnd.j(); ++j) {
						int jc = j*scanSize_.k()*scanSize_.l();
						for(int k=scanIndexStart.k(); k<=scanIndexEnd.k(); ++k) {
							int kc = k*scanSize_.l();
							for(int l=scanIndexStart.l(); l<=scanIndexEnd.l(); ++l) {
								measurementValues(scanPoints_.at(ic+jc+kc+l).at(measurementId), flatMeasurementSize, outputValues);
								outputValues += measurementSpaceSize;
							}
						}
					}
				}
			}
			else {
				for(int i=scanIndexStart.i(); i<=scanIndexEnd.i(); ++i) {
					int ic = i*scanSize_.j()*scanSize_.k()*scanSize_.l();
					for(int j=scanIndexStart.j(); j<=scanIndexEnd.j(); ++j) {
						int jc = j*scanSize_.k()*scanSize_.l();
						for(int k=scanIndexStart.k(); k<=scanIndexEnd.k(); ++k) {
							int kc = k*scanSize_.l();
							for(int l=scanIndexStart.l(); l<=scanIndexEnd.l(); ++l) {
								measurementValues(scanPoints_.at(ic+jc+kc+l).at(measurementId), measurementSize, measurementIndexStart, measurementIndexEnd, outputValues);
								outputValues += measurementSpaceSize;
							}
						}
					}
				}
			}
		}
		break;
	}
	default:{
		int measurementSpaceSize = measurementIndexStart.totalPointsTo(measurementIndexEnd);

		valuesImplementationRecursive(scanIndexStart, scanIndexEnd, measurementId, measurementIndexStart, measurementIndexEnd, &outputValues, 0, 0, measurementSize, measurementSpaceSize);
		return false;
		break;
	}
	}

	return true;
}