// -*- C++ -*- //# ConvFuncDiskCache.cc: Implementation of the ConvFuncDiskCache class //# Copyright (C) 1997,1998,1999,2000,2001,2002,2003 //# 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$ #include #include #include #include #include #include #include #include using namespace casacore; namespace casa{ // //------------------------------------------------------------------------- // Just load the axillary info. if found. The actual functions are loaded // as and when required using loadConvFunction() method. // void ConvFuncDiskCache::initCache() { ostringstream name; String line; Directory dirObj(Dir); if (Dir.length() == 0) throw(SynthesisFTMachineError("Got null string for disk cache dir. " "in ConvFuncDiskCache::initCache()")); // // If the directory does not exist, create it // if (!dirObj.exists()) dirObj.create(); else if ((!dirObj.isWritable()) || (!dirObj.isReadable())) { throw(SynthesisFTMachineError(String("Directory \"")+Dir+String("\"")+ String(" for convolution function cache" " exists but is unreadable/unwriteable"))); } try { name << Dir << "/" << aux; File file(name); Int Npa=0,Nw=0; ifstream aux; Bool readFromFile=false; if (file.exists() && file.isRegular()) { readFromFile=true; aux.open(name.str().c_str()); if (readFromFile && aux.good()) aux >> Npa >> Nw; else throw(SynthesisFTMachineError(string("Error while reading convolution function cache file ")+name.str( ))); } if (Npa > 0) { paList.resize(Npa,true); IPosition s(3,Nw,1,Npa); XSup.resize(s,true); YSup.resize(s,true); Sampling.resize(Npa,true); for(Int i=0;i> pa; for(Int iw=0;iw> XS >> YS; YS = XS; paList[i] = pa*M_PI/180.0; XSup(iw,0,i)=XS; YSup(iw,0,i)=YS; } aux >> S; Sampling[i]=S; } } } catch(AipsError& x) { throw(SynthesisFTMachineError(String("Error while initializing CF disk cache: ") +x.getMesg())); } } ConvFuncDiskCache& ConvFuncDiskCache::operator=(const ConvFuncDiskCache& other) { paList = other.paList; Sampling = other.Sampling; XSup = other.XSup; YSup = other.YSup; Dir = other.Dir; cfPrefix = other.cfPrefix; aux = other.aux; return *this; }; // //------------------------------------------------------------------------- // Write the conv. functions from the mem. cache to the disk cache. // void ConvFuncDiskCache::cacheConvFunction(Int which, Float pa, Array& cf, CoordinateSystem& coords, CoordinateSystem& ftCoords, Int &convSize, Cube &convSupport, Float convSampling, String nameQualifier, Bool savePA) { Int N=paList.nelements(); if (Dir.length() == 0) return; try { IPosition newConvShape = cf.shape(); Int wConvSize = newConvShape(2), directionIndex; for(Int iw=0;iw=0, AipsError); dc=coords.directionCoordinate(directionIndex); Vector axes(2); axes(0)=axes(1)=true;//axes(2)=true; Vector shape(2); shape(0)=newConvShape(0);shape(1)=newConvShape(1); shape=convSize; Vectorref(4); ref(0)=ref(1)=ref(2)=ref(3)=0; dc.setReferencePixel(ref); Coordinate* ftdc=dc.makeFourierCoordinate(axes,shape); Vector refVal; refVal=ftdc->referenceValue(); refVal(0)=refVal(1)=0; ftdc->setReferenceValue(refVal); ref(0)=newConvShape(0)/2-1; ref(1)=newConvShape(1)/2-1; ftdc->setReferencePixel(ref); // cout << ref << endl << refVal << endl << shape << endl; // cout << dc.increment() << " " << ftdc->increment() << endl; ftCoords.replaceCoordinate(*ftdc, directionIndex); { ostringstream name; name << Dir << "/" << cfPrefix << nameQualifier << iw << "_" << which; IPosition screenShape(4,newConvShape(0),newConvShape(1),newConvShape(3),1); PagedImage thisScreen(screenShape, ftCoords, name); Array buf; buf=((cf(Slicer(sliceStart,sliceLength)).nonDegenerate())); thisScreen.put(buf); } delete ftdc; ftdc=0; } if (savePA) { IPosition s(3,wConvSize,1,N+1); paList.resize(N+1,true); // XSup.resize(N+1,true); // YSup.resize(N+1,true); XSup.resize(s,true); YSup.resize(s,true); Sampling.resize(N+1,true); paList[N] = pa; for(Int iw=0;iw& cfWt, CoordinateSystem& coords, Int &convSize, Cube &convSupport, Float convSampling) { Int N=paList.nelements(); if (Dir.length() == 0) return; try { IPosition newConvShape = cfWt.shape(); Int wConvSize = newConvShape(2), directionIndex; for(Int iw=0;iw=0, AipsError); dc=coords.directionCoordinate(directionIndex); Vector axes(2); axes(0)=axes(1)=true;//axes(2)=true; Vector shape(2); shape(0)=newConvShape(0);shape(1)=newConvShape(1); shape=convSize; Vectorref(4); ref(0)=ref(1)=ref(2)=ref(3)=0; dc.setReferencePixel(ref); Coordinate* ftdc=dc.makeFourierCoordinate(axes,shape); Vector refVal; refVal=ftdc->referenceValue(); refVal(0)=refVal(1)=0; ftdc->setReferenceValue(refVal); ref(0)=newConvShape(0)/2-1; ref(1)=newConvShape(1)/2-1; ftdc->setReferencePixel(ref); // cout << ref << endl << refVal << endl << shape << endl; // cout << dc.increment() << " " << ftdc->increment() << endl; ftCoords.replaceCoordinate(*ftdc, directionIndex); delete ftdc; ftdc=0; { ostringstream name; name << Dir << "/" << cfPrefix << "WT" << iw << "_" << which; IPosition screenShape(4,newConvShape(0),newConvShape(1),newConvShape(3),1); PagedImage thisScreen(screenShape, ftCoords, name); Array buf; buf=((cfWt(Slicer(sliceStart,sliceLength)).nonDegenerate())); thisScreen.put(buf); } } IPosition s(3,wConvSize,1,N+1); paList.resize(N+1,true); // XSup.resize(N+1,true); // YSup.resize(N+1,true); XSup.resize(s,true); YSup.resize(s,true); Sampling.resize(N+1,true); paList[N] = pa; for(Int iw=0;iw antPA = vb.feed_pa(getCurrentTimeStamp(vb)); pa = sum(antPA)/(antPA.nelements()-1); */ pa = getPA(vb); // cout << dPA*57.295 << " " << pa*57.295 << endl; // pa = 0; // cout << "######CFDC::search: " << pa << " " << getPA(vb) << endl; // if (NPA == 0) return -1; for(i=0;i antPA = vb.feed_pa(getCurrentTimeStamp(vb)); pa = sum(antPA)/(antPA.nelements()-1); */ pa = getPA(vb); // pa = 0; // cout << "######CFDC::search: " << pa << " " << getPA(vb) << endl; // if (NPA == 0) return -1; Float paDiff=2*dPA; Int saveNdx=-1; saveNdx = -1; for(i=0;i -1) { iPA = paList[saveNdx]; if (fabs(iPA - pa) <= dPA) { i = saveNdx; paFound=true; } } /* for(i=0;i& avgPB) { if (Dir.length() == 0) return; finalize(); ostringstream Name; Name << Dir <<"/avgPB"; try { IPosition newShape(avgPB.shape()); PagedImage tmp(newShape, avgPB.coordinates(), Name); LatticeExpr le(avgPB); tmp.copyData(le); } catch(AipsError &x) { throw(SynthesisFTMachineError(string("Error while writing ") + Name.str( ) + (string) x.getMesg())); } } // //------------------------------------------------------------------------- //Load the average PB from the disk cache. // void ConvFuncDiskCache::loadAvgPB(ImageInterface& avgPB) { if (Dir.length() == 0) return; ostringstream name; name << Dir << "/avgPB"; // cout << name.str() << endl; try { PagedImage tmp(name.str().c_str()); avgPB.resize(tmp.shape()); avgPB.put(tmp.get()); } catch(AipsError& x) // Just rethrowing the exception for now. // Ultimately, this should be used to make // the state of this object consistant. { throw(SynthesisFTMachineError(string("Error while loading \"")+ name.str( ) + string("\": ") + (string) x.getMesg())); } } // //------------------------------------------------------------------------- //Load a conv. func. from the disk. This is non-optimal due to the //data structure used for the conv. func. in-memory cache (it's an //array of pointers where it should really be a List of pointers). //The conf. func. index, which is also used as a key to located them //in the mem. cache, are not assured to be contiguous. As a result, //in the current implementation there can be gaps in the //convFuncCache array. These gaps are initialized to NULL pointers. //It's not much of a memory waste, but still non-optimal! Leaving //it like this for now. // Bool ConvFuncDiskCache::loadConvFunction(Int where, Int Nw, PtrBlock < Array *> &convFuncCache, Cube &convSupport, Vector& convSampling, Double& cfRefFreq, CoordinateSystem& coordSys, String prefix) { if (Dir.length() == 0) return false; if (where < (Int)convFuncCache.nelements() && (convFuncCache[where] != NULL)) return false; Int wConvSize, polInUse=2; Int N=convFuncCache.nelements(); // // Re-size the conv. func. memory cache if required, and set the // new members of the resized cache to NULL. This is used in the // loop below to make a decision about allocating new memory or // not. // convFuncCache.resize(max(where+1,N), true); for(Int i=N;i<=where;i++) convFuncCache[i]=NULL; // // Each w-plan is in a separate disk file. Each file contains all // polarization planes though. Memory cache holds all w-planes and // poln-planes in a single complex array. The loop below read // each w-plane image from the disk, and fills in the 3D // mem. cache for each computed PA. // wConvSize = Nw; for(Int iw=0;iw