00001
00002
00003
00004
00005
00006
00007 #ifndef HLRADCIRC_H
00008 #define HLRADCIRC_H
00009
00010
00011 extern "C"
00012 {
00013 #include "slalib.h"
00014 #include "ast.h"
00015 }
00016 #include <float.h>
00017
00018 #include <algorithm>
00019 #include "Constants.h"
00020 #include "DataMethod.hxx"
00021 #include "FitsFile.h"
00022 #include "StringOps.h"
00023 #include "Logger.h"
00024 #include "DataOps.h"
00025 #include "Converter.h"
00026
00027
00032 template<typename DataType>
00033 class HlRadCirc : public DataMethod<DataType>
00034 {
00035 public:
00037 HlRadCirc(const FitsFile& aCatFile, const FitsFile& aFile)
00038 : mCatFile(aCatFile),mFile(aFile)
00039 {
00040 DataMethod<DataType>::methodName = "HlRadCirc";
00041 }
00042
00044 virtual ~HlRadCirc() { }
00045
00046
00048 void setSource(IntMap& tbls, IntMap& cols, StringMap units)
00049 {
00050 afColNo[0]=0;
00051 afeColNo[0]=0;
00052
00053 for (int i=0;i<NOAPERS-1;++i)
00054 {
00055 afColNo[i+1] = cols[2*i];
00056 afeColNo[i+1] = cols[2*i+1];
00057 }
00058 pfColNo = cols[26];
00059 extColNo = cols[27];
00060
00061
00062
00063
00064
00065 }
00066
00068 void setTarget(IntMap& cols, StringMap units)
00069 {
00070 hlCircColNo = cols[0];
00071 hlCErrColNo = cols[1];
00072
00073 }
00074
00076 void doit(TableData<DataType>& data, int row1, int row2)
00077 {
00078 Logger log;
00079
00080 double apertures[NOAPERS]={0.,0.5,sqrt(0.5),1.,sqrt(2.),2.,2.*sqrt(2.),4.,5.,6.,7.,8.,10.,12.};
00081 double rCore[mCatFile.getNumHdus()];
00082 double crval1;
00083 double crval2;
00084 int npixx,npixy;
00085
00086 double centre[2];
00087 double sizeFact[2];
00088 double pixelScale[mCatFile.getNumHdus()];
00089
00090
00091
00092 astBegin;
00093 AstFitsChan *fitschan = astFitsChan(NULL, NULL, "%.*s", 0, "NULL");
00094
00095 Converter conv;
00096 sizeFact[0] = conv.getFactor("RADIANS", "Arcseconds");
00097 sizeFact[1] = conv.getFactor("RADIANS", "Arcseconds");
00098
00099 for (int hduNo = 2; hduNo <= mCatFile.getNumHdus(); ++hduNo)
00100 {
00101
00102 int extNo = hduNo - 2;
00103
00104
00105 AstFrameSet *wcsinfo = 0;
00106
00107
00108 mCatFile.movabsHdu(hduNo);
00109 mFile.movabsHdu(hduNo);
00110 mCatFile.readKey("RCORE", rCore[extNo]);
00111
00112
00113
00114 int ncards = mFile.getNumCards();
00115 for (int n = 0; n < ncards; ++n) {
00116 char card[80];
00117 mFile.readCard(n, card);
00118 astPutFits(fitschan, card, 0);
00119 }
00120
00121
00122
00123 astClear( fitschan, "Card" );
00124
00125
00126
00127 mFile.readKey(FitsFile::CRVAL1, crval1);
00128 mFile.readKey(FitsFile::CRVAL2, crval2);
00129 if (crval1 == 0 && crval2 == 0) {
00130 log.addError("Could not read WCS info for " + mCatFile.getFileName());
00131 } else {
00132 wcsinfo = (AstFrameSet*)astRead(fitschan);
00133 }
00134
00135 mCatFile.readKey("NXOUT", npixx);
00136 mCatFile.readKey("NYOUT", npixy);
00137 centre[0] = (double)npixx / 2;
00138 centre[1] = (double)npixy / 2;
00139 Numeric xPixSize,yPixSize;
00140
00141 DataOps::calcPixSize(wcsinfo,centre,sizeFact,xPixSize,yPixSize);
00142 pixelScale[extNo]=sqrt(xPixSize*yPixSize);
00143
00144 }
00145
00146 for (int rowNo = row1; rowNo < row2; ++rowNo)
00147 {
00148 double extNum;
00149 data.value(extColNo, rowNo, extNum);
00150 int extNo=(int)(extNum-2);
00151
00152
00153 double aperFlux[NOAPERS];
00154 double aperFluxErr[NOAPERS];
00155
00156
00157 double petroFlux;
00158 double totalFlux;
00159
00160 data.value(pfColNo, rowNo, petroFlux);
00161
00162 double hlCirc=DefaultValues::realdef;
00163 double hlCErr=DefaultValues::realdef;
00164
00165
00166
00167
00168
00169
00170
00171
00172 if (petroFlux>0.)
00173 {
00174 int bestAper=0;
00175 bool isAperSet=false;
00176 totalFlux=petroFlux/0.9;
00177
00178 for (int i=1;i<NOAPERS;++i)
00179 {
00180 data.value(afColNo[i], rowNo, aperFlux[i]);
00181 data.value(afeColNo[i], rowNo, aperFluxErr[i]);
00182
00183 if (aperFlux[i]>0.5*totalFlux && !isAperSet)
00184 {
00185 bestAper=i;
00186 isAperSet=true;
00187
00188 }
00189
00190 }
00191 aperFlux[0]=0.;
00192 aperFluxErr[0]=aperFluxErr[1];
00193 if (!isAperSet) bestAper=NOAPERS-1;
00194
00195
00196 int minAper = max(bestAper-int(floor(NDATAPNTS/2.)),0);
00197 int maxAper = min(minAper+NDATAPNTS,NOAPERS-1);
00198 if ((maxAper-minAper)<NDATAPNTS) minAper=maxAper-NDATAPNTS;
00199
00200
00201 double matA[NDATAPNTS][NPOLY];
00202 double vecB[NDATAPNTS];
00203 double matW[NPOLY];
00204 double matV[NPOLY][NPOLY];
00205 double work[NPOLY];
00206 double xfit[NPOLY];
00207 double matC[NPOLY][NPOLY];
00208 int jstat;
00209 double minRadius=rCore[extNo]*apertures[minAper];
00210 double maxRadius=rCore[extNo]*apertures[minAper+NDATAPNTS-1];
00211
00212
00213 for (int j=0;j<NDATAPNTS;++j)
00214 {
00215
00216 double radius;
00217 radius=rCore[extNo]*apertures[minAper+j];
00218 if (j==0) minRadius=radius;
00219 if (j==NDATAPNTS-1) maxRadius=radius;
00220 double frac=0.;
00221 double fracErr=1.;
00222
00223 if (aperFlux[minAper+j]>=0.) {
00224 frac=aperFlux[minAper+j]/totalFlux;
00225 if (aperFluxErr[minAper+j]>0.) {
00226 fracErr=aperFluxErr[minAper+j]/totalFlux;
00227 }
00228 }
00229 double weight=1./fracErr;
00230 matA[j][0]=weight;
00231 vecB[j]=frac*weight;
00232 for (int k=0;k<NPOLY-1;++k) {
00233 matA[j][k+1]=pow(radius,k+1)*weight;
00234 }
00235 }
00236
00237
00238
00239 cslaSvd(NDATAPNTS,NPOLY,NDATAPNTS,NPOLY, (double *) matA,matW, (double *) matV, work, &jstat);
00240
00241
00242 double maxSvd=*max_element(matW,matW+NPOLY);
00243 for (int j=0;j<NPOLY;++j)
00244 {
00245 if (matW[j]<=minSvdRatio*maxSvd) matW[j]=0;
00246
00247 }
00248
00249 cslaSvdsol(NDATAPNTS,NPOLY,NDATAPNTS,NPOLY,vecB,(double *) matA,matW,(double *) matV, work,xfit);
00250 cslaSvdcov(NPOLY,NPOLY,NPOLY,matW,(double *) matV, work, (double *) matC);
00251
00252
00253
00254
00255 double roots[2];
00256
00257 xfit[0]-=0.5;
00258
00259 quadroots(xfit,roots);
00260
00261
00262
00263
00264 bool hasMatch=false;
00265
00266 for (int i=0;i<NPOLY-1;++i) {
00267 if (roots[i]>=minRadius && roots[i]<=maxRadius && !hasMatch) {
00268 hlCirc=roots[i];
00269 hasMatch=true;
00270 }
00271 }
00272 double sumCov=0.;
00273 double dfda[NPOLY];
00274 double dfdr=0;
00275 dfda[0]=1.;
00276
00277 for (int i=0;i<NPOLY-1;++i)
00278 {
00279 dfda[i+1]=pow(hlCirc,i+1);
00280 dfdr+=pow(hlCirc,i)*(i+1)*xfit[i+1];
00281 }
00282 for (int i=0;i<NPOLY;++i) {
00283 for (int j=0;j<NPOLY;++j) {
00284 sumCov+=dfda[i]*dfda[j]*matC[i][j];
00285 }
00286 }
00287 double ferr=sqrt(sumCov);
00288
00289 if (hlCirc<0.) {
00290 hlCErr=DefaultValues::realdef;
00291 } else if (abs(dfdr)>0.) {
00292 hlCirc=pixelScale[extNo]*hlCirc;
00293 hlCErr=pixelScale[extNo]*sqrt((ferr/dfdr)*(ferr/dfdr)+0.5*0.5);
00294 } else {
00295 hlCirc=pixelScale[extNo]*hlCirc;
00296 hlCErr=pixelScale[extNo]*0.5;
00297 }
00298
00299
00300 }
00301
00302 data.assign(hlCircColNo, rowNo, hlCirc);
00303 data.assign(hlCErrColNo, rowNo, hlCErr);
00304
00305 }
00306
00307 }
00308
00309
00310 void doit2(TableData<DataType>& rawData, TableData<DataType>& data, int row1, int row2) { }
00311
00312
00313 void quadroots(double a[3], double roots[2]) {
00314
00315 double sq=a[1]*a[1]-4.*a[0]*a[2];
00316 if (sq>=0) {
00317 roots[0]=(-a[1]+sqrt(sq))/(2.*a[2]);
00318 roots[1]=(-a[1]-sqrt(sq))/(2.*a[2]);
00319 } else {
00320 roots[0]=DefaultValues::realdef;
00321 roots[1]=DefaultValues::realdef;
00322 }
00323 }
00324
00325 double newrph(double poly[], double hlrE, double mnr, double mxr) {
00326 const double finalErr=1.0e-4;
00327 const int maxIter=5;
00328 double error=1.;
00329 int it=0;
00330 double hlr=hlrE;
00331 double dr=0;
00332 while (error>finalErr and it<maxIter) {
00333 double func=0;
00334 double dfdr=0;
00335 for (int i=0;i<NPOLY;++i) {
00336 func=poly[i]*pow(hlr,i);
00337 if (i>0) {
00338 dfdr+=i*poly[i]*pow(hlr,(i-1));
00339 }
00340 }
00341 dr=func/dfdr;
00342 error=sqrt(func);
00343 hlr-=dr;
00344
00345 it++;
00346 }
00347
00348 if (hlr<mnr) hlr=mnr;
00349 if (hlr>mxr) hlr=mxr;
00350 return hlr;
00351 }
00352 private:
00353 const static unsigned short int NOAPERS=14;
00354 const static unsigned short int NDATAPNTS=5;
00355 const static unsigned short int NPOLY=3;
00356 const static double minSvdRatio=1.0e-10;
00357 FitsFile mCatFile;
00358 FitsFile mFile;
00359
00360 int hlCircColNo;
00361 int hlCErrColNo;
00362 int afColNo[NOAPERS];
00363 int afeColNo[NOAPERS];
00364 int pfColNo;
00365 int extColNo;
00366
00367
00368 };
00369
00370 #endif
00371
00372
00373
00374