Line data Source code
1 : //# FluxCalcVQS.cc: Implementation of FluxCalcVQS.h
2 : //# Copyright (C) 2013
3 : //# Associated Universities, Inc. Washington DC, USA.
4 : //#
5 : //# This library is free software; you can redistribute it and/or modify it
6 : //# under the terms of the GNU Library General Public License as published by
7 : //# the Free Software Foundation; either version 2 of the License, or (at your
8 : //# option) any later version.
9 : //#
10 : //# This library is distributed in the hope that it will be useful, but WITHOUT
11 : //# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 : //# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
13 : //# License for more details.
14 : //#
15 : //# You should have received a copy of the GNU Library General Public License
16 : //# along with this library; if not, write to the Free Software Foundation,
17 : //# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA.
18 : //#
19 : //# Correspondence concerning AIPS++ should be addressed as follows:
20 : //# Internet email: casa-feedback@nrao.edu.
21 : //# Postal address: AIPS++ Project Office
22 : //# National Radio Astronomy Observatory
23 : //# 520 Edgemont Road
24 : //# Charlottesville, VA 22903-2475 USA
25 : //#
26 : #include <components/ComponentModels/FluxCalcVQS.h>
27 : #include <casacore/casa/Arrays/Vector.h>
28 : #include <casacore/casa/BasicSL/String.h>
29 : #include <casacore/casa/Logging/LogIO.h>
30 : #include <casacore/casa/Quanta/MVTime.h>
31 : #include <casacore/measures/Measures/MDirection.h>
32 : #include <casacore/measures/Measures/MFrequency.h>
33 : #include <casacore/measures/Measures/MEpoch.h>
34 : #include <casacore/tables/Tables/ScalarColumn.h>
35 : #include <casacore/tables/Tables/ArrayColumn.h>
36 : #include <casacore/tables/Tables/TableRecord.h>
37 : #include <casacore/tables/Tables/TableRecord.h>
38 : #include <casacore/tables/Tables/TableProxy.h>
39 :
40 : // Handy for passing anonymous arrays to functions.
41 : #include <casacore/scimath/Mathematics/RigidVector.h>
42 : #include <casacore/scimath/Functionals/ScalarSampledFunctional.h>
43 :
44 : #include <components/ComponentModels/FluxCalcLogFreqPolynomial.h>
45 :
46 : #include <map>
47 :
48 :
49 : using namespace casacore;
50 : namespace casa { //# NAMESPACE CASA - BEGIN
51 0 : FluxCalcVQS::FluxCalcVQS() :
52 0 : srcEnum_p(FluxStdSrcs::UNKNOWN_SOURCE),
53 0 : validfreqrange_p(2),
54 0 : istimevar_p(false)
55 0 : { }
56 :
57 : // Defined even though it's pure virtual; see http://www.gotw.ca/gotw/031.htm
58 0 : FluxCalcVQS::~FluxCalcVQS() { }
59 0 : Bool FluxCalcVQS::operator()(Vector<Flux<Double> >& values,
60 : Vector<Flux<Double> >& errors,
61 : const Vector<MFrequency>& mfreqs)
62 : {
63 0 : uInt nfreqs = mfreqs.nelements();
64 :
65 0 : values.resize(nfreqs);
66 0 : errors.resize(nfreqs);
67 :
68 0 : if (coeffsmat_p.nelements()) {
69 : // coeffs have been read from a table.
70 0 : uInt nep=0; // should be a single epoch (single row)
71 0 : setSourceCoeffsfromVec(nep);
72 : }
73 :
74 0 : Bool success = true;
75 0 : for(uInt f = 0; f < nfreqs; ++f)
76 0 : success &= (*this)(values[f], errors[f], mfreqs[f], false);
77 :
78 0 : return success;
79 : }
80 :
81 : //with interpolation over epochs
82 0 : Bool FluxCalcVQS::operator()(Vector<Flux<Double> >& values,
83 : Vector<Flux<Double> >& errors,
84 : const Vector<MFrequency>& mfreqs,
85 : const MEpoch& mtime,
86 : const String& interpmethod)
87 :
88 : {
89 0 : uInt nfreqs = mfreqs.nelements();
90 :
91 0 : values.resize(nfreqs);
92 0 : errors.resize(nfreqs);
93 :
94 : // for those considered to be variable, for each set of coefficients
95 : // at each epoch, call the follwoing to get values (fluxes)
96 : // and accumate in vector of vector to do interpolation.
97 : // istimevar_p to determine if the source is variable. If not
98 : // no interpolation is done, use first row of the coeffs table.
99 :
100 0 : Bool success = true;
101 :
102 0 : Int nep = 1;
103 0 : if (istimevar_p) nep=epochvec_p.nelements();
104 :
105 0 : Flux<Double> tmpfluxes;
106 0 : Flux<Double> tmperrors;
107 0 : Vector<Double> tmpfluxvec;
108 0 : Vector<Double> tmperrvec;
109 :
110 0 : fluxes_p.resize(nep);
111 0 : for(uInt f = 0; f < nfreqs; ++f){
112 0 : for(uInt iep=0; iep < (uInt)nep; ++iep) {
113 0 : setSourceCoeffsfromVec(iep);
114 0 : success &= (*this)(tmpfluxes,tmperrors,mfreqs[f],true);
115 0 : tmpfluxes.value(tmpfluxvec);
116 0 : tmperrors.value(tmperrvec);
117 : // currently only I flux is returned...
118 : //cerr<<"tmpfluxvec[0]="<<tmpfluxvec[0]<<endl;
119 : //cerr<<"epochvec_p[iep]="<<epochvec_p[iep]<<endl;
120 0 : fluxes_p[iep]=tmpfluxvec[0];
121 : }
122 0 : if (istimevar_p) {
123 : //setup interpolator
124 0 : ScalarSampledFunctional<Double> dts(epochvec_p);
125 0 : ScalarSampledFunctional<Float> flxs(fluxes_p);
126 0 : Interpolate1D<Double, Float> interpolateFlux(dts,flxs);
127 0 : interpolateFlux.setMethod(getInterpMethod_p(interpmethod));
128 :
129 0 : values[f].setValue(interpolateFlux(mtime.get("d").getValue()));
130 0 : }
131 : else { // no interpolation for non-var source, use first row data
132 0 : values[f].setValue(fluxes_p[0]);
133 : }
134 : }
135 :
136 : // success &= (*this)(values[f], errors[f], mfreqs[f]);
137 :
138 0 : return success;
139 0 : }
140 :
141 0 : Bool FluxCalcVQS::setSource(const String& sourceName, const MDirection& sourceDir)
142 : {
143 0 : srcEnum_p = srcNameToEnum(sourceName,sourceDir);
144 : //return srcEnum_p != FCQS::UNKNOWN_SOURCE;
145 0 : return srcEnum_p != FSS::UNKNOWN_SOURCE;
146 : }
147 :
148 0 : FluxCalcVQS::Source FluxCalcVQS::getSrcEnum()
149 : {
150 0 : return srcEnum_p;
151 : }
152 :
153 0 : void FluxCalcVQS::readQSCoeffsTable(const Path& fileName)
154 : {
155 : //table containing the coefficents has
156 : //epoch, vector of coefficients
157 0 : const String& fullName = fileName.absoluteName();
158 0 : LogIO os(LogOrigin("FluxCalcVQS", "readQSCoeffsTable", WHERE));
159 : os << LogIO::NORMAL1
160 : << "Reading the coefficient data from a table, "<< fullName
161 0 : << LogIO::POST;
162 :
163 0 : AlwaysAssert(Table::isReadable(fullName), AipsError);
164 0 : Table_p = Table(fullName, Table::Old);
165 : ///TableProxy tab2(Table_p);
166 : //String srcName(names_p[srcEnum_p](0));
167 0 : String srcName(EnumToSrcName(srcEnum_p));
168 0 : String srcCoeffColName=srcName+"_coeffs";
169 0 : String srcCoeffErrorColName=srcName+"_coefferrs";
170 :
171 : //check the source data exist in the table
172 0 : const ColumnDescSet& cds=Table_p.tableDesc().columnDescSet();
173 0 : if (!cds.isDefined(srcCoeffColName))
174 0 : throw(AipsError(srcName+" does not appears to be in "+fullName));
175 0 : const ScalarColumn<Double> epochCol(Table_p, "Epoch");
176 0 : const ArrayColumn<Float> CoeffCol(Table_p, srcCoeffColName);
177 0 : const ArrayColumn<Float> CoeffErrorCol(Table_p, srcCoeffErrorColName);
178 : // check if col contains a valid freq range info in a keyword
179 0 : if (CoeffCol.keywordSet().isDefined("ValidFreqRange")) {
180 0 : Vector<Double> validfreqRange;
181 0 : String freqRangeUnit;
182 0 : CoeffCol.keywordSet().asRecord("ValidFreqRange").get("freqRange",validfreqRange);
183 0 : CoeffCol.keywordSet().asRecord("ValidFreqRange").get("freqRangeUnit",freqRangeUnit);
184 0 : Vector<MFrequency> mvalidfreqs;
185 0 : validfreqrange_p(0) = MFrequency(Quantity(validfreqRange(0),freqRangeUnit), MFrequency::TOPO);
186 0 : validfreqrange_p(1) = MFrequency(Quantity(validfreqRange(1),freqRangeUnit), MFrequency::TOPO);
187 0 : }
188 : else {
189 0 : validfreqrange_p(0) = MFrequency(Quantity(0.0,"GHz"), MFrequency::TOPO);
190 0 : validfreqrange_p(1) = MFrequency(Quantity(0.0,"GHz"), MFrequency::TOPO);
191 : }
192 0 : Vector<Double> tempEpochs;
193 0 : epochCol.getColumn(tempEpochs,true);
194 0 : CoeffCol.getColumn(coeffsmat_p,true);
195 0 : CoeffErrorCol.getColumn(coefferrsmat_p,true);
196 : //convert the epoch (year + fraction) to mjd
197 0 : convertYearFracToMjd(tempEpochs,epochvec_p);
198 : os << LogIO::DEBUG1
199 : << "nepoch="<<epochvec_p.nelements()
200 0 : << "coeff_0 for the first epoch (coeffsmat_p(0,0))="<<coeffsmat_p(0,0)
201 0 : << LogIO::POST;
202 :
203 0 : }
204 :
205 0 : void FluxCalcVQS::interpolate(const String& interpmethod)
206 : {
207 0 : ScalarSampledFunctional<Double> dts(epochvec_p);
208 0 : ScalarSampledFunctional<Float> flxs(fluxes_p);
209 0 : Interpolate1D<Double, Float> interpolateFlux(dts,flxs);
210 0 : interpolateFlux.setMethod(getInterpMethod_p(interpmethod));
211 0 : }
212 :
213 0 : Interpolate1D<Double,Float>::Method FluxCalcVQS::getInterpMethod_p(const String& interpmethod)
214 : {
215 0 : if (interpmethod.contains("nearest"))
216 0 : return Interpolate1D<Double,Float>::nearestNeighbour;
217 0 : if (interpmethod.contains("linear"))
218 0 : return Interpolate1D<Double,Float>::linear;
219 0 : if (interpmethod.contains("cubic"))
220 0 : return Interpolate1D<Double,Float>::cubic;
221 0 : if (interpmethod.contains("spline"))
222 0 : return Interpolate1D<Double,Float>::spline;
223 0 : throw(AipsError("Unknown interpolation method: "+interpmethod));
224 : }
225 :
226 0 : void FluxCalcVQS::convertYearFracToMjd(const Vector<Double>& yearfrac, Vector<Double>& mjds)
227 : {
228 0 : uInt daysintheyr=365;
229 0 : uInt n = yearfrac.nelements();
230 0 : mjds.resize(n);
231 0 : for (uInt i=0; i < n; i++) {
232 0 : if (Time::isLeapYear(uInt(yearfrac(i)))) daysintheyr=366;
233 : Double fintyr, fyrfrac;
234 0 : fyrfrac = modf((Double)yearfrac(i),&fintyr);
235 0 : Float days=fyrfrac*daysintheyr;
236 0 : Time time0(Int(yearfrac(i)),1,1);
237 0 : Double mjdtime0 = time0.modifiedJulianDay();
238 :
239 0 : mjds[i] = mjdtime0 + days;
240 : }
241 0 : }
242 :
243 0 : void FluxCalcVQS::setSourceCoeffsfromVec(uInt& i)
244 : {
245 : //Vector<Float> err(4,0.0);
246 0 : tvcoeffs_p(0)=coeffsmat_p.column(i);
247 : //cerr<<"coeffsmat_p.column="<<coeffsmat_p.column(i)(0)<<endl;
248 0 : tvcoeffs_p(1)=coefferrsmat_p.column(i);
249 0 : }
250 :
251 0 : void FluxCalcVQS::isTimeVar(Bool istimevar)
252 : {
253 0 : istimevar_p=istimevar;
254 0 : }
255 :
256 : } //# NAMESPACE CASA - END
|