/******************************************************************************* * ALMA - Atacama Large Millimiter Array * (c) Instituto de Estructura de la Materia, 2009 * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * "@(#) $Id: ATMRefractiveIndexProfile.cpp Exp $" * * who when what * -------- -------- ---------------------------------------------- * pardo 24/03/09 created */ #include "ATMRefractiveIndexProfile.h" #include <iostream> #include <math.h> #include <string> #include <vector> ATM_NAMESPACE_BEGIN // Constructors RefractiveIndexProfile::RefractiveIndexProfile(const Frequency &freq, const AtmProfile &atmProfile) : AtmProfile(atmProfile), SpectralGrid(freq) { mkRefractiveIndexProfile(); } RefractiveIndexProfile::RefractiveIndexProfile(const SpectralGrid &spectralGrid, const AtmProfile &atmProfile) : AtmProfile(atmProfile), SpectralGrid(spectralGrid) { mkRefractiveIndexProfile(); } RefractiveIndexProfile::RefractiveIndexProfile(const RefractiveIndexProfile & a) : AtmProfile(a), SpectralGrid(a) { // std::cout<<"Enter RefractiveIndexProfile copy constructor version Fri May 20 00:59:47 CEST 2005"<<endl; // level AtmProfile // type_ = a.type_; // prLimit_ = a.prLimit_; /* v_hx_.reserve(a.v_hx_.size()); v_px_.reserve(a.v_px_.size()); v_tx_.reserve(a.v_tx_.size()); for(unsigned int n=0; n<a.v_hx_.size(); n++){ v_hx_.push_back(a.v_hx_[n]); v_px_.push_back(a.v_px_[n]); v_tx_.push_back(a.v_tx_[n]); } */ typeAtm_ = a.typeAtm_; groundTemperature_ = a.groundTemperature_; tropoLapseRate_ = a.tropoLapseRate_; groundPressure_ = a.groundPressure_; relativeHumidity_ = a.relativeHumidity_; wvScaleHeight_ = a.wvScaleHeight_; pressureStep_ = a.pressureStep_; pressureStepFactor_ = a.pressureStepFactor_; altitude_ = a.altitude_; topAtmProfile_ = a.topAtmProfile_; numLayer_ = a.numLayer_; newBasicParam_ = a.newBasicParam_; // copy thresholds altitudeThreshold_ = a.altitudeThreshold_; groundPressureThreshold_ = a.groundPressureThreshold_; groundTemperatureThreshold_ = a.groundTemperatureThreshold_; tropoLapseRateThreshold_ = a.tropoLapseRateThreshold_; relativeHumidityThreshold_ = a.relativeHumidityThreshold_; wvScaleHeightThreshold_ = a.wvScaleHeightThreshold_; v_layerThickness_.reserve(numLayer_); v_layerTemperature_.reserve(numLayer_); v_layerWaterVapor_.reserve(numLayer_); v_layerCO_.reserve(numLayer_); v_layerO3_.reserve(numLayer_); v_layerN2O_.reserve(numLayer_); v_layerNO2_.reserve(numLayer_); v_layerSO2_.reserve(numLayer_); for(unsigned int n = 0; n < numLayer_; n++) { v_layerThickness_.push_back(a.v_layerThickness_[n]); v_layerTemperature_.push_back(a.v_layerTemperature_[n]); //cout << "n=" << n << std::endl; v_layerWaterVapor_.push_back(a.v_layerWaterVapor_[n]); v_layerPressure_.push_back(a.v_layerPressure_[n]); v_layerCO_.push_back(a.v_layerCO_[n]); v_layerO3_.push_back(a.v_layerO3_[n]); v_layerN2O_.push_back(a.v_layerN2O_[n]); v_layerNO2_.push_back(a.v_layerNO2_[n]); v_layerSO2_.push_back(a.v_layerSO2_[n]); } // level Spectral Grid freqUnits_ = a.freqUnits_; v_chanFreq_ = a.v_chanFreq_; v_numChan_ = a.v_numChan_; v_refChan_ = a.v_refChan_; v_refFreq_ = a.v_refFreq_; v_chanSep_ = a.v_chanSep_; v_maxFreq_ = a.v_maxFreq_; v_minFreq_ = a.v_minFreq_; v_intermediateFrequency_ = a.v_intermediateFrequency_; v_loFreq_ = a.v_loFreq_; v_sidebandSide_ = a.v_sidebandSide_; v_sidebandType_ = a.v_sidebandType_; vv_assocSpwId_ = a.vv_assocSpwId_; vv_assocNature_ = a.vv_assocNature_; v_transfertId_ = a.v_transfertId_; // level Absorption Profile vv_N_H2OLinesPtr_.reserve(a.v_chanFreq_.size()); vv_N_H2OContPtr_.reserve(a.v_chanFreq_.size()); vv_N_O2LinesPtr_.reserve(a.v_chanFreq_.size()); vv_N_DryContPtr_.reserve(a.v_chanFreq_.size()); vv_N_O3LinesPtr_.reserve(a.v_chanFreq_.size()); vv_N_COLinesPtr_.reserve(a.v_chanFreq_.size()); vv_N_N2OLinesPtr_.reserve(a.v_chanFreq_.size()); vv_N_NO2LinesPtr_.reserve(a.v_chanFreq_.size()); vv_N_SO2LinesPtr_.reserve(a.v_chanFreq_.size()); std::vector<std::complex<double> >* v_N_H2OLinesPtr; std::vector<std::complex<double> >* v_N_H2OContPtr; std::vector<std::complex<double> >* v_N_O2LinesPtr; std::vector<std::complex<double> >* v_N_DryContPtr; std::vector<std::complex<double> >* v_N_O3LinesPtr; std::vector<std::complex<double> >* v_N_COLinesPtr; std::vector<std::complex<double> >* v_N_N2OLinesPtr; std::vector<std::complex<double> >* v_N_NO2LinesPtr; std::vector<std::complex<double> >* v_N_SO2LinesPtr; for(unsigned int nc = 0; nc < v_chanFreq_.size(); nc++) { v_N_H2OLinesPtr = new std::vector<std::complex<double> > ; v_N_H2OLinesPtr->reserve(numLayer_); v_N_H2OContPtr = new std::vector<std::complex<double> > ; v_N_H2OContPtr->reserve(numLayer_); v_N_O2LinesPtr = new std::vector<std::complex<double> > ; v_N_O2LinesPtr->reserve(numLayer_); v_N_DryContPtr = new std::vector<std::complex<double> > ; v_N_DryContPtr->reserve(numLayer_); v_N_O3LinesPtr = new std::vector<std::complex<double> > ; v_N_O3LinesPtr->reserve(numLayer_); v_N_COLinesPtr = new std::vector<std::complex<double> > ; v_N_COLinesPtr->reserve(numLayer_); v_N_N2OLinesPtr = new std::vector<std::complex<double> > ; v_N_N2OLinesPtr->reserve(numLayer_); v_N_NO2LinesPtr = new std::vector<std::complex<double> > ; v_N_NO2LinesPtr->reserve(numLayer_); v_N_SO2LinesPtr = new std::vector<std::complex<double> > ; v_N_SO2LinesPtr->reserve(numLayer_); for(unsigned int n = 0; n < numLayer_; n++) { // std::cout << "numLayer_=" << nc << " " << n << std::endl; // COMMENTED OUT BY JUAN MAY/16/2005 v_N_H2OLinesPtr->push_back(a.vv_N_H2OLinesPtr_[nc]->at(n)); v_N_H2OContPtr->push_back(a.vv_N_H2OContPtr_[nc]->at(n)); v_N_O2LinesPtr->push_back(a.vv_N_O2LinesPtr_[nc]->at(n)); v_N_DryContPtr->push_back(a.vv_N_DryContPtr_[nc]->at(n)); v_N_O3LinesPtr->push_back(a.vv_N_O3LinesPtr_[nc]->at(n)); v_N_COLinesPtr->push_back(a.vv_N_COLinesPtr_[nc]->at(n)); v_N_N2OLinesPtr->push_back(a.vv_N_N2OLinesPtr_[nc]->at(n)); v_N_NO2LinesPtr->push_back(a.vv_N_NO2LinesPtr_[nc]->at(n)); v_N_SO2LinesPtr->push_back(a.vv_N_SO2LinesPtr_[nc]->at(n)); } vv_N_H2OLinesPtr_.push_back(v_N_H2OLinesPtr); vv_N_H2OContPtr_.push_back(v_N_H2OContPtr); vv_N_O2LinesPtr_.push_back(v_N_O2LinesPtr); vv_N_DryContPtr_.push_back(v_N_DryContPtr); vv_N_O3LinesPtr_.push_back(v_N_O3LinesPtr); vv_N_COLinesPtr_.push_back(v_N_COLinesPtr); vv_N_N2OLinesPtr_.push_back(v_N_N2OLinesPtr); vv_N_NO2LinesPtr_.push_back(v_N_NO2LinesPtr); vv_N_SO2LinesPtr_.push_back(v_N_SO2LinesPtr); } } RefractiveIndexProfile::RefractiveIndexProfile() { } RefractiveIndexProfile::~RefractiveIndexProfile() { rmRefractiveIndexProfile(); } void RefractiveIndexProfile::rmRefractiveIndexProfile() { // for every frequency channel delete the pointer to the absorption profile for(unsigned int nc = 0; nc < v_chanFreq_.size(); nc++) { delete vv_N_H2OLinesPtr_[nc]; delete vv_N_H2OContPtr_[nc]; delete vv_N_O2LinesPtr_[nc]; delete vv_N_DryContPtr_[nc]; delete vv_N_O3LinesPtr_[nc]; delete vv_N_COLinesPtr_[nc]; delete vv_N_N2OLinesPtr_[nc]; delete vv_N_NO2LinesPtr_[nc]; delete vv_N_SO2LinesPtr_[nc]; } } bool RefractiveIndexProfile::updateRefractiveIndexProfile(const Length &altitude, const Pressure &groundPressure, const Temperature &groundTemperature, double tropoLapseRate, const Humidity &relativeHumidity, const Length &wvScaleHeight) { bool updated = false; bool mkNewAtmProfile = updateAtmProfile(altitude, groundPressure, groundTemperature, tropoLapseRate, relativeHumidity, wvScaleHeight); unsigned int numLayer = getNumLayer(); if(vv_N_H2OLinesPtr_.size() < v_chanFreq_.size()) { mkNewAtmProfile = true; std::cout << " RefractiveIndexProfile: number of spectral windows has increased" << std::endl; } if(mkNewAtmProfile) { if(numLayer) { mkRefractiveIndexProfile(); updated = true; } else { std::cout << " RefractiveIndexProfile: ERROR: getNumLayer() returns 0" << std::endl; } } return updated; } // NB: this interface is required because the sub-class .... overrides this method. bool RefractiveIndexProfile::setBasicAtmosphericParameters(const Length &altitude, const Pressure &groundPressure, const Temperature &groundTemperature, double tropoLapseRate, const Humidity &relativeHumidity, const Length &wvScaleHeight) { bool updated = updateRefractiveIndexProfile(altitude, groundPressure, groundTemperature, tropoLapseRate, relativeHumidity, wvScaleHeight); return updated; } void RefractiveIndexProfile::mkRefractiveIndexProfile() { // static const double abun_18o=0.0020439; // static const double abun_17o=0.0003750; // static const double abun_D=0.000298444; // static const double o2_mixing_ratio=0.2092; // static const double mmol_h2o=18.005059688; // 20*0.0020439+19*(0.0003750+2*0.000298444)+18*(1-0.0020439-0.0003750-2*0.000298444) // static bool first = true; // [-Wunused_but_set_variable] double abun_O3, abun_CO, abun_N2O, abun_NO2, abun_SO2; double wvt, wv; // double t; // [-Wunused_but_set_variable] double nu; // double nu2, nu_pi; // [-Wunused_but_set_variable] // double width; // unsigned int npoints; RefractiveIndex atm; // double sumAbsO3Lines1, sumAbsCOLines1, sumAbsN2OLines1, sumAbsNO2Lines1, sumAbsSO2Lines1; //TODO we will have to put numLayer_ and v_chanFreq_.size() const //we do not want to resize! ==> pas de setter pour SpectralGrid //cout << "vv_N_H2OLinesPtr_.size()=" << vv_N_H2OLinesPtr_.size() << std::endl; if(vv_N_H2OLinesPtr_.size() == 0) { // first time vv_N_H2OLinesPtr_.reserve(v_chanFreq_.size()); vv_N_H2OContPtr_.reserve(v_chanFreq_.size()); vv_N_O2LinesPtr_.reserve(v_chanFreq_.size()); vv_N_DryContPtr_.reserve(v_chanFreq_.size()); vv_N_O3LinesPtr_.reserve(v_chanFreq_.size()); vv_N_COLinesPtr_.reserve(v_chanFreq_.size()); vv_N_N2OLinesPtr_.reserve(v_chanFreq_.size()); vv_N_NO2LinesPtr_.reserve(v_chanFreq_.size()); vv_N_SO2LinesPtr_.reserve(v_chanFreq_.size()); } else { if(vv_N_H2OLinesPtr_.size() == v_chanFreq_.size()) // there are new basic param rmRefractiveIndexProfile(); // delete all the layer profiles for all the frequencies } std::vector<std::complex<double> >* v_N_H2OLinesPtr; std::vector<std::complex<double> >* v_N_H2OContPtr; std::vector<std::complex<double> >* v_N_O2LinesPtr; std::vector<std::complex<double> >* v_N_DryContPtr; std::vector<std::complex<double> >* v_N_O3LinesPtr; std::vector<std::complex<double> >* v_N_COLinesPtr; std::vector<std::complex<double> >* v_N_N2OLinesPtr; std::vector<std::complex<double> >* v_N_NO2LinesPtr; std::vector<std::complex<double> >* v_N_SO2LinesPtr; // std::cout << "v_chanFreq_.size()=" << v_chanFreq_.size() << std::endl; // std::cout << "numLayer_=" << numLayer_ << std::endl; // std::cout << "v_chanFreq_[0]=" << v_chanFreq_[0] << std::endl; // check if new spectral windows have been added unsigned int ncmin; /* std::cout << "vv_N_H2OLinesPtr_.size()="<<vv_N_H2OLinesPtr_.size()<<endl; */ ncmin = vv_N_H2OLinesPtr_.size(); // will be > 0 if spectral window(s) have been added if(newBasicParam_) ncmin = 0; // std::cout << "ncmin=" << ncmin << std::endl; for(unsigned int nc = ncmin; nc < v_chanFreq_.size(); nc++) { v_N_H2OLinesPtr = new std::vector<std::complex<double> > ; v_N_H2OContPtr = new std::vector<std::complex<double> > ; v_N_O2LinesPtr = new std::vector<std::complex<double> > ; v_N_DryContPtr = new std::vector<std::complex<double> > ; v_N_O3LinesPtr = new std::vector<std::complex<double> > ; v_N_COLinesPtr = new std::vector<std::complex<double> > ; v_N_N2OLinesPtr = new std::vector<std::complex<double> > ; v_N_NO2LinesPtr = new std::vector<std::complex<double> > ; v_N_SO2LinesPtr = new std::vector<std::complex<double> > ; v_N_H2OLinesPtr->reserve(numLayer_); v_N_H2OContPtr->reserve(numLayer_); v_N_O2LinesPtr->reserve(numLayer_); v_N_DryContPtr->reserve(numLayer_); v_N_O3LinesPtr->reserve(numLayer_); v_N_COLinesPtr->reserve(numLayer_); v_N_N2OLinesPtr->reserve(numLayer_); v_N_NO2LinesPtr->reserve(numLayer_); v_N_SO2LinesPtr->reserve(numLayer_); nu = 1.0E-9 * v_chanFreq_[nc]; // ATM uses GHz units // std::cout << "freq. points =" << v_chanFreq_.size() << std::endl; /* TO BE IMPLEMENTED IN NEXT RELEASE if (v_chanFreq_.size()>1){ if(nc==0){ width = fabs(v_chanFreq_[nc+1]-v_chanFreq_[nc])*1e-9; // width en GHz para ATM npoints=(unsigned int)round(width*100); // One point every 10 MHz }else{ if(nc==v_chanFreq_.size()-1){ width = fabs(v_chanFreq_[nc]-v_chanFreq_[nc-1])*1e-9; // width en GHz para ATM npoints=(unsigned int)round(width*100); // One point every 10 MHz }else{ width = fabs((v_chanFreq_[nc+1]-v_chanFreq_[nc-1])/2.0)*1e-9; // width en GHz para ATM npoints=(unsigned int)round(width*100); // One point every 10 MHz } } }else{ width = 0.001; // default width = 1 MHz = 0.001 GHz npoints=1; } if(npoints==0){npoints=1;} */ // std::cout << "nc =" << nc << " nu=" << nu << " width=" << width << " GHz npoints=" << npoints << std::endl; // nu2 = nu * nu; // [-Wunused_but_set_variable] // nu_pi = nu / M_PI; // [-Wunused_but_set_variable] for(unsigned int j = 0; j < numLayer_; j++) { wv = v_layerWaterVapor_[j] * 1000.0; // se multiplica por 10**3 por cuestión de unidades en las rutinas fortran. wvt = wv * v_layerTemperature_[j] / 217.0; // v_layerWaterVapor_[j] está en kg/m**3 // t = v_layerTemperature_[j] / 300.0; // [-Wunused_but_set_variable] // std::cout <<"ATMRefractiveIndexProfile: " << v_layerTemperature_[j] << " K " << v_layerPressure_[j] << " mb " << nu << " GHz " << std::endl; // std::cout <<"ATMRefractiveIndexProfile: O2" << atm.getRefractivity_o2(v_layerTemperature_[j],v_layerPressure_[j],wvt,nu) << std::endl; // std::cout << "ATMRefractiveIndexProfile: O2" << atm.getRefractivity_o2(v_layerTemperature_[j],v_layerPressure_[j],wvt,nu,width,npoints) << std::endl; // std::cout << "ATMRefractiveIndexProfile: H2O" << atm.getRefractivity_h2o(v_layerTemperature_[j],v_layerPressure_[j],wvt,nu) << std::endl; // std::cout << "ATMRefractiveIndexProfile: H2O" << atm.getRefractivity_h2o(v_layerTemperature_[j],v_layerPressure_[j],wvt,nu,width,npoints) << std::endl; // std::cout <<"ATMRefractiveIndexProfile: O3" << atm.getRefractivity_o3(v_layerTemperature_[j],v_layerPressure_[j],nu,v_layerO3_[j]) << std::endl; // std::cout << "ATMRefractiveIndexProfile: O3" << atm.getRefractivity_o3(v_layerTemperature_[j],v_layerPressure_[j],nu,width,npoints,v_layerO3_[j]) << std::endl; // std::cout <<"ATMRefractiveIndexProfile: CO" << atm.getSpecificRefractivity_co(v_layerTemperature_[j],v_layerPressure_[j],nu) << std::endl; // std::cout << "ATMRefractiveIndexProfile: CO" << atm.getSpecificRefractivity_co(v_layerTemperature_[j],v_layerPressure_[j],nu,width,npoints) << std::endl; v_N_O2LinesPtr->push_back(atm.getRefractivity_o2(v_layerTemperature_[j], v_layerPressure_[j], wvt, nu)); // ,width,npoints)); TO BE IMPLEMENTED IN NEXT RELEASE std::complex<double> cont_h2o = atm.getSpecificRefractivity_cnth2o(v_layerTemperature_[j], v_layerPressure_[j], wvt, nu); // ,width,npoints); TO BE IMPLEMENTED IN NEXT RELEASE std::complex<double> cont_dry = atm.getSpecificRefractivity_cntdry(v_layerTemperature_[j], v_layerPressure_[j], wvt, nu); // ,width,npoints); TO BE IMPLEMENTED IN NEXT RELEASE v_N_H2OContPtr->push_back(cont_h2o); v_N_DryContPtr->push_back(cont_dry); if(v_layerWaterVapor_[j] > 0) { v_N_H2OLinesPtr->push_back(atm.getRefractivity_h2o(v_layerTemperature_[j], v_layerPressure_[j], wvt, nu)); // ,width,npoints)); TO BE IMPLEMENTED IN NEXT RELEASE } else { v_N_H2OLinesPtr->push_back(0.0); } // if(v_layerO3_[j]<0.0||j==10){cout << "v_layerO3_[" << j << "]=" << v_layerO3_[j] << std::endl;} if(v_layerO3_[j] > 0) { abun_O3 = v_layerO3_[j] * 1E-6; v_N_O3LinesPtr->push_back(atm.getRefractivity_o3(v_layerTemperature_[j], v_layerPressure_[j], nu, // width,npoints, TO BE IMPLEMENTED IN NEXT RELEASE abun_O3 * 1e6)); } else { v_N_O3LinesPtr->push_back(0.0); } if(v_layerCO_[j] > 0) { abun_CO = v_layerCO_[j] * 1E-6; // in cm^-3 v_N_COLinesPtr->push_back(atm.getSpecificRefractivity_co(v_layerTemperature_[j], v_layerPressure_[j], nu) // ,width,npoints) TO BE IMPLEMENTED IN NEXT RELEASE * abun_CO * 1e6); // m^2 * m^-3 = m^-1 } else { v_N_COLinesPtr->push_back(0.0); } if(v_layerN2O_[j] > 0) { abun_N2O = v_layerN2O_[j] * 1E-6; v_N_N2OLinesPtr->push_back(atm.getSpecificRefractivity_n2o(v_layerTemperature_[j], v_layerPressure_[j], nu) // ,width,npoints) TO BE IMPLEMENTED IN NEXT RELEASE * abun_N2O * 1e6); // m^2 * m^-3 = m^-1 } else { v_N_N2OLinesPtr->push_back(0.0); } if(v_layerNO2_[j] > 0) { abun_NO2 = v_layerNO2_[j] * 1E-6; v_N_NO2LinesPtr->push_back(atm.getSpecificRefractivity_no2(v_layerTemperature_[j], v_layerPressure_[j], nu) // ,width,npoints) TO BE IMPLEMENTED IN NEXT RELEASE * abun_NO2 * 1e6); // m^2 * m^-3 = m^-1 } else { v_N_NO2LinesPtr->push_back(0.0); } if(v_layerSO2_[j] > 0) { abun_SO2 = v_layerSO2_[j] * 1E-6; v_N_SO2LinesPtr->push_back(atm.getSpecificRefractivity_so2(v_layerTemperature_[j], v_layerPressure_[j], nu) // ,width,npoints) TO BE IMPLEMENTED IN NEXT RELEASE * abun_SO2 * 1e6); // m^2 * m^-3 = m^-1 } else { v_N_SO2LinesPtr->push_back(0.0); } } // if(vv_N_H2OLinesPtr_.size() == 0) first = true; // [-Wunused_but_set_variable] if(vv_N_H2OLinesPtr_.size() < v_chanFreq_.size()) { vv_N_H2OLinesPtr_.push_back(v_N_H2OLinesPtr); vv_N_H2OContPtr_.push_back(v_N_H2OContPtr); vv_N_O2LinesPtr_.push_back(v_N_O2LinesPtr); vv_N_DryContPtr_.push_back(v_N_DryContPtr); vv_N_O3LinesPtr_.push_back(v_N_O3LinesPtr); vv_N_COLinesPtr_.push_back(v_N_COLinesPtr); vv_N_N2OLinesPtr_.push_back(v_N_N2OLinesPtr); vv_N_NO2LinesPtr_.push_back(v_N_NO2LinesPtr); vv_N_SO2LinesPtr_.push_back(v_N_SO2LinesPtr); } else { vv_N_H2OLinesPtr_[nc] = v_N_H2OLinesPtr; vv_N_H2OContPtr_[nc] = v_N_H2OContPtr; vv_N_O2LinesPtr_[nc] = v_N_O2LinesPtr; vv_N_DryContPtr_[nc] = v_N_DryContPtr; vv_N_O3LinesPtr_[nc] = v_N_O3LinesPtr; vv_N_COLinesPtr_[nc] = v_N_COLinesPtr; vv_N_N2OLinesPtr_[nc] = v_N_N2OLinesPtr; vv_N_NO2LinesPtr_[nc] = v_N_NO2LinesPtr; vv_N_SO2LinesPtr_[nc] = v_N_SO2LinesPtr; } } newBasicParam_ = false; // first = false; // [-Wunused_but_set_variable] } Opacity RefractiveIndexProfile::getDryOpacityUpTo(unsigned int nc, Length refalti) { unsigned int ires; unsigned int numlayerold; Length alti; double fractionLast; Opacity opacityout0; Opacity opacityout1; Opacity zeroOp(0.0,Opacity::UnitNeper); if(refalti.get(Length::UnitKiloMeter) <= altitude_.get(Length::UnitKiloMeter)) { return zeroOp; }else{ fractionLast = 1.0; numlayerold = numLayer_; opacityout0=getDryOpacity(nc); ires=numlayerold-1; alti=altitude_; for(unsigned int i=0; i<numLayer_; i++){ if(alti.get(Length::UnitKiloMeter) < refalti.get(Length::UnitKiloMeter) && (alti.get(Length::UnitKiloMeter)+v_layerThickness_[i]/1000.0) >= refalti.get(Length::UnitKiloMeter)) { ires=i; fractionLast = (refalti.get(Length::UnitMeter)-alti.get(Length::UnitMeter))/v_layerThickness_[i]; } alti = alti + Length(v_layerThickness_[i],Length::UnitMeter); } numLayer_ = ires; opacityout0=getDryOpacity(nc); numLayer_ = ires+1; opacityout1=getDryOpacity(nc); numLayer_ = numlayerold; return opacityout0+(opacityout1-opacityout0)*fractionLast; } } Opacity RefractiveIndexProfile::getDryOpacity(unsigned int nc) { if(!chanIndexIsValid(nc)) return Opacity(-999.0); double kv = 0; for(unsigned int j = 0; j < numLayer_; j++) { kv = kv + imag(vv_N_O2LinesPtr_[nc]->at(j) + vv_N_DryContPtr_[nc]->at(j) + vv_N_O3LinesPtr_[nc]->at(j) + vv_N_COLinesPtr_[nc]->at(j) + vv_N_N2OLinesPtr_[nc]->at(j) + vv_N_NO2LinesPtr_[nc]->at(j) + vv_N_SO2LinesPtr_[nc]->at(j)) * v_layerThickness_[j]; } return Opacity(kv); } Opacity RefractiveIndexProfile::getAverageDryOpacity(unsigned int spwid) { if(!spwidAndIndexAreValid(spwid, 0)) return Opacity(-999.0); Opacity totalaverage; totalaverage = Opacity(0.0, Opacity::UnitNeper); for(unsigned int nc = 0; nc < getNumChan(spwid); nc++) { totalaverage = totalaverage + getDryOpacity(spwid, nc); } totalaverage = totalaverage / getNumChan(spwid); return totalaverage; } Opacity RefractiveIndexProfile::getAverageO2LinesOpacity(unsigned int spwid) { if(!spwidAndIndexAreValid(spwid, 0)) return Opacity(-999.0); Opacity totalaverage; totalaverage = Opacity(0.0, Opacity::UnitNeper); for(unsigned int nc = 0; nc < getNumChan(spwid); nc++) { totalaverage = totalaverage + getO2LinesOpacity(spwid, nc); } totalaverage = totalaverage / getNumChan(spwid); return totalaverage; } Opacity RefractiveIndexProfile::getAverageO3LinesOpacity(unsigned int spwid) { if(!spwidAndIndexAreValid(spwid, 0)) return Opacity(-999.0); Opacity totalaverage; totalaverage = Opacity(0.0, Opacity::UnitNeper); for(unsigned int nc = 0; nc < getNumChan(spwid); nc++) { /* std::cout << " Freq = " << getChanFreq(spwid,nc).get(Frequency::UnitGigaHertz) << " O3 opacity = " << getO3LinesOpacity(spwid,nc).get(Opacity::UnitNeper) << " O3 pathlength = " << getO3LinesPathLength(spwid,nc).get(Length::Microns) << " O2 opacity = " << getO2LinesOpacity(spwid,nc).get(Opacity::UnitNeper) << " O2 pathlength = " << getO2LinesPathLength(spwid,nc).get(Length::Microns) << std::endl; */ totalaverage = totalaverage + getO3LinesOpacity(spwid, nc); } totalaverage = totalaverage / getNumChan(spwid); return totalaverage; } Opacity RefractiveIndexProfile::getAverageN2OLinesOpacity(unsigned int spwid) { if(!spwidAndIndexAreValid(spwid, 0)) return Opacity(-999.0); Opacity totalaverage; totalaverage = Opacity(0.0, Opacity::UnitNeper); for(unsigned int nc = 0; nc < getNumChan(spwid); nc++) { totalaverage = totalaverage + getN2OLinesOpacity(spwid, nc); } totalaverage = totalaverage / getNumChan(spwid); return totalaverage; } Opacity RefractiveIndexProfile::getAverageNO2LinesOpacity(unsigned int spwid) { if(!spwidAndIndexAreValid(spwid, 0)) return Opacity(-999.0); Opacity totalaverage; totalaverage = Opacity(0.0, Opacity::UnitNeper); for(unsigned int nc = 0; nc < getNumChan(spwid); nc++) { totalaverage = totalaverage + getNO2LinesOpacity(spwid, nc); } totalaverage = totalaverage / getNumChan(spwid); return totalaverage; } Opacity RefractiveIndexProfile::getAverageSO2LinesOpacity(unsigned int spwid) { if(!spwidAndIndexAreValid(spwid, 0)) return Opacity(-999.0); Opacity totalaverage; totalaverage = Opacity(0.0, Opacity::UnitNeper); for(unsigned int nc = 0; nc < getNumChan(spwid); nc++) { totalaverage = totalaverage + getSO2LinesOpacity(spwid, nc); } totalaverage = totalaverage / getNumChan(spwid); return totalaverage; } Opacity RefractiveIndexProfile::getAverageCOLinesOpacity(unsigned int spwid) { if(!spwidAndIndexAreValid(spwid, 0)) return Opacity(-999.0); Opacity totalaverage; totalaverage = Opacity(0.0, Opacity::UnitNeper); for(unsigned int nc = 0; nc < getNumChan(spwid); nc++) { totalaverage = totalaverage + getCOLinesOpacity(spwid, nc); } totalaverage = totalaverage / getNumChan(spwid); return totalaverage; } Opacity RefractiveIndexProfile::getAverageDryContOpacity(unsigned int spwid) { if(!spwidAndIndexAreValid(spwid, 0)) return Opacity(-999.0); Opacity totalaverage; totalaverage = Opacity(0.0, Opacity::UnitNeper); for(unsigned int nc = 0; nc < getNumChan(spwid); nc++) { totalaverage = totalaverage + getDryContOpacity(spwid, nc); } totalaverage = totalaverage / getNumChan(spwid); return totalaverage; } Opacity RefractiveIndexProfile::getDryContOpacity() { return getDryContOpacity(0); } Opacity RefractiveIndexProfile::getDryContOpacity(unsigned int nc) { if(!chanIndexIsValid(nc)) return Opacity(-999.0); double kv = 0; for(unsigned int j = 0; j < numLayer_; j++) { kv = kv + imag(vv_N_DryContPtr_[nc]->at(j)) * v_layerThickness_[j]; } return Opacity(kv); } Opacity RefractiveIndexProfile::getDryContOpacity(unsigned int spwid, unsigned int nc) { if(!spwidAndIndexAreValid(spwid, nc)) return Opacity(-999.0); return getDryContOpacity(v_transfertId_[spwid] + nc); } Opacity RefractiveIndexProfile::getO2LinesOpacity() { return getO2LinesOpacity(0); } Opacity RefractiveIndexProfile::getO2LinesOpacity(unsigned int nc) { if(!chanIndexIsValid(nc)) return Opacity(-999.0); double kv = 0; for(unsigned int j = 0; j < numLayer_; j++) { kv = kv + imag(vv_N_O2LinesPtr_[nc]->at(j)) * v_layerThickness_[j]; } return Opacity(kv); } Opacity RefractiveIndexProfile::getO2LinesOpacity(unsigned int spwid, unsigned int nc) { if(!spwidAndIndexAreValid(spwid, nc)) return Opacity(-999.0); return getO2LinesOpacity(v_transfertId_[spwid] + nc); } Opacity RefractiveIndexProfile::getCOLinesOpacity() { return getCOLinesOpacity(0); } Opacity RefractiveIndexProfile::getCOLinesOpacity(unsigned int nc) { if(!chanIndexIsValid(nc)) return Opacity(-999.0); double kv = 0; for(unsigned int j = 0; j < numLayer_; j++) { kv = kv + imag(vv_N_COLinesPtr_[nc]->at(j)) * v_layerThickness_[j]; } return Opacity(kv); } Opacity RefractiveIndexProfile::getCOLinesOpacity(unsigned int spwid, unsigned int nc) { if(!spwidAndIndexAreValid(spwid, nc)) return Opacity(-999.0); return getCOLinesOpacity(v_transfertId_[spwid] + nc); } Opacity RefractiveIndexProfile::getN2OLinesOpacity() { return getN2OLinesOpacity(0); } Opacity RefractiveIndexProfile::getNO2LinesOpacity() { return getNO2LinesOpacity(0); } Opacity RefractiveIndexProfile::getSO2LinesOpacity() { return getSO2LinesOpacity(0); } Opacity RefractiveIndexProfile::getN2OLinesOpacity(unsigned int nc) { if(!chanIndexIsValid(nc)) return Opacity(-999.0); double kv = 0; for(unsigned int j = 0; j < numLayer_; j++) { kv = kv + imag(vv_N_N2OLinesPtr_[nc]->at(j)) * v_layerThickness_[j]; } return Opacity(kv); } Opacity RefractiveIndexProfile::getN2OLinesOpacity(unsigned int spwid, unsigned int nc) { if(!spwidAndIndexAreValid(spwid, nc)) return Opacity(-999.0); return getN2OLinesOpacity(v_transfertId_[spwid] + nc); } Opacity RefractiveIndexProfile::getNO2LinesOpacity(unsigned int nc) { if(!chanIndexIsValid(nc)) return Opacity(-999.0); double kv = 0; for(unsigned int j = 0; j < numLayer_; j++) { kv = kv + imag(vv_N_NO2LinesPtr_[nc]->at(j)) * v_layerThickness_[j]; } return Opacity(kv); } Opacity RefractiveIndexProfile::getNO2LinesOpacity(unsigned int spwid, unsigned int nc) { if(!spwidAndIndexAreValid(spwid, nc)) return Opacity(-999.0); return getNO2LinesOpacity(v_transfertId_[spwid] + nc); } Opacity RefractiveIndexProfile::getSO2LinesOpacity(unsigned int nc) { if(!chanIndexIsValid(nc)) return Opacity(-999.0); double kv = 0; for(unsigned int j = 0; j < numLayer_; j++) { kv = kv + imag(vv_N_SO2LinesPtr_[nc]->at(j)) * v_layerThickness_[j]; } return Opacity(kv); } Opacity RefractiveIndexProfile::getSO2LinesOpacity(unsigned int spwid, unsigned int nc) { if(!spwidAndIndexAreValid(spwid, nc)) return Opacity(-999.0); return getSO2LinesOpacity(v_transfertId_[spwid] + nc); } Opacity RefractiveIndexProfile::getO3LinesOpacity() { return getO3LinesOpacity(0); } Opacity RefractiveIndexProfile::getO3LinesOpacity(unsigned int nc) { if(!chanIndexIsValid(nc)) return Opacity(-999.0); double kv = 0; for(unsigned int j = 0; j < numLayer_; j++) { kv = kv + imag(vv_N_O3LinesPtr_[nc]->at(j)) * v_layerThickness_[j]; } return Opacity(kv); } Opacity RefractiveIndexProfile::getO3LinesOpacity(unsigned int spwid, unsigned int nc) { if(!spwidAndIndexAreValid(spwid, nc)) return Opacity(-999.0); return getO3LinesOpacity(v_transfertId_[spwid] + nc); } Opacity RefractiveIndexProfile::getWetOpacity(const Length &integratedwatercolumn) { // std::cout << "1 integratedwatercolumn.get()=" << integratedwatercolumn.get() << std::endl; // std::cout << "2 getGroundWH2O().get()=" << getGroundWH2O().get() << std::endl; // std::cout << "3 getWetOpacity()=" << std::endl; // std::cout << "4 " << std::endl; return getWetOpacity(getGroundWH2O(),0)*(integratedwatercolumn.get()/getGroundWH2O().get()); // 2010_SEP02: return getWetOpacity(integratedwatercolumn,0)*(integratedwatercolumn.get()/getGroundWH2O().get()); } Opacity RefractiveIndexProfile::getWetOpacity(const Length &integratedwatercolumn, unsigned int nc) { if(!chanIndexIsValid(nc)) return Opacity(-999.0); double kv = 0; /* std::cout<<"nc="<<nc<<endl; */ for(unsigned int j = 0; j < numLayer_; j++) { kv = kv + imag(vv_N_H2OLinesPtr_[nc]->at(j) + vv_N_H2OContPtr_[nc]->at(j)) * v_layerThickness_[j]; } return Opacity(kv*(integratedwatercolumn.get()/getGroundWH2O().get())); } Opacity RefractiveIndexProfile::getWetOpacity(const Length & integratedwatercolumn, unsigned int spwid, unsigned int nc) { if(!spwidAndIndexAreValid(spwid, nc)) return Opacity(-999.0); return getWetOpacity(integratedwatercolumn,v_transfertId_[spwid] + nc); } Opacity RefractiveIndexProfile::getAverageWetOpacity(const Length &integratedwatercolumn, unsigned int spwid) { if(!spwidAndIndexAreValid(spwid, 0)) return Opacity(-999.0); Opacity totalaverage; totalaverage = Opacity(0.0, Opacity::UnitNeper); for(unsigned int nc = 0; nc < getNumChan(spwid); nc++) { totalaverage = totalaverage + getWetOpacity(integratedwatercolumn, spwid, nc); } totalaverage = totalaverage / getNumChan(spwid); return totalaverage; } Opacity RefractiveIndexProfile::getH2OLinesOpacity(const Length &integratedwatercolumn) { return getH2OLinesOpacity(integratedwatercolumn,0); } Opacity RefractiveIndexProfile::getH2OLinesOpacity(const Length &integratedwatercolumn, unsigned int nc) { if(!chanIndexIsValid(nc)) return Opacity(-999.0); double kv = 0; for(unsigned int j = 0; j < numLayer_; j++) { /* std::cout <<"j="<<j<<" abs H2O Lines ="<<vv_N_H2OLinesPtr_[nc]->at(j) <<endl; */ kv = kv + imag(vv_N_H2OLinesPtr_[nc]->at(j)) * v_layerThickness_[j]; } return Opacity(kv*(integratedwatercolumn.get()/getGroundWH2O().get())); } Opacity RefractiveIndexProfile::getH2OLinesOpacity(const Length &integratedwatercolumn, unsigned int spwid, unsigned int nc) { if(!spwidAndIndexAreValid(spwid, nc)) return Opacity(-999.0); return getH2OLinesOpacity(integratedwatercolumn,v_transfertId_[spwid] + nc); } Opacity RefractiveIndexProfile::getAverageH2OLinesOpacity(const Length &integratedwatercolumn, unsigned int spwid) { if(!spwidAndIndexAreValid(spwid, 0)) return Opacity(-999.0); Opacity totalaverage; totalaverage = Opacity(0.0, Opacity::UnitNeper); for(unsigned int nc = 0; nc < getNumChan(spwid); nc++) { totalaverage = totalaverage + getH2OLinesOpacity(integratedwatercolumn,spwid, nc); } totalaverage = totalaverage / getNumChan(spwid); return totalaverage; } Opacity RefractiveIndexProfile::getH2OContOpacity(const Length &integratedwatercolumn) { return getH2OContOpacity(integratedwatercolumn,0); } Opacity RefractiveIndexProfile::getH2OContOpacity(const Length &integratedwatercolumn, unsigned int nc) { if(!chanIndexIsValid(nc)) return Opacity(-999.0); double kv = 0; for(unsigned int j = 0; j < numLayer_; j++) { kv = kv + imag(vv_N_H2OContPtr_[nc]->at(j)) * v_layerThickness_[j]; } return Opacity(kv*(integratedwatercolumn.get()/getGroundWH2O().get())); } Opacity RefractiveIndexProfile::getH2OContOpacity(const Length &integratedwatercolumn, unsigned int spwid, unsigned int nc) { if(!spwidAndIndexAreValid(spwid, nc)) return Opacity(-999.0); return getH2OContOpacity(integratedwatercolumn,v_transfertId_[spwid] + nc); } Opacity RefractiveIndexProfile::getAverageH2OContOpacity(const Length &integratedwatercolumn, unsigned int spwid) { if(!spwidAndIndexAreValid(spwid, 0)) return Opacity(-999.0); Opacity totalaverage; totalaverage = Opacity(0.0, Opacity::UnitNeper); for(unsigned int nc = 0; nc < getNumChan(spwid); nc++) { totalaverage = totalaverage + getH2OContOpacity(integratedwatercolumn,spwid, nc); } totalaverage = totalaverage / getNumChan(spwid); return totalaverage; } Angle RefractiveIndexProfile::getDispersiveH2OPhaseDelay(const Length &integratedwatercolumn) { return getDispersiveH2OPhaseDelay(integratedwatercolumn,0); } Length RefractiveIndexProfile::getDispersiveH2OPathLength(const Length &integratedwatercolumn) { return getDispersiveH2OPathLength(integratedwatercolumn,0); } Angle RefractiveIndexProfile::getDispersiveH2OPhaseDelay(const Length &integratedwatercolumn, unsigned int nc) { if(!chanIndexIsValid(nc)) { return Angle(-999.0, Angle::UnitDegree); } double kv = 0; for(unsigned int j = 0; j < numLayer_; j++) { kv = kv + real(vv_N_H2OLinesPtr_[nc]->at(j)) * v_layerThickness_[j]; } Angle aa(kv*(integratedwatercolumn.get()/getGroundWH2O().get())* 57.29578, Angle::UnitDegree); return aa; } Length RefractiveIndexProfile::getDispersiveH2OPathLength(const Length &integratedwatercolumn, unsigned int nc) { if(!chanIndexIsValid(nc)) { return Length(-999.0, Length::UnitMeter); } double wavelength = 299792458.0 / v_chanFreq_[nc]; // in m Length ll((wavelength / 360.0) * getDispersiveH2OPhaseDelay(integratedwatercolumn,nc).get(Angle::UnitDegree), Length::UnitMeter); return ll; } Angle RefractiveIndexProfile::getDispersiveH2OPhaseDelay(const Length &integratedwatercolumn, unsigned int spwid, unsigned int nc) { if(!spwidAndIndexAreValid(spwid, nc)) { return Angle(-999.0, Angle::UnitDegree); } return getDispersiveH2OPhaseDelay(integratedwatercolumn,v_transfertId_[spwid] + nc); } Angle RefractiveIndexProfile::getAverageDispersiveH2OPhaseDelay(const Length &integratedwatercolumn, unsigned int spwid) { if(!spwidAndIndexAreValid(spwid, 0)) { return Angle(-999.0, Angle::UnitDegree); } double av = 0.0; for(unsigned int i = 0; i < getNumChan(spwid); i++) { av = av + getDispersiveH2OPhaseDelay(integratedwatercolumn,v_transfertId_[spwid] + i).get(Angle::UnitDegree); } av = av / getNumChan(spwid); Angle average(av, Angle::UnitDegree); return average; } Length RefractiveIndexProfile::getDispersiveH2OPathLength(const Length &integratedwatercolumn, unsigned int spwid, unsigned int nc) { if(!spwidAndIndexAreValid(spwid, nc)) { return Length(-999.0, Length::UnitMeter); } return getDispersiveH2OPathLength(integratedwatercolumn,v_transfertId_[spwid] + nc); } Length RefractiveIndexProfile::getAverageDispersiveH2OPathLength(const Length &integratedwatercolumn, unsigned int spwid) { if(!spwidAndIndexAreValid(spwid, 0)) { return Length(-999.0, Length::UnitMeter); } double av = 0.0; for(unsigned int i = 0; i < getNumChan(spwid); i++) { av = av + getDispersiveH2OPathLength(integratedwatercolumn,v_transfertId_[spwid] + i).get(Length::UnitMilliMeter); } av = av / getNumChan(spwid); Length average(av, Length::UnitMilliMeter); return average; } Angle RefractiveIndexProfile::getNonDispersiveDryPhaseDelay() { return getNonDispersiveDryPhaseDelay(0); } Length RefractiveIndexProfile::getNonDispersiveDryPathLength() { return getNonDispersiveDryPathLength(0); } Angle RefractiveIndexProfile::getDispersiveDryPhaseDelay() { return getDispersiveDryPhaseDelay(0); } Length RefractiveIndexProfile::getDispersiveDryPathLength() { return getDispersiveDryPathLength(0); } Angle RefractiveIndexProfile::getNonDispersiveDryPhaseDelay(unsigned int nc) { if(!chanIndexIsValid(nc)) { return Angle(-999.0, Angle::UnitDegree); } double kv = 0; for(unsigned int j = 0; j < numLayer_; j++) { kv = kv + real(vv_N_DryContPtr_[nc]->at(j)) * v_layerThickness_[j]; } Angle aa(kv * 57.29578, Angle::UnitDegree); return aa; } Angle RefractiveIndexProfile::getDispersiveDryPhaseDelay(unsigned int nc) { // std::cout << "getO2LinesPhaseDelay(" << nc << ")=" << getO2LinesPhaseDelay(nc).get(Angle::UnitDegree) << std::endl; // std::cout << "getO3LinesPhaseDelay(" << nc << ")=" << getO3LinesPhaseDelay(nc).get(Angle::UnitDegree) << std::endl; // std::cout << "getN2OLinesPhaseDelay(" << nc << ")=" << getN2OLinesPhaseDelay(nc).get(Angle::UnitDegree) << std::endl; // std::cout << "getNO2LinesPhaseDelay(" << nc << ")=" << getNO2LinesPhaseDelay(nc).get(Angle::UnitDegree) << std::endl; // std::cout << "getSO2LinesPhaseDelay(" << nc << ")=" << getSO2LinesPhaseDelay(nc).get(Angle::UnitDegree) << std::endl; // std::cout << "getCOLinesPhaseDelay(" << nc << ")=" << getCOLinesPhaseDelay(nc).get(Angle::UnitDegree) << std::endl; return getO2LinesPhaseDelay(nc) + getO3LinesPhaseDelay(nc) + getN2OLinesPhaseDelay(nc) + getCOLinesPhaseDelay(nc) + getNO2LinesPhaseDelay(nc) + getSO2LinesPhaseDelay(nc); } Length RefractiveIndexProfile::getNonDispersiveDryPathLength(unsigned int nc) { if(!chanIndexIsValid(nc)) { return Length(-999.0, Length::UnitMeter); } double wavelength = 299792458.0 / v_chanFreq_[nc]; // in m Length ll((wavelength / 360.0) * getNonDispersiveDryPhaseDelay(nc).get(Angle::UnitDegree), Length::UnitMeter); return ll; } Angle RefractiveIndexProfile::getNonDispersiveDryPhaseDelay(unsigned int spwid, unsigned int nc) { if(!spwidAndIndexAreValid(spwid, nc)) { return Angle(-999.0, Angle::UnitDegree); } return getNonDispersiveDryPhaseDelay(v_transfertId_[spwid] + nc); } Length RefractiveIndexProfile::getDispersiveDryPathLength(unsigned int nc) { if(!chanIndexIsValid(nc)) { return Length(-999.0, Length::UnitMeter); } double wavelength = 299792458.0 / v_chanFreq_[nc]; // in m Length ll((wavelength / 360.0) * getDispersiveDryPhaseDelay(nc).get(Angle::UnitDegree), Length::UnitMeter); return ll; } Angle RefractiveIndexProfile::getDispersiveDryPhaseDelay(unsigned int spwid, unsigned int nc) { if(!spwidAndIndexAreValid(spwid, nc)) { return Angle(-999.0, Angle::UnitDegree); } return getDispersiveDryPhaseDelay(v_transfertId_[spwid] + nc); } Angle RefractiveIndexProfile::getAverageNonDispersiveDryPhaseDelay(unsigned int spwid) { if(!spwidAndIndexAreValid(spwid, 0)) { return Angle(-999.0, Angle::UnitDegree); } double av = 0.0; for(unsigned int i = 0; i < getNumChan(spwid); i++) { av = av + getNonDispersiveDryPhaseDelay(v_transfertId_[spwid] + i).get(Angle::UnitDegree); } av = av / getNumChan(spwid); Angle average(av, Angle::UnitDegree); return average; } Angle RefractiveIndexProfile::getAverageDispersiveDryPhaseDelay(unsigned int spwid) { if(!spwidAndIndexAreValid(spwid, 0)) { return Angle(-999.0, Angle::UnitDegree); } double av = 0.0; for(unsigned int i = 0; i < getNumChan(spwid); i++) { av = av + getDispersiveDryPhaseDelay(v_transfertId_[spwid] + i).get(Angle::UnitDegree); } av = av / getNumChan(spwid); Angle average(av, Angle::UnitDegree); return average; } Length RefractiveIndexProfile::getNonDispersiveDryPathLength(unsigned int spwid, unsigned int nc) { if(!spwidAndIndexAreValid(spwid, nc)) { return Length(-999.0, Length::UnitMeter); } return getNonDispersiveDryPathLength(v_transfertId_[spwid] + nc); } Length RefractiveIndexProfile::getDispersiveDryPathLength(unsigned int spwid, unsigned int nc) { if(!spwidAndIndexAreValid(spwid, nc)) { return Length(-999.0, Length::UnitMeter); } return getDispersiveDryPathLength(v_transfertId_[spwid] + nc); } Length RefractiveIndexProfile::getAverageNonDispersiveDryPathLength(unsigned int spwid) { if(!spwidAndIndexAreValid(spwid, 0)) { return Length(-999.0, Length::UnitMeter); } double av = 0.0; for(unsigned int i = 0; i < getNumChan(spwid); i++) { av = av + getNonDispersiveDryPathLength(v_transfertId_[spwid] + i).get(Length::UnitMilliMeter); } av = av / getNumChan(spwid); Length average(av, Length::UnitMilliMeter); return average; } Length RefractiveIndexProfile::getAverageDispersiveDryPathLength(unsigned int spwid) { if(!spwidAndIndexAreValid(spwid, 0)) { return Length(-999.0, Length::UnitMeter); } double av = 0.0; for(unsigned int i = 0; i < getNumChan(spwid); i++) { av = av + getDispersiveDryPathLength(v_transfertId_[spwid] + i).get(Length::UnitMilliMeter); } av = av / getNumChan(spwid); Length average(av, Length::UnitMilliMeter); return average; } Angle RefractiveIndexProfile::getO2LinesPhaseDelay() { return getO2LinesPhaseDelay(0); } Length RefractiveIndexProfile::getO2LinesPathLength() { return getO2LinesPathLength(0); } Angle RefractiveIndexProfile::getO2LinesPhaseDelay(unsigned int nc) { if(!chanIndexIsValid(nc)) { return Angle(-999.0, Angle::UnitDegree); } double kv = 0; for(unsigned int j = 0; j < numLayer_; j++) { kv = kv + real(vv_N_O2LinesPtr_[nc]->at(j)) * v_layerThickness_[j]; } Angle aa(kv * 57.29578, Angle::UnitDegree); return aa; } Length RefractiveIndexProfile::getO2LinesPathLength(unsigned int nc) { if(!chanIndexIsValid(nc)) { return Length(-999.0, Length::UnitMeter); } double wavelength = 299792458.0 / v_chanFreq_[nc]; // in m Length ll((wavelength / 360.0) * getO2LinesPhaseDelay(nc).get(Angle::UnitDegree), Length::UnitMeter); return ll; } Angle RefractiveIndexProfile::getO2LinesPhaseDelay(unsigned int spwid, unsigned int nc) { if(!spwidAndIndexAreValid(spwid, nc)) { return Angle(-999.0, Angle::UnitDegree); } return getO2LinesPhaseDelay(v_transfertId_[spwid] + nc); } Angle RefractiveIndexProfile::getAverageO2LinesPhaseDelay(unsigned int spwid) { if(!spwidAndIndexAreValid(spwid, 0)) { return Angle(-999.0, Angle::UnitDegree); } double av = 0.0; for(unsigned int i = 0; i < getNumChan(spwid); i++) { av = av + getO2LinesPhaseDelay(v_transfertId_[spwid] + i).get(Angle::UnitDegree); } av = av / getNumChan(spwid); Angle average(av, Angle::UnitDegree); return average; } Length RefractiveIndexProfile::getO2LinesPathLength(unsigned int spwid, unsigned int nc) { if(!spwidAndIndexAreValid(spwid, nc)) { return Length(-999.0, Length::UnitMeter); } return getO2LinesPathLength(v_transfertId_[spwid] + nc); } Length RefractiveIndexProfile::getAverageO2LinesPathLength(unsigned int spwid) { if(!spwidAndIndexAreValid(spwid, 0)) { return Length(-999.0, Length::UnitMeter); } double av = 0.0; for(unsigned int i = 0; i < getNumChan(spwid); i++) { av = av + getO2LinesPathLength(v_transfertId_[spwid] + i).get(Length::UnitMilliMeter); } av = av / getNumChan(spwid); Length average(av, Length::UnitMilliMeter); return average; } Angle RefractiveIndexProfile::getO3LinesPhaseDelay() { return getO3LinesPhaseDelay(0); } Length RefractiveIndexProfile::getO3LinesPathLength() { return getO3LinesPathLength(0); } Angle RefractiveIndexProfile::getO3LinesPhaseDelay(unsigned int nc) { if(!chanIndexIsValid(nc)) { return Angle(-999.0, Angle::UnitDegree); } double kv = 0; // if(nc=66){cout << "vv_N_O3LinesPtr_" << ".size()=" << vv_N_O3LinesPtr_.size() << std::endl;} for(unsigned int j = 0; j < numLayer_; j++) { /* if(nc=66){ std::cout << "j=" << j << " vv_N_O3LinesPtr_[" << nc << "]->at(" << j << ")=" << vv_N_O3LinesPtr_[nc]->at(j) << std::endl; } */ kv = kv + real(vv_N_O3LinesPtr_[nc]->at(j)) * v_layerThickness_[j]; } Angle aa(kv * 57.29578, Angle::UnitDegree); return aa; } Length RefractiveIndexProfile::getO3LinesPathLength(unsigned int nc) { if(!chanIndexIsValid(nc)) { return Length(-999.0, Length::UnitMeter); } double wavelength = 299792458.0 / v_chanFreq_[nc]; // in m Length ll((wavelength / 360.0) * getO3LinesPhaseDelay(nc).get(Angle::UnitDegree), Length::UnitMeter); return ll; } Angle RefractiveIndexProfile::getO3LinesPhaseDelay(unsigned int spwid, unsigned int nc) { if(!spwidAndIndexAreValid(spwid, nc)) { return Angle(-999.0, Angle::UnitDegree); } return getO3LinesPhaseDelay(v_transfertId_[spwid] + nc); } Angle RefractiveIndexProfile::getAverageO3LinesPhaseDelay(unsigned int spwid) { if(!spwidAndIndexAreValid(spwid, 0)) { return Angle(-999.0, Angle::UnitDegree); } double av = 0.0; for(unsigned int i = 0; i < getNumChan(spwid); i++) { av = av + getO3LinesPhaseDelay(v_transfertId_[spwid] + i).get(Angle::UnitDegree); } av = av / getNumChan(spwid); Angle average(av, Angle::UnitDegree); return average; } Length RefractiveIndexProfile::getO3LinesPathLength(unsigned int spwid, unsigned int nc) { if(!spwidAndIndexAreValid(spwid, nc)) { return Length(-999.0, Length::UnitMeter); } return getO3LinesPathLength(v_transfertId_[spwid] + nc); } Length RefractiveIndexProfile::getAverageO3LinesPathLength(unsigned int spwid) { if(!spwidAndIndexAreValid(spwid, 0)) { return Length(-999.0, Length::UnitMeter); } double av = 0.0; for(unsigned int i = 0; i < getNumChan(spwid); i++) { av = av + getO3LinesPathLength(v_transfertId_[spwid] + i).get(Length::UnitMilliMeter); } av = av / getNumChan(spwid); Length average(av, Length::UnitMilliMeter); return average; } Angle RefractiveIndexProfile::getCOLinesPhaseDelay() { return getCOLinesPhaseDelay(0); } Length RefractiveIndexProfile::getCOLinesPathLength() { return getCOLinesPathLength(0); } Angle RefractiveIndexProfile::getCOLinesPhaseDelay(unsigned int nc) { if(!chanIndexIsValid(nc)) { return Angle(-999.0, Angle::UnitDegree); } double kv = 0; for(unsigned int j = 0; j < numLayer_; j++) { kv = kv + real(vv_N_COLinesPtr_[nc]->at(j)) * v_layerThickness_[j]; } Angle aa(kv * 57.29578, Angle::UnitDegree); return aa; } Length RefractiveIndexProfile::getCOLinesPathLength(unsigned int nc) { if(!chanIndexIsValid(nc)) { return Length(-999.0, Length::UnitMeter); } double wavelength = 299792458.0 / v_chanFreq_[nc]; // in m Length ll((wavelength / 360.0) * getCOLinesPhaseDelay(nc).get(Angle::UnitDegree), Length::UnitMeter); return ll; } Angle RefractiveIndexProfile::getCOLinesPhaseDelay(unsigned int spwid, unsigned int nc) { if(!spwidAndIndexAreValid(spwid, nc)) { return Angle(-999.0, Angle::UnitDegree); } return getCOLinesPhaseDelay(v_transfertId_[spwid] + nc); } Angle RefractiveIndexProfile::getAverageCOLinesPhaseDelay(unsigned int spwid) { if(!spwidAndIndexAreValid(spwid, 0)) { return Angle(-999.0, Angle::UnitDegree); } double av = 0.0; for(unsigned int i = 0; i < getNumChan(spwid); i++) { av = av + getCOLinesPhaseDelay(v_transfertId_[spwid] + i).get(Angle::UnitDegree); } av = av / getNumChan(spwid); Angle average(av, Angle::UnitDegree); return average; } Length RefractiveIndexProfile::getCOLinesPathLength(unsigned int spwid, unsigned int nc) { if(!spwidAndIndexAreValid(spwid, nc)) { return Length(-999.0, Length::UnitMeter); } return getCOLinesPathLength(v_transfertId_[spwid] + nc); } Length RefractiveIndexProfile::getAverageCOLinesPathLength(unsigned int spwid) { if(!spwidAndIndexAreValid(spwid, 0)) { return Length(-999.0, Length::UnitMeter); } double av = 0.0; for(unsigned int i = 0; i < getNumChan(spwid); i++) { av = av + getCOLinesPathLength(v_transfertId_[spwid] + i).get(Length::UnitMilliMeter); } av = av / getNumChan(spwid); Length average(av, Length::UnitMilliMeter); return average; } Angle RefractiveIndexProfile::getN2OLinesPhaseDelay() { return getN2OLinesPhaseDelay(0); } Length RefractiveIndexProfile::getN2OLinesPathLength() { return getN2OLinesPathLength(0); } Angle RefractiveIndexProfile::getN2OLinesPhaseDelay(unsigned int nc) { if(!chanIndexIsValid(nc)) { return Angle(-999.0, Angle::UnitDegree); } double kv = 0; for(unsigned int j = 0; j < numLayer_; j++) { kv = kv + real(vv_N_N2OLinesPtr_[nc]->at(j)) * v_layerThickness_[j]; } Angle aa(kv * 57.29578, Angle::UnitDegree); return aa; } Length RefractiveIndexProfile::getN2OLinesPathLength(unsigned int nc) { if(!chanIndexIsValid(nc)) { return Length(-999.0, Length::UnitMeter); } double wavelength = 299792458.0 / v_chanFreq_[nc]; // in m Length ll((wavelength / 360.0) * getN2OLinesPhaseDelay(nc).get(Angle::UnitDegree), Length::UnitMeter); return ll; } Angle RefractiveIndexProfile::getN2OLinesPhaseDelay(unsigned int spwid, unsigned int nc) { if(!spwidAndIndexAreValid(spwid, nc)) { return Angle(-999.0, Angle::UnitDegree); } return getN2OLinesPhaseDelay(v_transfertId_[spwid] + nc); } Angle RefractiveIndexProfile::getAverageN2OLinesPhaseDelay(unsigned int spwid) { if(!spwidAndIndexAreValid(spwid, 0)) { return Angle(-999.0, Angle::UnitDegree); } double av = 0.0; for(unsigned int i = 0; i < getNumChan(spwid); i++) { av = av + getN2OLinesPhaseDelay(v_transfertId_[spwid] + i).get(Angle::UnitDegree); } av = av / getNumChan(spwid); Angle average(av, Angle::UnitDegree); return average; } Length RefractiveIndexProfile::getN2OLinesPathLength(unsigned int spwid, unsigned int nc) { if(!spwidAndIndexAreValid(spwid, nc)) { return Length(-999.0, Length::UnitMeter); } return getN2OLinesPathLength(v_transfertId_[spwid] + nc); } Length RefractiveIndexProfile::getAverageN2OLinesPathLength(unsigned int spwid) { if(!spwidAndIndexAreValid(spwid, 0)) { return Length(-999.0, Length::UnitMeter); } double av = 0.0; for(unsigned int i = 0; i < getNumChan(spwid); i++) { av = av + getN2OLinesPathLength(v_transfertId_[spwid] + i).get(Length::UnitMilliMeter); } av = av / getNumChan(spwid); Length average(av, Length::UnitMilliMeter); return average; } Angle RefractiveIndexProfile::getNO2LinesPhaseDelay() { return getNO2LinesPhaseDelay(0); } Length RefractiveIndexProfile::getNO2LinesPathLength() { return getNO2LinesPathLength(0); } Angle RefractiveIndexProfile::getNO2LinesPhaseDelay(unsigned int nc) { if(!chanIndexIsValid(nc)) { return Angle(-999.0, Angle::UnitDegree); } double kv = 0; for(unsigned int j = 0; j < numLayer_; j++) { kv = kv + real(vv_N_NO2LinesPtr_[nc]->at(j)) * v_layerThickness_[j]; } Angle aa(kv * 57.29578, Angle::UnitDegree); return aa; } Length RefractiveIndexProfile::getNO2LinesPathLength(unsigned int nc) { if(!chanIndexIsValid(nc)) { return Length(-999.0, Length::UnitMeter); } double wavelength = 299792458.0 / v_chanFreq_[nc]; // in m Length ll((wavelength / 360.0) * getNO2LinesPhaseDelay(nc).get(Angle::UnitDegree), Length::UnitMeter); return ll; } Angle RefractiveIndexProfile::getNO2LinesPhaseDelay(unsigned int spwid, unsigned int nc) { if(!spwidAndIndexAreValid(spwid, nc)) { return Angle(-999.0, Angle::UnitDegree); } return getNO2LinesPhaseDelay(v_transfertId_[spwid] + nc); } Angle RefractiveIndexProfile::getAverageNO2LinesPhaseDelay(unsigned int spwid) { if(!spwidAndIndexAreValid(spwid, 0)) { return Angle(-999.0, Angle::UnitDegree); } double av = 0.0; for(unsigned int i = 0; i < getNumChan(spwid); i++) { av = av + getNO2LinesPhaseDelay(v_transfertId_[spwid] + i).get(Angle::UnitDegree); } av = av / getNumChan(spwid); Angle average(av, Angle::UnitDegree); return average; } Length RefractiveIndexProfile::getNO2LinesPathLength(unsigned int spwid, unsigned int nc) { if(!spwidAndIndexAreValid(spwid, nc)) { return Length(-999.0, Length::UnitMeter); } return getNO2LinesPathLength(v_transfertId_[spwid] + nc); } Length RefractiveIndexProfile::getAverageNO2LinesPathLength(unsigned int spwid) { if(!spwidAndIndexAreValid(spwid, 0)) { return Length(-999.0, Length::UnitMeter); } double av = 0.0; for(unsigned int i = 0; i < getNumChan(spwid); i++) { av = av + getNO2LinesPathLength(v_transfertId_[spwid] + i).get(Length::UnitMilliMeter); } av = av / getNumChan(spwid); Length average(av, Length::UnitMilliMeter); return average; } Angle RefractiveIndexProfile::getSO2LinesPhaseDelay() { return getSO2LinesPhaseDelay(0); } Length RefractiveIndexProfile::getSO2LinesPathLength() { return getSO2LinesPathLength(0); } Angle RefractiveIndexProfile::getSO2LinesPhaseDelay(unsigned int nc) { if(!chanIndexIsValid(nc)) { return Angle(-999.0, Angle::UnitDegree); } double kv = 0; for(unsigned int j = 0; j < numLayer_; j++) { kv = kv + real(vv_N_SO2LinesPtr_[nc]->at(j)) * v_layerThickness_[j]; } Angle aa(kv * 57.29578, Angle::UnitDegree); return aa; } Length RefractiveIndexProfile::getSO2LinesPathLength(unsigned int nc) { if(!chanIndexIsValid(nc)) { return Length(-999.0, Length::UnitMeter); } double wavelength = 299792458.0 / v_chanFreq_[nc]; // in m Length ll((wavelength / 360.0) * getSO2LinesPhaseDelay(nc).get(Angle::UnitDegree), Length::UnitMeter); return ll; } Angle RefractiveIndexProfile::getSO2LinesPhaseDelay(unsigned int spwid, unsigned int nc) { if(!spwidAndIndexAreValid(spwid, nc)) { return Angle(-999.0, Angle::UnitDegree); } return getSO2LinesPhaseDelay(v_transfertId_[spwid] + nc); } Angle RefractiveIndexProfile::getAverageSO2LinesPhaseDelay(unsigned int spwid) { if(!spwidAndIndexAreValid(spwid, 0)) { return Angle(-999.0, Angle::UnitDegree); } double av = 0.0; for(unsigned int i = 0; i < getNumChan(spwid); i++) { av = av + getSO2LinesPhaseDelay(v_transfertId_[spwid] + i).get(Angle::UnitDegree); } av = av / getNumChan(spwid); Angle average(av, Angle::UnitDegree); return average; } Length RefractiveIndexProfile::getSO2LinesPathLength(unsigned int spwid, unsigned int nc) { if(!spwidAndIndexAreValid(spwid, nc)) { return Length(-999.0, Length::UnitMeter); } return getSO2LinesPathLength(v_transfertId_[spwid] + nc); } Length RefractiveIndexProfile::getAverageSO2LinesPathLength(unsigned int spwid) { if(!spwidAndIndexAreValid(spwid, 0)) { return Length(-999.0, Length::UnitMeter); } double av = 0.0; for(unsigned int i = 0; i < getNumChan(spwid); i++) { av = av + getSO2LinesPathLength(v_transfertId_[spwid] + i).get(Length::UnitMilliMeter); } av = av / getNumChan(spwid); Length average(av, Length::UnitMilliMeter); return average; } Angle RefractiveIndexProfile::getNonDispersiveH2OPhaseDelay(const Length &integratedwatercolumn) { return getNonDispersiveH2OPhaseDelay(integratedwatercolumn,0); } Length RefractiveIndexProfile::getNonDispersiveH2OPathLength(const Length &integratedwatercolumn) { return getNonDispersiveH2OPathLength(integratedwatercolumn,0); } Angle RefractiveIndexProfile::getNonDispersiveH2OPhaseDelay(const Length &integratedwatercolumn, unsigned int nc) { double kv = 0; if(!chanIndexIsValid(nc)) { return Angle(-999.0, Angle::UnitDegree); } for(unsigned int j = 0; j < numLayer_; j++) { kv = kv + real(vv_N_H2OContPtr_[nc]->at(j)) * v_layerThickness_[j]; } Angle aa(kv*(integratedwatercolumn.get()/getGroundWH2O().get())* 57.29578, Angle::UnitDegree); return aa; } Length RefractiveIndexProfile::getNonDispersiveH2OPathLength(const Length &integratedwatercolumn, unsigned int nc) { if(!chanIndexIsValid(nc)) { return Length(-999.0, Length::UnitMeter); } double wavelength = 299792458.0 / v_chanFreq_[nc]; // in m Length ll((wavelength / 360.0) * getNonDispersiveH2OPhaseDelay(integratedwatercolumn,nc).get(Angle::UnitDegree),Length::UnitMeter); return ll; } Angle RefractiveIndexProfile::getNonDispersiveH2OPhaseDelay(const Length &integratedwatercolumn, unsigned int spwid, unsigned int nc) { if(!spwidAndIndexAreValid(spwid, nc)) { return Angle(-999.0, Angle::UnitDegree); } return getNonDispersiveH2OPhaseDelay(integratedwatercolumn,v_transfertId_[spwid] + nc); } Angle RefractiveIndexProfile::getAverageNonDispersiveH2OPhaseDelay(const Length &integratedwatercolumn, unsigned int spwid) { if(!spwidAndIndexAreValid(spwid, 0)) { return Angle(-999.0, Angle::UnitDegree); } double av = 0.0; for(unsigned int i = 0; i < getNumChan(spwid); i++) { av = av + getNonDispersiveH2OPhaseDelay(v_transfertId_[spwid] + i).get(Angle::UnitDegree); } av = av / getNumChan(spwid); Angle average(av*(integratedwatercolumn.get()/getGroundWH2O().get()), Angle::UnitDegree); return average; } Length RefractiveIndexProfile::getNonDispersiveH2OPathLength(const Length &integratedwatercolumn, unsigned int spwid, unsigned int nc) { if(!spwidAndIndexAreValid(spwid, nc)) { return Length(-999.0); } return getNonDispersiveH2OPathLength(integratedwatercolumn,v_transfertId_[spwid] + nc); } Length RefractiveIndexProfile::getAverageNonDispersiveH2OPathLength(const Length &integratedwatercolumn, unsigned int spwid) { if(!spwidAndIndexAreValid(spwid, 0)) { return Length(-999.0); } double av = 0.0; for(unsigned int i = 0; i < getNumChan(spwid); i++) { av = av + getNonDispersiveH2OPathLength(integratedwatercolumn,v_transfertId_[spwid] + i).get(Length::UnitMeter); } av = av / getNumChan(spwid); Length average(av, Length::UnitMeter); return average; } // NB: the function chanIndexIsValid will be overrided by .... bool RefractiveIndexProfile::chanIndexIsValid(unsigned int nc) { if(nc < vv_N_H2OLinesPtr_.size()) return true; if(nc < v_chanFreq_.size()) { std::cout << " RefractiveIndexProfile: Requested index in a new spectral window ==> update profile" << std::endl; mkRefractiveIndexProfile(); // std::cout << "...and we return" << std::endl; return true; } std::cout << " RefractiveIndexProfile: ERROR: Invalid channel frequency index" << std::endl; return false; } // NB: the function spwidAndIndexAreValid will be overrided by ... bool RefractiveIndexProfile::spwidAndIndexAreValid(unsigned int spwid, unsigned int idx) { if(spwid > getNumSpectralWindow() - 1) { std::cout << " RefractiveIndexProfile: ERROR: spectral window identifier out of range " << std::endl; return false; } if(idx > getNumChan(spwid) - 1) { std::cout << " RefractiveIndexProfile: ERROR: channel index out of range " << std::endl; return false; } unsigned int nc = v_transfertId_[spwid] + idx; bool valid = chanIndexIsValid(nc); return valid; } void RefractiveIndexProfile::updateNewSpectralWindows() { mkRefractiveIndexProfile(); } ATM_NAMESPACE_END