//# ScaledArrayEngine.cc: Templated virtual column engine to scale a table array //# Copyright (C) 1994,1995,1996,1997,1999,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_SCALEDARRAYENGINE_TCC #define TABLES_SCALEDARRAYENGINE_TCC //# Includes #include #include #include #include #include #include #include #include #include #include #include #include namespace casacore { //# NAMESPACE CASACORE - BEGIN template ScaledArrayEngine::ScaledArrayEngine (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 ScaledArrayEngine::ScaledArrayEngine (const String& virtualColumnName, const String& storedColumnName, const String& scaleColumnName, S offset) : BaseMappedArrayEngine (virtualColumnName, storedColumnName), scaleName_p (scaleColumnName), scale_p (0.0), offset_p (offset), fixedScale_p (False), fixedOffset_p (True), scaleColumn_p (0), offsetColumn_p(0) {} template ScaledArrayEngine::ScaledArrayEngine (const String& virtualColumnName, const String& storedColumnName, const String& scaleColumnName, const String& offsetColumnName) : BaseMappedArrayEngine (virtualColumnName, storedColumnName), scaleName_p (scaleColumnName), offsetName_p (offsetColumnName), scale_p (0.0), offset_p (0.0), fixedScale_p (False), fixedOffset_p (False), scaleColumn_p (0), offsetColumn_p(0) {} template ScaledArrayEngine::ScaledArrayEngine (const Record& spec) : BaseMappedArrayEngine (), scale_p (1.0), offset_p (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 ScaledArrayEngine::ScaledArrayEngine (const ScaledArrayEngine& 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 ScaledArrayEngine::~ScaledArrayEngine() { delete scaleColumn_p; delete offsetColumn_p; } //# Clone the engine object. template DataManager* ScaledArrayEngine::clone() const { DataManager* dmPtr = new ScaledArrayEngine (*this); return dmPtr; } //# Return the type name of the engine (i.e. its class name). template String ScaledArrayEngine::dataManagerType() const { return className(); } //# Return the class name. //# Get the data type names using class ValType. template String ScaledArrayEngine::className() { return "ScaledArrayEngine<" + valDataTypeId (static_cast(0)) + "," + valDataTypeId (static_cast(0)) + ">"; } template String ScaledArrayEngine::dataManagerName() const { return virtualName(); } template Record ScaledArrayEngine::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 ("SCALE", scale_p); } else { spec.define ("SCALENAME", scaleName_p); } return spec; } template DataManager* ScaledArrayEngine::makeObject (const String&, const Record& spec) { DataManager* dmPtr = new ScaledArrayEngine(spec); return dmPtr; } template void ScaledArrayEngine::registerClass() { DataManager::registerCtor (className(), makeObject); } template void ScaledArrayEngine::create64 (rownr_t initialNrrow) { BaseMappedArrayEngine::create64 (initialNrrow); // Store the various parameters as keywords in this column. TableColumn thisCol (table(), virtualName()); thisCol.rwKeywordSet().define ("_ScaledArrayEngine_Scale", scale_p); thisCol.rwKeywordSet().define ("_ScaledArrayEngine_Offset", offset_p); thisCol.rwKeywordSet().define ("_ScaledArrayEngine_ScaleName", scaleName_p); thisCol.rwKeywordSet().define ("_ScaledArrayEngine_OffsetName", offsetName_p); thisCol.rwKeywordSet().define ("_ScaledArrayEngine_FixedScale", fixedScale_p); thisCol.rwKeywordSet().define ("_ScaledArrayEngine_FixedOffset", fixedOffset_p); } template void ScaledArrayEngine::prepare() { BaseMappedArrayEngine::prepare(); TableColumn thisCol (table(), virtualName()); thisCol.keywordSet().get ("_ScaledArrayEngine_Scale", scale_p); thisCol.keywordSet().get ("_ScaledArrayEngine_Offset", offset_p); thisCol.keywordSet().get ("_ScaledArrayEngine_ScaleName", scaleName_p); thisCol.keywordSet().get ("_ScaledArrayEngine_OffsetName", offsetName_p); thisCol.keywordSet().get ("_ScaledArrayEngine_FixedScale", fixedScale_p); thisCol.keywordSet().get ("_ScaledArrayEngine_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); } } template S ScaledArrayEngine::getScale (rownr_t rownr) { if (fixedScale_p) { return scale_p; } return (*scaleColumn_p)(rownr); } template S ScaledArrayEngine::getOffset (rownr_t rownr) { if (fixedOffset_p) { return offset_p; } return (*offsetColumn_p)(rownr); } // Scale/offset an array for get. template void ScaledArrayEngine::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 + array.nelements(); if (offset == 0) { if (scale == 1) { while (ip < last) { *op++ = *ip++; } }else{ while (ip < last) { *op++ = *ip++ * scale; } } }else{ if (scale == 1) { while (ip < last) { *op++ = *ip++ + offset; } }else{ while (ip < last) { *op++ = *ip++ * scale + offset; } } } target.freeStorage (in, deleteIn); array.putStorage (out, deleteOut); } // Scale/offset an array for put. template void ScaledArrayEngine::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 + array.nelements(); if (offset == 0) { if (scale == 1) { while (op < last) { *op++ = T(*ip++); } }else{ while (op < last) { *op++ = T(*ip++ / scale); } } }else{ if (scale == 1) { while (op < last) { *op++ = T(*ip++ - offset); } }else{ while (op < last) { *op++ = T((*ip++ - offset) / scale); } } } array.freeStorage (in, deleteIn); target.putStorage (out, deleteOut); } template void ScaledArrayEngine::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 ScaledArrayEngine::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 ScaledArrayEngine::getArray (rownr_t rownr, Array& array) { Array target(array.shape()); column().get (rownr, target); scaleOnGet (getScale(rownr), getOffset(rownr), array, target); } template void ScaledArrayEngine::putArray (rownr_t rownr, const Array& array) { Array target(array.shape()); scaleOnPut (getScale(rownr), getOffset(rownr), array, target); column().put (rownr, target); } template void ScaledArrayEngine::getSlice (rownr_t rownr, const Slicer& slicer, Array& array) { Array target(array.shape()); column().getSlice (rownr, slicer, target); scaleOnGet (getScale(rownr), getOffset(rownr), array, target); } template void ScaledArrayEngine::putSlice (rownr_t rownr, const Slicer& slicer, const Array& array) { Array target(array.shape()); scaleOnPut (getScale(rownr), getOffset(rownr), array, target); column().putSlice (rownr, slicer, target); } template void ScaledArrayEngine::getArrayColumn (Array& array) { Array target(array.shape()); column().getColumn (target); scaleColumnOnGet (array, target); } template void ScaledArrayEngine::putArrayColumn (const Array& array) { Array target(array.shape()); scaleColumnOnPut (array, target); column().putColumn (target); } template void ScaledArrayEngine::getColumnSlice (const Slicer& slicer, Array& array) { Array target(array.shape()); column().getColumn (slicer, target); scaleColumnOnGet (array, target); } template void ScaledArrayEngine::putColumnSlice (const Slicer& slicer, const Array& array) { Array target(array.shape()); scaleColumnOnPut (array, target); column().putColumn (slicer, target); } } //# NAMESPACE CASACORE - END #endif