//#--------------------------------------------------------------------------- //# MBrecord.cc: Class to store an MBFITS single-dish data record. //#--------------------------------------------------------------------------- //# livedata - processing pipeline for single-dish, multibeam spectral data. //# Copyright (C) 2000-2009, Australia Telescope National Facility, CSIRO //# //# This file is part of livedata. //# //# livedata is free software: you can redistribute it and/or modify it under //# the terms of the GNU General Public License as published by the Free //# Software Foundation, either version 3 of the License, or (at your option) //# any later version. //# //# livedata 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 General Public License for //# more details. //# //# You should have received a copy of the GNU General Public License along //# with livedata. If not, see . //# //# Correspondence concerning livedata may be directed to: //# Internet email: mcalabre@atnf.csiro.au //# Postal address: Dr. Mark Calabretta //# Australia Telescope National Facility, CSIRO //# PO Box 76 //# Epping NSW 1710 //# AUSTRALIA //# //# http://www.atnf.csiro.au/computing/software/livedata.html //# $Id: MBrecord.cc,v 19.14 2009-09-29 07:33:38 cal103 Exp $ //#--------------------------------------------------------------------------- //# The MBrecord class stores an MBFITS single-dish data record. //# //# Original: 2000/08/01 Mark Calabretta, ATNF //#--------------------------------------------------------------------------- #include #include //--------------------------------------------------------- MBrecord::MBrecord // Default constructor. MBrecord::MBrecord(int nif) { // Construct arrays for the required number of IFs. cNIF = 0; setNIFs(nif); scanNo = 0; cycleNo = 0; beamNo = 0; pCode = 0; rateAge = 0.0f; raRate = 0.0f; decRate = 0.0f; nIF = 0; } //-------------------------------------------------------- MBrecord::~MBrecord // Destructor. MBrecord::~MBrecord() { free(); } //---------------------------------------------------------- MBrecord::setNIFs // Expand arrays if necessary to accomodate the required number of IFs; never // contracts them. void MBrecord::setNIFs(int nif) { if (nif < 1) return; if (cNIF < nif) { // Too few IFs, free everything. if (cNIF) free(); } if (cNIF == 0) { IFno = new short[nif]; nChan = new int[nif]; nPol = new int[nif]; fqRefPix = new float[nif]; fqRefVal = new double[nif]; fqDelt = new double[nif]; tsys = new float[nif][2]; calfctr = new float[nif][2]; xcalfctr = new float[nif][2]; baseLin = new float[nif][2][2]; baseSub = new float[nif][2][24]; spectra = new float*[nif]; flagged = new unsigned char*[nif]; xpol = new float*[nif]; tcal = new float[nif][2]; cNProd = new int[nif]; cNXPol = new int[nif]; for (int iIF = 0; iIF < nif; iIF++) { spectra[iIF] = 0x0; flagged[iIF] = 0x0; xpol[iIF] = 0x0; cNProd[iIF] = 0; cNXPol[iIF] = 0; } // The number we can accomodate, may exceed the number we have. cNIF = nif; } } //--------------------------------------------------------- MBrecord::allocate // Ensure there is enough storage for the specified number of spectral // products (channels x polarizations) for IF with array index iIF (i.e. // the actual IF number is IFno[iIF]). Expands arrays if necessary but // never contracts. void MBrecord::allocate( int iIF, int nprod, int nxpol) { // Don't mess with storage we didn't allocate. if (cNProd[iIF] || spectra[iIF] == 0x0) { if (cNProd[iIF] < nprod) { if (cNProd[iIF]) { // Free storage previously allocated. delete [] spectra[iIF]; delete [] flagged[iIF]; } // Reallocate data storage. cNProd[iIF] = nprod; spectra[iIF] = new float[nprod]; flagged[iIF] = new unsigned char[nprod]; } } if (cNXPol[iIF] || xpol[iIF] == 0x0) { if (cNXPol[iIF] < nxpol) { if (cNXPol[iIF]) { // Free storage previously allocated. delete [] xpol[iIF]; } // Reallocate xpol storage. cNXPol[iIF] = nxpol; xpol[iIF] = new float[nxpol]; } } } //------------------------------------------------------------- MBrecord::free // Free all allocated storage. void MBrecord::free() { if (cNIF) { for (int iIF = 0; iIF < cNIF; iIF++) { // Don't free storage we didn't allocate. if (cNProd[iIF]) { delete [] spectra[iIF]; delete [] flagged[iIF]; } if (cNXPol[iIF]) { delete [] xpol[iIF]; } } delete [] IFno; delete [] nChan; delete [] nPol; delete [] fqRefPix; delete [] fqRefVal; delete [] fqDelt; delete [] tsys; delete [] calfctr; delete [] xcalfctr; delete [] baseLin; delete [] baseSub; delete [] spectra; delete [] flagged; delete [] xpol; delete [] tcal; delete [] cNProd; delete [] cNXPol; cNIF = 0; } } //-------------------------------------------------------- MBrecord::operator= // Do a deep copy of one MBrecord to another. MBrecord &MBrecord::operator=(const MBrecord &other) { if (this == &other) { return *this; } setNIFs(other.nIF); scanNo = other.scanNo; cycleNo = other.cycleNo; strcpy(datobs, other.datobs); utc = other.utc; exposure = other.exposure; strcpy(srcName, other.srcName); srcRA = other.srcRA; srcDec = other.srcDec; restFreq = other.restFreq; strcpy(obsType, other.obsType); // Beam-dependent parameters. beamNo = other.beamNo; ra = other.ra; dec = other.dec; pCode = other.pCode; rateAge = other.rateAge; raRate = other.raRate; decRate = other.decRate; // IF-dependent parameters. nIF = other.nIF; for (int iIF = 0; iIF < nIF; iIF++) { IFno[iIF] = other.IFno[iIF]; nChan[iIF] = other.nChan[iIF]; nPol[iIF] = other.nPol[iIF]; fqRefPix[iIF] = other.fqRefPix[iIF]; fqRefVal[iIF] = other.fqRefVal[iIF]; fqDelt[iIF] = other.fqDelt[iIF]; for (int j = 0; j < 2; j++) { tsys[iIF][j] = other.tsys[iIF][j]; } for (int j = 0; j < 2; j++) { calfctr[iIF][j] = other.calfctr[iIF][j]; xcalfctr[iIF][j] = other.xcalfctr[iIF][j]; } haveBase = other.haveBase; for (int ipol = 0; ipol < nPol[iIF]; ipol++) { baseLin[iIF][ipol][0] = other.baseLin[iIF][ipol][0]; baseLin[iIF][ipol][1] = other.baseLin[iIF][ipol][1]; for (int j = 0; j < 24; j++) { baseSub[iIF][ipol][j] = other.baseSub[iIF][ipol][j]; } } for (int j = 0; j < 2; j++) { tcal[iIF][j] = other.tcal[iIF][j]; } } haveSpectra = other.haveSpectra; if (haveSpectra) { for (int iIF = 0; iIF < nIF; iIF++) { int nprod = nChan[iIF] * nPol[iIF]; int nxpol = other.xpol[iIF] ? nChan[iIF] * 2 : 0; allocate(iIF, nprod, nxpol); } // Copy data. for (int iIF = 0; iIF < nIF; iIF++) { float *specp = spectra[iIF]; float *ospecp = other.spectra[iIF]; unsigned char *flagp = flagged[iIF]; unsigned char *oflagp = other.flagged[iIF]; for (int j = 0; j < nChan[iIF]*nPol[iIF]; j++) { *(specp++) = *(ospecp++); *(flagp++) = *(oflagp++); } if (xpol[iIF]) { float *xpolp = xpol[iIF]; float *oxpolp = other.xpol[iIF]; for (int j = 0; j < 2*nChan[iIF]; j++) { *(xpolp++) = *(oxpolp++); } } } } extraSysCal = other.extraSysCal; azimuth = other.azimuth; elevation = other.elevation; parAngle = other.parAngle; paRate = other.paRate; focusAxi = other.focusAxi; focusTan = other.focusTan; focusRot = other.focusRot; temp = other.temp; pressure = other.pressure; humidity = other.humidity; windSpeed = other.windSpeed; windAz = other.windAz; strcpy(tcalTime, other.tcalTime); refBeam = other.refBeam; polNo = other.polNo ; srcVelocity = other.srcVelocity ; return *this; } //---------------------------------------------------------- MBrecord::extract // Extract a selected IF from one MBrecord into another. int MBrecord::extract(const MBrecord &other, int iIF) { if (this == &other) { return 1; } setNIFs(1); scanNo = other.scanNo; cycleNo = other.cycleNo; strcpy(datobs, other.datobs); utc = other.utc; exposure = other.exposure; strcpy(srcName, other.srcName); srcRA = other.srcRA; srcDec = other.srcDec; restFreq = other.restFreq; strcpy(obsType, other.obsType); // Beam-dependent parameters. beamNo = other.beamNo; ra = other.ra; dec = other.dec; pCode = other.pCode; rateAge = other.rateAge; raRate = other.raRate; decRate = other.decRate; paRate = other.paRate; // IF-dependent parameters. nIF = 1; IFno[0] = other.IFno[iIF]; nChan[0] = other.nChan[iIF]; nPol[0] = other.nPol[iIF]; fqRefPix[0] = other.fqRefPix[iIF]; fqRefVal[0] = other.fqRefVal[iIF]; fqDelt[0] = other.fqDelt[iIF]; for (int j = 0; j < 2; j++) { tsys[0][j] = other.tsys[iIF][j]; } for (int j = 0; j < 2; j++) { calfctr[0][j] = other.calfctr[iIF][j]; xcalfctr[0][j] = other.xcalfctr[iIF][j]; } haveBase = other.haveBase; for (int ipol = 0; ipol < nPol[0]; ipol++) { baseLin[0][ipol][0] = other.baseLin[iIF][ipol][0]; baseLin[0][ipol][1] = other.baseLin[iIF][ipol][1]; for (int j = 0; j < 24; j++) { baseSub[0][ipol][j] = other.baseSub[iIF][ipol][j]; } } for (int j = 0; j < 2; j++) { tcal[0][j] = other.tcal[iIF][j]; } haveSpectra = other.haveSpectra; if (haveSpectra) { int nprod = nChan[0] * nPol[0]; int nxpol = other.xpol[iIF] ? nChan[0] * 2 : 0; allocate(0, nprod, nxpol); // Copy data. float *specp = spectra[0]; float *ospecp = other.spectra[iIF]; unsigned char *flagp = flagged[0]; unsigned char *oflagp = other.flagged[iIF]; for (int j = 0; j < nChan[0]*nPol[0]; j++) { *(specp++) = *(ospecp++); *(flagp++) = *(oflagp++); } if (xpol[0]) { float *xpolp = xpol[0]; float *oxpolp = other.xpol[iIF]; for (int j = 0; j < 2*nChan[0]; j++) { *(xpolp++) = *(oxpolp++); } } } extraSysCal = other.extraSysCal; azimuth = other.azimuth; elevation = other.elevation; parAngle = other.parAngle; focusAxi = other.focusAxi; focusTan = other.focusTan; focusRot = other.focusRot; temp = other.temp; pressure = other.pressure; humidity = other.humidity; windSpeed = other.windSpeed; windAz = other.windAz; strcpy(tcalTime, other.tcalTime); refBeam = other.refBeam; polNo = other.polNo ; srcVelocity = other.srcVelocity ; return 0; }