//# ScaledComplexData.cc: Templated virtual column engine to scale a complex table array //# Copyright (C) 1999,2000,2001 //# Associated Universities, Inc. Washington DC, USA. //# //# This library is free software; you can redistribute it and/or modify it //# under the terms of the GNU Library General Public License as published by //# the Free Software Foundation; either version 2 of the License, or (at your //# option) any later version. //# //# This library is distributed in the hope that it will be useful, but WITHOUT //# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or //# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public //# License for more details. //# //# You should have received a copy of the GNU Library General Public License //# along with this library; if not, write to the Free Software Foundation, //# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA. //# //# Correspondence concerning AIPS++ should be addressed as follows: //# Internet email: aips2-request@nrao.edu. //# Postal address: AIPS++ Project Office //# National Radio Astronomy Observatory //# 520 Edgemont Road //# Charlottesville, VA 22903-2475 USA //# //# $Id$ #ifndef TABLES_SCALEDCOMPLEXDATA_TCC #define TABLES_SCALEDCOMPLEXDATA_TCC //# Includes #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include namespace casacore { //# NAMESPACE CASACORE - BEGIN template ScaledComplexData::ScaledComplexData (const String& virtualColumnName, const String& storedColumnName, S scale, S offset) : BaseMappedArrayEngine (virtualColumnName, storedColumnName), scale_p (scale), offset_p (offset), fixedScale_p (True), fixedOffset_p (True), scaleColumn_p (0), offsetColumn_p(0) {} template ScaledComplexData::ScaledComplexData (const String& virtualColumnName, const String& storedColumnName, const String& scaleColumnName, S offset) : BaseMappedArrayEngine (virtualColumnName, storedColumnName), scaleName_p (scaleColumnName), scale_p (S(0.0, 0.0)), offset_p (offset), fixedScale_p (False), fixedOffset_p (True), scaleColumn_p (0), offsetColumn_p(0) {} template ScaledComplexData::ScaledComplexData (const String& virtualColumnName, const String& storedColumnName, const String& scaleColumnName, const String& offsetColumnName) : BaseMappedArrayEngine (virtualColumnName, storedColumnName), scaleName_p (scaleColumnName), offsetName_p (offsetColumnName), scale_p (S(0.0, 0.0)), offset_p (S(0.0, 0.0)), fixedScale_p (False), fixedOffset_p (False), scaleColumn_p (0), offsetColumn_p(0) {} template ScaledComplexData::ScaledComplexData (const ScaledComplexData& that) : BaseMappedArrayEngine (that), scaleName_p (that.scaleName_p), offsetName_p (that.offsetName_p), scale_p (that.scale_p), offset_p (that.offset_p), fixedScale_p (that.fixedScale_p), fixedOffset_p (that.fixedOffset_p), scaleColumn_p (0), offsetColumn_p(0) {} template ScaledComplexData::ScaledComplexData (const Record& spec) : BaseMappedArrayEngine (), scale_p (S(1.0, 1.0)), offset_p (S(0.0, 0.0)), fixedScale_p (True), fixedOffset_p (True), scaleColumn_p (0), offsetColumn_p(0) { if (spec.isDefined("SOURCENAME") && spec.isDefined("TARGETNAME")) { setNames (spec.asString("SOURCENAME"), spec.asString("TARGETNAME")); if (spec.isDefined("SCALE")) { spec.get ("SCALE", scale_p); } else { spec.get ("SCALENAME", scaleName_p); fixedScale_p = False; } if (spec.isDefined("OFFSET")) { spec.get ("OFFSET", offset_p); } else { spec.get ("OFFSETNAME", offsetName_p); fixedOffset_p = False; } } } template ScaledComplexData::~ScaledComplexData() { delete scaleColumn_p; delete offsetColumn_p; } //# Clone the engine object. template DataManager* ScaledComplexData::clone() const { DataManager* dmPtr = new ScaledComplexData (*this); return dmPtr; } //# Return the type name of the engine (i.e. its class name). template String ScaledComplexData::dataManagerType() const { return className(); } //# Return the class name. //# Get the data type names using class ValType. template String ScaledComplexData::className() { return "ScaledComplexData<" + valDataTypeId ((S*)0) + "," + valDataTypeId ((T*)0) + ">"; } template Record ScaledComplexData::dataManagerSpec() const { Record spec; spec.define ("SOURCENAME", virtualName()); spec.define ("TARGETNAME", storedName()); if (fixedScale_p) { spec.define ("SCALE", scale_p); } else { spec.define ("SCALENAME", scaleName_p); } if (fixedOffset_p) { spec.define ("OFFSET", offset_p); } else { spec.define ("OFFSETNAME", offsetName_p); } return spec; } template DataManager* ScaledComplexData::makeObject (const String&, const Record& spec) { return new ScaledComplexData (spec); } template void ScaledComplexData::registerClass() { DataManager::registerCtor (className(), makeObject); } template void ScaledComplexData::create64 (rownr_t initialNrrow) { BaseMappedArrayEngine::create64 (initialNrrow); // Store the various parameters as keywords in this column. TableColumn thisCol (table(), virtualName()); thisCol.rwKeywordSet().define ("_ScaledComplexData_Scale", scale_p); thisCol.rwKeywordSet().define ("_ScaledComplexData_Offset", offset_p); thisCol.rwKeywordSet().define ("_ScaledComplexData_ScaleName", scaleName_p); thisCol.rwKeywordSet().define ("_ScaledComplexData_OffsetName", offsetName_p); thisCol.rwKeywordSet().define ("_ScaledComplexData_FixedScale", fixedScale_p); thisCol.rwKeywordSet().define ("_ScaledComplexData_FixedOffset", fixedOffset_p); } template void ScaledComplexData::prepare() { BaseMappedArrayEngine::prepare(); TableColumn thisCol (table(), virtualName()); thisCol.keywordSet().get ("_ScaledComplexData_Scale", scale_p); thisCol.keywordSet().get ("_ScaledComplexData_Offset", offset_p); thisCol.keywordSet().get ("_ScaledComplexData_ScaleName", scaleName_p); thisCol.keywordSet().get ("_ScaledComplexData_OffsetName", offsetName_p); thisCol.keywordSet().get ("_ScaledComplexData_FixedScale", fixedScale_p); thisCol.keywordSet().get ("_ScaledComplexData_FixedOffset", fixedOffset_p); //# Allocate column objects to get scale and offset. if (! fixedScale_p) { scaleColumn_p = new ScalarColumn (table(), scaleName_p); } if (! fixedOffset_p) { offsetColumn_p = new ScalarColumn (table(), offsetName_p); } } //# This function is called in case the virtual column has FixedShape arrays. template void ScaledComplexData::setShapeColumn (const IPosition& shape) { BaseMappedArrayEngine::setShapeColumn (storedShape(shape)); } template void ScaledComplexData::setShape (rownr_t rownr, const IPosition& shape) { BaseMappedArrayEngine::setShape (rownr, storedShape(shape)); } template uInt ScaledComplexData::ndim (rownr_t rownr) { return column().ndim (rownr) - 1; } template IPosition ScaledComplexData::shape (rownr_t rownr) { // The virtual shape is the stored shape minus the first dimensions. IPosition storedShape = column().shape (rownr); return storedShape.getLast (storedShape.nelements() - 1); } template S ScaledComplexData::getScale (rownr_t rownr) { if (fixedScale_p) { return scale_p; } return (*scaleColumn_p)(rownr); } template S ScaledComplexData::getOffset (rownr_t rownr) { if (fixedOffset_p) { return offset_p; } return (*offsetColumn_p)(rownr); } // Scale/offset an array for get. template void ScaledComplexData::scaleOnGet (S scale, S offset, Array& array, const Array& target) { Bool deleteIn, deleteOut; S* out = array.getStorage (deleteOut); S* op = out; const T* in = target.getStorage (deleteIn); const T* ip = in; const T* last = ip + target.nelements(); if (offset == S(0.0, 0.0)) { if (scale == S(1.0, 1.0)) { while (ip < last) { /// op->real() = *ip++; /// op->imag() = *ip++; *op = S(*ip, ip[1]); ip++; ip++; op++; } }else{ while (ip < last) { /// op->real() = *ip++ * scale.real(); /// op->imag() = *ip++ * scale.imag(); *op = S(*ip * scale.real(), ip[1] * scale.imag()); ip++; ip++; op++; } } }else{ if (scale == S(1.0, 1.0)) { while (ip < last) { /// op->real() = *ip++ + offset.real(); /// op->imag() = *ip++ + offset.imag(); *op = S(*ip + offset.real(), ip[1] + offset.imag()); ip++; ip++; op++; } }else{ while (ip < last) { /// op->real() = *ip++ * scale.real() + offset.real(); /// op->imag() = *ip++ * scale.imag() + offset.imag(); *op = S(*ip * scale.real() + offset.real(), ip[1] * scale.imag() + offset.imag()); ip++; ip++; op++; } } } target.freeStorage (in, deleteIn); array.putStorage (out, deleteOut); } // Scale/offset an array for put. template void ScaledComplexData::scaleOnPut (S scale, S offset, const Array& array, Array& target) { Bool deleteIn, deleteOut; const S* in = array.getStorage (deleteIn); const S* ip = in; T* out = target.getStorage (deleteOut); T* op = out; const T* last = op + target.nelements(); if (offset == S(0.0, 0.0)) { if (scale == S(1.0, 1.0)) { while (op < last) { *op++ = T(ip->real()); *op++ = T(ip->imag()); ip++; } }else{ while (op < last) { *op++ = T(ip->real() / scale.real()); *op++ = T(ip->imag() / scale.imag()); ip++; } } }else{ if (scale == S(1.0, 1.0)) { while (op < last) { *op++ = T(ip->real() - offset.real()); *op++ = T(ip->imag() - offset.imag()); ip++; } }else{ while (op < last) { *op++ = T((ip->real() - offset.real()) / scale.real()); *op++ = T((ip->imag() - offset.imag()) / scale.imag()); ip++; } } } array.freeStorage (in, deleteIn); target.putStorage (out, deleteOut); } template void ScaledComplexData::scaleColumnOnGet (Array& array, const Array& target) { if (fixedScale_p && fixedOffset_p) { scaleOnGet (scale_p, offset_p, array, target); }else{ ArrayIterator arrayIter (array, array.ndim() - 1); ReadOnlyArrayIterator targetIter (target, target.ndim() - 1); rownr_t rownr = 0; while (! arrayIter.pastEnd()) { scaleOnGet (getScale(rownr), getOffset(rownr), arrayIter.array(), targetIter.array()); rownr++; arrayIter.next(); targetIter.next(); } } } template void ScaledComplexData::scaleColumnOnPut (const Array& array, Array& target) { if (fixedScale_p && fixedOffset_p) { scaleOnPut (scale_p, offset_p, array, target); }else{ ReadOnlyArrayIterator arrayIter (array, array.ndim() - 1); ArrayIterator targetIter (target, target.ndim() - 1); rownr_t rownr = 0; while (! arrayIter.pastEnd()) { scaleOnPut (getScale(rownr), getOffset(rownr), arrayIter.array(), targetIter.array()); rownr++; arrayIter.next(); targetIter.next(); } } } template void ScaledComplexData::scaleCellsOnGet (Array& array, const Array& target, const RefRows& rownrs) { if (fixedScale_p && fixedOffset_p) { scaleOnGet (scale_p, offset_p, array, target); }else{ ArrayIterator arrayIter (array, array.ndim() - 1); ReadOnlyArrayIterator targetIter (target, target.ndim() - 1); RefRowsSliceIter rowiter(rownrs); while (! rowiter.pastEnd()) { rownr_t rownr = rowiter.sliceStart(); rownr_t end = rowiter.sliceEnd(); rownr_t incr = rowiter.sliceIncr(); // Iterate through the row numbers in the slice. while (rownr <= end) { scaleOnGet (getScale(rownr), getOffset(rownr), arrayIter.array(), targetIter.array()); rownr += incr; arrayIter.next(); targetIter.next(); } // Go to next slice. rowiter++; } } } template void ScaledComplexData::scaleCellsOnPut (const Array& array, Array& target, const RefRows& rownrs) { if (fixedScale_p && fixedOffset_p) { scaleOnPut (scale_p, offset_p, array, target); }else{ ReadOnlyArrayIterator arrayIter (array, array.ndim() - 1); ArrayIterator targetIter (target, target.ndim() - 1); RefRowsSliceIter rowiter(rownrs); while (! rowiter.pastEnd()) { rownr_t rownr = rowiter.sliceStart(); rownr_t end = rowiter.sliceEnd(); rownr_t incr = rowiter.sliceIncr(); // Iterate through the row numbers in the slice. while (rownr <= end) { scaleOnPut (getScale(rownr), getOffset(rownr), arrayIter.array(), targetIter.array()); rownr += incr; arrayIter.next(); targetIter.next(); } // Go to next slice. rowiter++; } } } template void ScaledComplexData::getArray (rownr_t rownr, Array& array) { Array target(storedShape(array.shape())); column().get (rownr, target); scaleOnGet (getScale(rownr), getOffset(rownr), array, target); } template void ScaledComplexData::putArray (rownr_t rownr, const Array& array) { Array target(storedShape(array.shape())); scaleOnPut (getScale(rownr), getOffset(rownr), array, target); column().put (rownr, target); } template void ScaledComplexData::getSlice (rownr_t rownr, const Slicer& slicer, Array& array) { Array target(storedShape(array.shape())); column().getSlice (rownr, storedSlicer(slicer), target); scaleOnGet (getScale(rownr), getOffset(rownr), array, target); } template void ScaledComplexData::putSlice (rownr_t rownr, const Slicer& slicer, const Array& array) { Array target(storedShape(array.shape())); scaleOnPut (getScale(rownr), getOffset(rownr), array, target); column().putSlice (rownr, storedSlicer(slicer), target); } template void ScaledComplexData::getArrayColumn (Array& array) { Array target(storedShape(array.shape())); column().getColumn (target); scaleColumnOnGet (array, target); } template void ScaledComplexData::putArrayColumn (const Array& array) { Array target(storedShape(array.shape())); scaleColumnOnPut (array, target); column().putColumn (target); } template void ScaledComplexData::getArrayColumnCells (const RefRows& rownrs, Array& array) { Array target(storedShape(array.shape())); column().getColumnCells (rownrs, target); scaleCellsOnGet (array, target, rownrs); } template void ScaledComplexData::putArrayColumnCells (const RefRows& rownrs, const Array& array) { Array target(storedShape(array.shape())); scaleCellsOnPut (array, target, rownrs); column().putColumnCells (rownrs, target); } template void ScaledComplexData::getColumnSlice (const Slicer& slicer, Array& array) { Array target(storedShape(array.shape())); column().getColumn (storedSlicer(slicer), target); scaleColumnOnGet (array, target); } template void ScaledComplexData::putColumnSlice (const Slicer& slicer, const Array& array) { Array target(storedShape(array.shape())); scaleColumnOnPut (array, target); column().putColumn (storedSlicer(slicer), target); } template void ScaledComplexData::getColumnSliceCells (const RefRows& rownrs, const Slicer& slicer, Array& array) { Array target(storedShape(array.shape())); column().getColumnCells (rownrs, storedSlicer(slicer), target); scaleCellsOnGet (array, target, rownrs); } template void ScaledComplexData::putColumnSliceCells (const RefRows& rownrs, const Slicer& slicer, const Array& array) { Array target(storedShape(array.shape())); scaleCellsOnPut (array, target, rownrs); column().putColumnCells (rownrs, storedSlicer(slicer), target); } template Slicer ScaledComplexData::storedSlicer (const Slicer& virtualSlicer) const { return Slicer (IPosition(1,0).concatenate (virtualSlicer.start()), IPosition(1,1).concatenate (virtualSlicer.end()), IPosition(1,1).concatenate (virtualSlicer.stride()), Slicer::endIsLast); } } //# NAMESPACE CASACORE - END #endif