//# QuantumHolder.cc: A holder for Quantum to enable record conversions //# Copyright (C) 1998,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$ //# Includes #include #include #include #include #include #include #include #include #include #include #include namespace casacore { //# NAMESPACE CASACORE - BEGIN //# Constructors QuantumHolder::QuantumHolder() : hold_p() {} QuantumHolder::QuantumHolder(const QBase &in) : hold_p(in.clone()) {} QuantumHolder::QuantumHolder(const QuantumHolder &other) : RecordTransformable(), hold_p() { if (other.hold_p.ptr()) hold_p.set(other.hold_p.ptr()->clone()); } //# Destructor QuantumHolder::~QuantumHolder() {} //# Operators QuantumHolder &QuantumHolder::operator=(const QuantumHolder &other) { if (this != &other) { if (other.hold_p.ptr()) { hold_p.set(other.hold_p.ptr()->clone()); } else { hold_p.clear(); } } return *this; } //# Member Functions Bool QuantumHolder::isEmpty() const { return (!hold_p.ptr()); } Bool QuantumHolder::isQuantum() const { return (hold_p.ptr()); } Bool QuantumHolder::isScalar() const { return (hold_p.ptr() && nelements() == 1); } Bool QuantumHolder::isVector() const { return (hold_p.ptr() && ndim() == 1); } Bool QuantumHolder::isArray() const { return (hold_p.ptr() && ndim() > 0); } Bool QuantumHolder::isReal() const { return (hold_p.ptr() && (isQuantumDouble() || isQuantumFloat() || isQuantumInt() || isQuantumArrayDouble() || isQuantumArrayFloat() || isQuantumArrayInt())); } Bool QuantumHolder::isComplex() const { return (hold_p.ptr() && (isQuantumComplex() || isQuantumDComplex() || isQuantumArrayComplex() || isQuantumArrayDComplex())); } Bool QuantumHolder::isQuantity() const { return (hold_p.ptr() && isQuantumDouble()); } Bool QuantumHolder::isQuantumDouble() const { return (hold_p.ptr() && hold_p.ptr()->type() == Quantum::myType()); } Bool QuantumHolder::isQuantumFloat() const { return (hold_p.ptr() && hold_p.ptr()->type() == Quantum::myType()); } Bool QuantumHolder::isQuantumInt() const { return (hold_p.ptr() && hold_p.ptr()->type() == Quantum::myType()); } Bool QuantumHolder::isQuantumComplex() const { return (hold_p.ptr() && hold_p.ptr()->type() == Quantum::myType()); } Bool QuantumHolder::isQuantumDComplex() const { return (hold_p.ptr() && hold_p.ptr()->type() == Quantum::myType()); } Bool QuantumHolder::isQuantumArrayDouble() const { return (hold_p.ptr() && (hold_p.ptr()->type() == Quantum >::myType() || hold_p.ptr()->type() == Quantum >::myType())); } Bool QuantumHolder::isQuantumArrayFloat() const { return (hold_p.ptr() && (hold_p.ptr()->type() == Quantum >::myType() || hold_p.ptr()->type() == Quantum >::myType())); } Bool QuantumHolder::isQuantumArrayInt() const { return (hold_p.ptr() && (hold_p.ptr()->type() == Quantum >::myType() || hold_p.ptr()->type() == Quantum >::myType())); } Bool QuantumHolder::isQuantumArrayComplex() const { return (hold_p.ptr() && (hold_p.ptr()->type() == Quantum >::myType() || hold_p.ptr()->type() == Quantum >::myType())); } Bool QuantumHolder::isQuantumArrayDComplex() const { return (hold_p.ptr() && (hold_p.ptr()->type() == Quantum >::myType() || hold_p.ptr()->type() == Quantum >::myType())); } Bool QuantumHolder::isQuantumVectorDouble() const { return (isQuantumArrayDouble() && ndim() == 1); } Bool QuantumHolder::isQuantumVectorFloat() const { return (isQuantumArrayFloat() && ndim() == 1); } Bool QuantumHolder::isQuantumVectorInt() const { return (isQuantumArrayInt() && ndim() == 1); } Bool QuantumHolder::isQuantumVectorComplex() const { return (isQuantumArrayComplex() && ndim() == 1); } Bool QuantumHolder::isQuantumVectorDComplex() const { return (isQuantumArrayDComplex() && ndim() == 1); } Int QuantumHolder::nelements() const { if (!hold_p.ptr()) { throw(AipsError("Empty QuantumHolder argument for nelements")); } else if (isQuantumArrayDouble()) { return ((Quantum > *)(hold_p.ptr()))->getValue().nelements(); } else if (isQuantumArrayFloat()) { return ((Quantum > *)(hold_p.ptr()))->getValue().nelements(); } else if (isQuantumArrayInt()) { return ((Quantum > *)(hold_p.ptr()))->getValue().nelements(); } else if (isQuantumArrayComplex()) { return ((Quantum > *)(hold_p.ptr()))->getValue().nelements(); } else if (isQuantumArrayDComplex()) { return ((Quantum > *)(hold_p.ptr()))->getValue().nelements(); } return 1; } Int QuantumHolder::ndim() const { if (!hold_p.ptr()) { throw(AipsError("Empty QuantumHolder argument for ndim")); } else if (isQuantumArrayDouble()) { return ((Quantum > *)(hold_p.ptr()))->getValue().ndim(); } else if (isQuantumArrayFloat()) { return ((Quantum > *)(hold_p.ptr()))->getValue().ndim(); } else if (isQuantumArrayInt()) { return ((Quantum > *)(hold_p.ptr()))->getValue().ndim(); } else if (isQuantumArrayComplex()) { return ((Quantum > *)(hold_p.ptr()))->getValue().ndim(); } else if (isQuantumArrayDComplex()) { return ((Quantum > *)(hold_p.ptr()))->getValue().ndim(); } return 0; } const QBase &QuantumHolder::asQuantum() const { if (!hold_p.ptr()) { throw(AipsError("Empty QuantumHolder argument for asQuantum")); } return *hold_p.ptr(); } const Quantum &QuantumHolder::asQuantity() { if (!hold_p.ptr()) { throw(AipsError("Empty QuantumHolder argument for asQuantumDouble")); } if (!isReal() || !isScalar()) { throw(AipsError("Wrong QuantumHolder to convert asQuantumDouble")); } if (!isQuantity()) toReal(Quantum::myType()); return (const Quantum &) *hold_p.ptr(); } const Quantum &QuantumHolder::asQuantumDouble() { return asQuantity(); } const Quantum &QuantumHolder::asQuantumFloat() { if (!hold_p.ptr()) { throw(AipsError("Empty QuantumHolder argument for asQuantumFloat")); } if (!isReal() || !isScalar()) { throw(AipsError("Wrong QuantumHolder to convert asQuantumFloat")); } if (!isQuantumFloat()) toReal(Quantum::myType()); return (const Quantum &) *hold_p.ptr(); } const Quantum &QuantumHolder::asQuantumInt() { if (!hold_p.ptr()) { throw(AipsError("Empty QuantumHolder argument for asQuantumInt")); } if (!isReal() || !isScalar()) { throw(AipsError("Wrong QuantumHolder to convert asQuantumInt")); } if (!isQuantumInt()) toReal(Quantum::myType()); return (const Quantum &) *hold_p.ptr(); } const Quantum &QuantumHolder::asQuantumComplex() { if (!hold_p.ptr()) { throw(AipsError("Empty QuantumHolder argument for asQuantumComplex")); } if (!isScalar()) { throw(AipsError("Wrong QuantumHolder to convert asQuantumComplex")); } if (!isQuantumComplex()) toComplex(Quantum::myType()); return (const Quantum &) *hold_p.ptr(); } const Quantum &QuantumHolder::asQuantumDComplex() { if (!hold_p.ptr()) { throw(AipsError("Empty QuantumHolder argument for asQuantumDComplex")); } if (!isScalar()) { throw(AipsError("Wrong QuantumHolder to convert asQuantumDComplex")); } if (!isQuantumDComplex()) toComplex(Quantum::myType()); return (const Quantum &) *hold_p.ptr(); } const Quantum > &QuantumHolder::asQuantumVectorDouble() { if (!hold_p.ptr()) { throw(AipsError("Empty QuantumHolder argument for asQuantumVectorDouble")); } if (isArray()) { if (!isQuantumArrayDouble()) { throw(AipsError("Cannot convert to QuantumVectorDouble")); } if (ndim() != 1) { ((Quantum > *)(hold_p.ptr()))->getValue(). reform(IPosition(1, nelements())); } } else { if (!isReal()) { throw(AipsError("Wrong QuantumHolder to convert asQuantumVectorDouble")); } if (!isQuantumDouble()) toReal(Quantum::myType()); toVector(); } return (const Quantum > &) *hold_p.ptr(); } const Quantum > &QuantumHolder::asQuantumVectorFloat() { if (!hold_p.ptr()) { throw(AipsError("Empty QuantumHolder argument for asQuantumVectorFloat")); } if (isArray()) { if (!isQuantumArrayFloat()) { throw(AipsError("Cannot convert to QuantumVectorFloat")); } if (ndim() != 1) { ((Quantum > *)(hold_p.ptr()))->getValue(). reform(IPosition(1, nelements())); } } else { if (!isReal()) { throw(AipsError("Wrong QuantumHolder to convert asQuantumVectorFloat")); } if (!isQuantumFloat()) toReal(Quantum::myType()); toVector(); } return (const Quantum > &) *hold_p.ptr(); } const Quantum > &QuantumHolder::asQuantumVectorInt() { if (!hold_p.ptr()) { throw(AipsError("Empty QuantumHolder argument for asQuantumVectorInt")); } if (isArray()) { if (!isQuantumArrayInt()) { throw(AipsError("Cannot convert to QuantumVectorInt")); } if (ndim() != 1) { ((Quantum > *)(hold_p.ptr()))->getValue(). reform(IPosition(1, nelements())); } } else { if (!isReal()) { throw(AipsError("Wrong QuantumHolder to convert asQuantumVectorInt")); } if (!isQuantumInt()) toReal(Quantum::myType()); toVector(); } return (const Quantum > &) *hold_p.ptr(); } const Quantum > &QuantumHolder::asQuantumVectorComplex() { if (!hold_p.ptr()) { throw(AipsError("Empty QuantumHolder argument for asQuantumVectorComplex")); } if (isArray()) { if (!isQuantumArrayComplex()) { throw(AipsError("Cannot convert to QuantumVectorComplex")); } if (ndim() != 1) { ((Quantum > *)(hold_p.ptr()))->getValue(). reform(IPosition(1, nelements())); } } else { if (!isQuantumComplex()) toComplex(Quantum::myType()); toVector(); } return (const Quantum > &) *hold_p.ptr(); } const Quantum > &QuantumHolder::asQuantumVectorDComplex() { if (!hold_p.ptr()) { throw(AipsError("Empty QuantumHolder argument for asQuantumVectorDComplex")); } if (isArray()) { if (!isQuantumArrayDComplex()) { throw(AipsError("Cannot convert to QuantumVectorDComplex")); } if (ndim() != 1) { ((Quantum > *)(hold_p.ptr()))->getValue(). reform(IPosition(1, nelements())); } } else { if (!isQuantumDComplex()) toComplex(Quantum::myType()); toVector(); } return (const Quantum > &) *hold_p.ptr(); } const Quantum > &QuantumHolder::asQuantumArrayDouble() { if (!hold_p.ptr()) { throw(AipsError("Empty QuantumHolder argument for asQuantumArrayDouble")); } if (isArray()) { if (!isQuantumArrayDouble()) { throw(AipsError("Cannot convert to QuantumArrayDouble")); } } else { if (!isReal()) { throw(AipsError("Wrong QuantumHolder to convert asQuantumArrayDouble")); } if (!isQuantumDouble()) toReal(Quantum::myType()); toArray(); } return (const Quantum > &) *hold_p.ptr(); } const Quantum > &QuantumHolder::asQuantumArrayFloat() { if (!hold_p.ptr()) { throw(AipsError("Empty QuantumHolder argument for asQuantumArrayFloat")); } if (isArray()) { if (!isQuantumArrayFloat()) { throw(AipsError("Cannot convert to QuantumArrayFloat")); } } else { if (!isReal()) { throw(AipsError("Wrong QuantumHolder to convert asQuantumArrayFloat")); } if (!isQuantumFloat()) toReal(Quantum::myType()); toArray(); } return (const Quantum > &) *hold_p.ptr(); } const Quantum > &QuantumHolder::asQuantumArrayInt() { if (!hold_p.ptr()) { throw(AipsError("Empty QuantumHolder argument for asQuantumArrayInt")); } if (isArray()) { if (!isQuantumArrayInt()) { throw(AipsError("Cannot convert to QuantumArrayInt")); } } else { if (!isReal()) { throw(AipsError("Wrong QuantumHolder to convert asQuantumArrayInt")); } if (!isQuantumInt()) toReal(Quantum::myType()); toArray(); } return (const Quantum > &) *hold_p.ptr(); } const Quantum > &QuantumHolder::asQuantumArrayComplex() { if (!hold_p.ptr()) { throw(AipsError("Empty QuantumHolder argument for asQuantumArrayComplex")); } if (isArray()) { if (!isQuantumArrayComplex()) { throw(AipsError("Cannot convert to QuantumArrayComplex")); } } else { if (!isQuantumComplex()) toComplex(Quantum::myType()); toArray(); } return (const Quantum > &) *hold_p.ptr(); } const Quantum > &QuantumHolder::asQuantumArrayDComplex() { if (!hold_p.ptr()) { throw(AipsError("Empty QuantumHolder argument for asQuantumArrayDComplex")); } if (isArray()) { if (!isQuantumArrayDComplex()) { throw(AipsError("Cannot convert to QuantumArrayDComplex")); } } else { if (!isQuantumDComplex()) toComplex(Quantum::myType()); toArray(); } return (const Quantum > &) *hold_p.ptr(); } Bool QuantumHolder::fromRecord(String &error, const RecordInterface &in) { String un; if (in.isDefined(String("value")) && in.isDefined(String("unit")) && in.type(in.idToNumber(RecordFieldId("unit"))) == TpString) { String un; in.get(RecordFieldId("unit"), un); switch (in.type(in.idToNumber(RecordFieldId("value")))) { case TpDouble: { Double vl; in.get(RecordFieldId("value"), vl); hold_p.set(new Quantum(vl, un)); return True; } case TpFloat: { Float vl; in.get(RecordFieldId("value"), vl); hold_p.set(new Quantum(vl, un)); return True; } case TpInt: { Int vl; in.get(RecordFieldId("value"), vl); hold_p.set(new Quantum(vl, un)); return True; } case TpComplex: { Complex vl; in.get(RecordFieldId("value"), vl); hold_p.set(new Quantum(vl, un)); return True; } case TpDComplex: { DComplex vl; in.get(RecordFieldId("value"), vl); hold_p.set(new Quantum(vl, un)); return True; } case TpArrayDouble: { Array vl; in.get(RecordFieldId("value"), vl); hold_p.set(new Quantum >(vl, un)); return True; } case TpArrayFloat: { Array vl; in.get(RecordFieldId("value"), vl); hold_p.set(new Quantum >(vl, un)); return True; } case TpArrayInt: { Array vl; in.get(RecordFieldId("value"), vl); hold_p.set(new Quantum >(vl, un)); return True; } case TpArrayComplex: { Array vl; in.get(RecordFieldId("value"), vl); hold_p.set(new Quantum >(vl, un)); return True; } case TpArrayDComplex: { Array vl; in.get(RecordFieldId("value"), vl); hold_p.set(new Quantum >(vl, un)); return True; } default: break; } } error += String("Illegal Quantum record in QuantumHolder::fromRecord\n"); return False; } Bool QuantumHolder::fromString(String &error, const String &in) { Quantum res; if (!Quantum::read(res, in)) { error += String("in QuantumHolder::fromString with input string \"") + in + String("\": Illegal input units or format\n"); return False; } hold_p.set(new Quantum(res)); return True; } Bool QuantumHolder::toRecord(String &error, RecordInterface &out) const { if (hold_p.ptr()) { if (out.isDefined("value")) out.removeField(RecordFieldId("value")); if (isQuantumDouble()) { out.define(RecordFieldId("value"), (((Quantum *)(hold_p.ptr()))->getValue())); } else if (isQuantumFloat()) { out.define(RecordFieldId("value"), (((Quantum *)(hold_p.ptr()))->getValue())); } else if (isQuantumInt()) { out.define(RecordFieldId("value"), (((Quantum *)(hold_p.ptr()))->getValue())); } else if (isQuantumComplex()) { out.define(RecordFieldId("value"), (((Quantum *)(hold_p.ptr()))->getValue())); } else if (isQuantumDComplex()) { out.define(RecordFieldId("value"), (((Quantum *)(hold_p.ptr()))->getValue())); } else if (isQuantumVectorDouble()) { out.define(RecordFieldId("value"), (((Quantum > *)(hold_p.ptr()))->getValue())); } else if (isQuantumVectorFloat()) { out.define(RecordFieldId("value"), (((Quantum > *)(hold_p.ptr()))->getValue())); } else if (isQuantumVectorInt()) { out.define(RecordFieldId("value"), (((Quantum > *)(hold_p.ptr()))->getValue())); } else if (isQuantumVectorComplex()) { out.define(RecordFieldId("value"), (((Quantum > *)(hold_p.ptr()))->getValue())); } else if (isQuantumVectorDComplex()) { out.define(RecordFieldId("value"), (((Quantum > *)(hold_p.ptr()))->getValue())); } else if (isQuantumArrayDouble()) { out.define(RecordFieldId("value"), (((Quantum > *)(hold_p.ptr()))->getValue())); } else if (isQuantumArrayFloat()) { out.define(RecordFieldId("value"), (((Quantum > *)(hold_p.ptr()))->getValue())); } else if (isQuantumArrayInt()) { out.define(RecordFieldId("value"), (((Quantum > *)(hold_p.ptr()))->getValue())); } else if (isQuantumArrayComplex()) { out.define(RecordFieldId("value"), (((Quantum > *)(hold_p.ptr()))->getValue())); } else if (isQuantumArrayDComplex()) { out.define(RecordFieldId("value"), (((Quantum > *)(hold_p.ptr()))->getValue())); } out.define(RecordFieldId("unit"), String(hold_p.ptr()->getFullUnit().getName())); return True; } error += String("No Quantum specified in QuantumHolder::toRecord\n"); return False; } void QuantumHolder::toRecord(RecordInterface &out) const { String error; if (! toRecord(error, out)) { throw AipsError(error); } } Record QuantumHolder::toRecord() const { Record r; toRecord(r); return r; } void QuantumHolder::toReal(const uInt &tp) { Double d1=0; if (isArray()) { IPosition stx(ndim(), 0); if (isQuantumArrayDouble()) { d1 = Double(((Quantum > *)(hold_p.ptr()))->getValue()(stx)); } else if (isQuantumArrayFloat()) { d1 = Double(((Quantum > *)(hold_p.ptr()))->getValue()(stx)); } else if (isQuantumArrayInt()) { d1 = Double(((Quantum > *)(hold_p.ptr()))->getValue()(stx)); } } else { if (isQuantumDouble()) { d1 = Double(((Quantum *)(hold_p.ptr()))->getValue()); } else if (isQuantumFloat()) { d1 = Double(((Quantum *)(hold_p.ptr()))->getValue()); } else if (isQuantumInt()) { d1 = Double(((Quantum *)(hold_p.ptr()))->getValue()); } } Unit x = hold_p.ptr()->getFullUnit(); if (tp == Quantum::myType()) { hold_p.set(new Quantum(d1, x)); } else if (tp == Quantum::myType()) { hold_p.set(new Quantum(Float(d1), x)); } else if (tp == Quantum::myType()) { hold_p.set(new Quantum(Int(d1), x)); } } void QuantumHolder::toComplex(const uInt &tp) { DComplex d1; if (isArray()) { IPosition stx(ndim(), 0); if (isQuantumArrayDouble()) { d1 = DComplex(((Quantum > *)(hold_p.ptr()))->getValue()(stx)); } else if (isQuantumArrayFloat()) { d1 = DComplex(((Quantum > *)(hold_p.ptr()))->getValue()(stx)); } else if (isQuantumArrayInt()) { d1 = DComplex(((Quantum > *)(hold_p.ptr()))->getValue()(stx)); } else if (isQuantumArrayComplex()) { d1 = (((Quantum > *)(hold_p.ptr()))->getValue()(stx)); } else if (isQuantumArrayDComplex()) { d1 = (((Quantum > *)(hold_p.ptr()))->getValue()(stx)); } } else { if (isQuantumDouble()) { d1 = DComplex(((Quantum *)(hold_p.ptr()))->getValue()); } else if (isQuantumFloat()) { d1 = DComplex(((Quantum *)(hold_p.ptr()))->getValue()); } else if (isQuantumInt()) { d1 = DComplex(((Quantum *)(hold_p.ptr()))->getValue()); } else if (isQuantumComplex()) { d1 = (((Quantum *)(hold_p.ptr()))->getValue()); } else if (isQuantumDComplex()) { d1 = (((Quantum *)(hold_p.ptr()))->getValue()); } } Unit x = hold_p.ptr()->getFullUnit(); if (tp == Quantum::myType()) { hold_p.set(new Quantum(Complex(d1), x)); } else if (tp == Quantum::myType()) { hold_p.set(new Quantum(d1, x)); } } void QuantumHolder::toVector() { Unit x = hold_p.ptr()->getFullUnit(); if (isQuantumDouble()) { Vector d1(1); d1(0) = ((Quantum *)(hold_p.ptr()))->getValue(); hold_p.set(new Quantum >(d1, x)); } else if (isQuantumFloat()) { Vector d1(1); d1(0) = ((Quantum *)(hold_p.ptr()))->getValue(); hold_p.set(new Quantum >(d1, x)); } else if (isQuantumInt()) { Vector d1(1); d1(0) = ((Quantum *)(hold_p.ptr()))->getValue(); hold_p.set(new Quantum >(d1, x)); } else if (isQuantumComplex()) { Vector d1(1); d1(0) = ((Quantum *)(hold_p.ptr()))->getValue(); hold_p.set(new Quantum >(d1, x)); } else if (isQuantumDComplex()) { Vector d1(1); d1(0) = ((Quantum *)(hold_p.ptr()))->getValue(); hold_p.set(new Quantum >(d1, x)); } } void QuantumHolder::toArray() { toVector(); } const String &QuantumHolder::ident() const { static const String myid = "quant"; return myid; } } //# NAMESPACE CASACORE - END