9 #ifndef __HCIobservation_hpp__
10 #define __HCIobservation_hpp__
19 #include "../mxlib.hpp"
21 #include "../mxException.hpp"
23 #include "../math/templateBLAS.hpp"
24 #include "../sys/timeUtils.hpp"
25 #include "../ioutils/fileUtils.hpp"
26 #include "../ioutils/readColumns.hpp"
27 #include "../ioutils/fits/fitsFile.hpp"
28 #include "../ipc/ompLoopWatcher.hpp"
81 template<
typename _realT>
89 typedef Eigen::Array<realT, Eigen::Dynamic, Eigen::Dynamic>
eigenImageT;
103 const std::string &prefix,
104 const std::string &ext
121 const std::string &prefix,
122 const std::string &ext,
123 const std::string &RDIdir,
124 const std::string &RDIprefix,
125 const std::string &RDIext=
""
136 const std::string & RDIfileListFile
145 const std::string &prefix,
146 const std::string &ext
162 const std::string &prefix,
163 const std::string &ext
391 int threshold( std::vector<std::string> & fileList,
392 const std::string & qualityFile,
393 realT qualityThreshold
429 std::vector<std::string> & coaddKeywords,
430 std::vector<double> & imageMJD,
431 std::vector<fits::fitsHeader> & heads,
632 const std::string & prefix,
633 const std::string & ext,
652 double t_load_begin {0};
653 double t_load_end {0};
655 double t_coadd_begin {0};
656 double t_coadd_end {0};
658 double t_preproc_begin {0};
659 double t_preproc_end {0};
661 double t_azusm_begin {0};
662 double t_azusm_end {0};
664 double t_gaussusm_begin {0};
665 double t_gaussusm_end {0};
668 double t_combo_begin {0};
669 double t_combo_end {0};
675 template<
typename _realT>
680 template<
typename _realT>
682 const std::string & prefix,
683 const std::string & ext
686 load_fileList(dir, prefix, ext);
689 template<
typename _realT>
692 load_fileList(fileListFile);
696 template<
typename _realT>
698 const std::string & prefix,
699 const std::string & ext,
700 const std::string & RDIdir,
701 const std::string & RDIprefix,
702 const std::string & RDIext
705 std::cerr <<
"HCI 6\n";
707 load_fileList(dir, prefix, ext);
710 if(RDIext ==
"") re = ext;
713 load_RDIfileList(RDIdir, RDIprefix, re);
718 template<
typename _realT>
720 const std::string & RDIfileListFile
723 load_fileList( fileListFile);
724 load_RDIfileList( RDIfileListFile);
727 template<
typename _realT>
729 const std::string & prefix,
730 const std::string & ext
734 m_filesDeleted =
false;
737 template<
typename _realT>
741 m_filesDeleted =
false;
744 template<
typename _realT>
746 const std::string & prefix,
747 const std::string & ext
751 m_RDIfilesDeleted =
false;
754 template<
typename _realT>
758 m_RDIfilesDeleted =
false;
764 template<
typename _realT>
767 if(m_fileList.size() == 0)
769 mxError(
"HCIobservation", MXE_FILENOTFOUND,
"The target fileList has 0 length, there are no files to be read.");
776 if(m_deleteFront > 0)
778 m_fileList.erase(m_fileList.begin(), m_fileList.begin()+m_deleteFront);
783 m_fileList.erase(m_fileList.end()-m_deleteBack, m_fileList.end());
785 m_filesDeleted =
true;
788 if( m_fileList.size() == 0)
790 mxError(
"HCIobservation", MXE_FILENOTFOUND,
"The target fileList has 0 length, there are no files to be read after deletions.");
794 if(m_qualityFile !=
"")
796 std::cerr <<
"Thresholding target images...";
797 size_t origsize = m_fileList.size();
799 if( threshold(m_fileList, m_qualityFile, m_qualityThreshold) < 0)
return -1;
801 if( m_fileList.size() == 0)
803 mxError(
"HCIobservation", MXE_FILENOTFOUND,
"The fileList has 0 length, there are no files to be read after thresholding.");
807 std::cerr <<
"Done. Selected " << m_fileList.size() <<
" out of " << origsize <<
"\n";
812 std::cout <<
"#Files which passed thresholding:\n";
813 for(
size_t i=0; i<m_fileList.size(); ++i)
815 std::cout << m_fileList[i] <<
"\n";
823 if(m_weightFile !=
"")
825 if(readWeights() < 0)
return -1;
832 if(m_MJDKeyword !=
"") head.
append(m_MJDKeyword);
834 for(
size_t i=0;i<m_keywords.size();++i)
836 if(head.
count(m_keywords[i]) == 0) head.
append(m_keywords[i]);
840 m_heads.resize(m_fileList.size(), head);
844 Eigen::Array<realT, Eigen::Dynamic, Eigen::Dynamic> im;
853 m_imSize = im.rows();
854 if(m_imSize > im.cols()) m_imSize = im.cols();
859 if(m_imSize > im.rows()) m_imSize = im.rows();
860 if(m_imSize > im.cols()) m_imSize = im.cols();
865 f.
setReadSize( floor(0.5*(im.rows()-1) - 0.5*(m_imSize-1) +0.1), floor(0.5*(im.cols()-1.0) - 0.5*(m_imSize-1.0)+0.1), m_imSize, m_imSize);
866 im.resize(m_imSize, m_imSize);
872 m_tgtIms.resize(im.rows(), im.cols(), m_fileList.size());
876 f.
read(m_tgtIms.data(), m_heads, m_fileList);
881 if(m_MJDKeyword !=
"")
883 m_imageMJD.resize(m_heads.size());
887 for(
size_t i=0;i<m_imageMJD.size();++i)
894 for(
size_t i=0;i<m_imageMJD.size();++i)
896 m_imageMJD[i] = m_heads[i][m_MJDKeyword].template value<realT>()*m_MJDUnits;
903 m_Nims = m_tgtIms.planes();
904 m_Nrows = m_tgtIms.rows();
905 m_Ncols = m_tgtIms.cols();
906 m_Npix = m_tgtIms.rows()*m_tgtIms.cols();
908 std::cerr <<
"loading complete\n";
910 std::cerr <<
"zero-ing NaNs\n";
912 std::cerr <<
"done\n";
915 if( postReadFiles() < 0)
return -1;
922 if(!m_skipPreProcess)
925 if(m_preProcess_beforeCoadd) preProcess(m_tgtIms);
929 std::cerr <<
"Coadding target images...\n";
930 coaddImages(m_coaddCombineMethod, m_coaddMaxImno, m_coaddMaxTime, m_coaddKeywords, m_imageMJD, m_heads, m_tgtIms);
932 m_Nims = m_tgtIms.planes();
933 m_Nrows = m_tgtIms.rows();
934 m_Ncols = m_tgtIms.cols();
935 m_Npix = m_tgtIms.rows()*m_tgtIms.cols();
939 std::cerr <<
"Post coadd error " << __FILE__ <<
" " << __LINE__ <<
"\n";
942 std::cerr <<
"Done.\n";
945 if( m_maskFile !=
"")
952 if(!m_preProcess_beforeCoadd) preProcess(m_tgtIms);
954 outputPreProcessed();
963 template<
typename _realT>
969 template<
typename _realT>
976 template<
typename _realT>
981 if(m_Nrows == 0 || m_Ncols == 0)
983 mxError(
"HCIobservation", MXE_PARAMNOTSET,
"The target image size must be set before reading RDI files.");
987 if(m_RDIfileList.size() == 0)
989 mxError(
"HCIobservation", MXE_FILENOTFOUND,
"The RDI fileList has 0 length, there are no files to be read.");
994 if(!m_RDIfilesDeleted)
996 if(m_RDIdeleteFront > 0)
998 m_RDIfileList.erase(m_RDIfileList.begin(), m_RDIfileList.begin()+m_RDIdeleteFront);
1001 if(m_RDIdeleteBack > 0)
1003 m_RDIfileList.erase(m_RDIfileList.end()-m_RDIdeleteBack, m_RDIfileList.end());
1005 m_RDIfilesDeleted =
true;
1008 if( m_RDIfileList.size() == 0)
1010 mxError(
"HCIobservation", MXE_FILENOTFOUND,
"The RDI fileList has 0 length, there are no files to be read after deletions.");
1014 if(m_RDIqualityFile !=
"")
1016 std::cerr <<
"Thresholding RDI images...";
1017 size_t origsize = m_RDIfileList.size();
1019 if( threshold(m_RDIfileList, m_RDIqualityFile, m_RDIqualityThreshold) < 0)
return -1;
1021 if( m_RDIfileList.size() == 0)
1023 mxError(
"HCIobservation", MXE_FILENOTFOUND,
"The fileList has 0 length, there are no files to be read after thresholding.");
1027 std::cerr <<
"Done. Selected " << m_RDIfileList.size() <<
" out of " << origsize <<
"\n";
1036 if(m_MJDKeyword !=
"") head.
append(m_MJDKeyword);
1038 for(
size_t i=0;i<m_RDIkeywords.size();++i)
1040 head.
append(m_RDIkeywords[i]);
1044 m_RDIheads.resize(m_RDIfileList.size(), head);
1048 Eigen::Array<realT, Eigen::Dynamic, Eigen::Dynamic> im;
1054 if(im.rows() < m_imSize || im.cols() < m_imSize)
1056 mxError(
"HCIobservation", MXE_SIZEERR,
"The reference images are too small, do not match the target images.");
1062 f.
setReadSize( floor(0.5*(im.rows()-1) - 0.5*(m_imSize-1) +0.1), floor(0.5*(im.cols()-1.0) - 0.5*(m_imSize-1.0)+0.1), m_imSize, m_imSize);
1064 m_refIms.resize(m_imSize, m_imSize, m_RDIfileList.size());
1068 f.
read(m_refIms.data(), m_RDIheads, m_RDIfileList);
1072 if(m_MJDKeyword !=
"")
1074 m_RDIimageMJD.resize(m_RDIheads.size());
1078 for(
size_t i=0;i<m_RDIimageMJD.size();++i)
1085 for(
size_t i=0;i<m_RDIimageMJD.size();++i)
1087 m_RDIimageMJD[i] = m_RDIheads[i][m_MJDKeyword].template value<realT>()*m_MJDUnits;
1094 std::cerr <<
"loading complete\n";
1096 std::cerr <<
"zero-ing NaNs\n";
1098 std::cerr <<
"Done.\n";
1101 if( postRDIReadFiles() < 0)
return -1;
1104 if(!m_skipPreProcess)
1107 if(m_preProcess_beforeCoadd) preProcess(m_refIms);
1111 std::cerr <<
"Coadding reference images...\n";
1112 coaddImages(m_coaddCombineMethod, m_coaddMaxImno, m_coaddMaxTime, m_coaddKeywords, m_RDIimageMJD, m_RDIheads, m_refIms);
1114 if( postRDICoadd() < 0)
1116 std::cerr <<
"Post coadd error " << __FILE__ <<
" " << __LINE__ <<
"\n";
1119 std::cerr <<
"Done.\n";
1123 if(!m_preProcess_beforeCoadd) preProcess(m_refIms);
1129 m_RDIfilesRead =
true;
1134 template<
typename _realT>
1140 template<
typename _realT>
1146 template<
typename _realT>
1148 const std::string & qualityFile,
1149 realT qualityThreshold
1152 if(qualityFile ==
"")
1154 mxError(
"HCIobservation::threshold", MXE_PARAMNOTSET,
"qualityFile not set");
1158 int origsize = fileList.size();
1160 std::vector<std::string> qfileNames;
1161 std::vector<realT> imQ;
1166 std::map<std::string, realT> quality;
1167 for(
size_t i=0;i<qfileNames.size();++i) quality[
ioutils::pathFilename(qfileNames[i].c_str())] = imQ[i];
1171 for(
size_t i=0; i<fileList.size(); ++i)
1179 q = qualityThreshold - 1;
1182 if (q < qualityThreshold)
1184 fileList.erase(fileList.begin()+i);
1192 template<
typename _realT>
1196 std::vector<std::string> & coaddKeywords,
1197 std::vector<double> & imageMJD,
1198 std::vector<fits::fitsHeader> & heads,
1202 std::cerr <<
"***************************************************************\n";
1203 std::cerr <<
" *** WARNING *** \n";
1204 std::cerr <<
" coadding is poorly tested. proceed with caution. \n";
1205 std::cerr <<
"***************************************************************\n";
1209 if(coaddMaxImno <=0 && coaddMaxTime <= 0)
return;
1214 int Nims = ims.planes();
1215 int Nrows = ims.rows();
1216 int Ncols = ims.cols();
1220 std::vector<eigenImageT> coadds;
1223 std::vector<double> avgMJD;
1224 std::vector<std::vector<double> > avgVals;
1242 std::vector<double> initVals;
1243 initVals.resize(coaddKeywords.size());
1248 initMJD = imageMJD[im0];
1250 for(
size_t i=0;i< coaddKeywords.size(); ++i)
1252 initVals[i] = heads[im0][coaddKeywords[i]].value<
double>();
1256 bool increment =
true;
1257 while(increment ==
true)
1268 if(imF-im0 > coaddMaxImno && coaddMaxImno > 0)
1276 if( (imageMJD[imF] - imageMJD[im0])*86400.0 > coaddMaxTime && coaddMaxTime > 0)
1288 for(
int imno = im0+1; imno < imF; ++imno)
1290 initMJD += imageMJD[imno];
1292 for(
size_t i=0;i<coaddKeywords.size(); ++i)
1294 initVals[i] += heads[imno][coaddKeywords[i]].value<
double>();
1301 initMJD /= (imF - im0);
1302 for(
size_t i=0;i<coaddKeywords.size(); ++i)
1304 initVals[i] /= (imF-im0);
1308 imsToCoadd.resize(Nrows, Ncols, imF-im0);
1309 for(
int i =0; i < (imF-im0); ++i)
1318 imsToCoadd.
median(coadd);
1322 imsToCoadd.
mean(coadd);
1324 coadds.push_back(coadd);
1327 avgMJD.push_back(initMJD);
1328 avgVals.push_back(initVals);
1335 ims.resize(Nrows, Ncols, coadds.size());
1336 Nims = coadds.size();
1338 for(
int i=0;i<Nims;++i) ims.
image(i) = coadds[i];
1341 imageMJD.erase(imageMJD.begin()+Nims, imageMJD.end());
1342 heads.erase(heads.begin()+Nims, heads.end());
1344 for(
int i=0;i<Nims;++i)
1346 imageMJD[i] = avgMJD[i];
1347 for(
size_t j=0;j<coaddKeywords.size(); ++j)
1349 heads[i][coaddKeywords[j]].value(avgVals[i][j]);
1358 template<
typename _realT>
1362 if( m_maskFile !=
"")
1364 std::cerr <<
"creating mask cube\n";
1366 ff.
read(m_mask, m_maskFile);
1369 if(m_mask.rows() > m_imSize || m_mask.cols() > m_imSize)
1371 eigenImageT tmask = m_mask.block( (
int)(0.5*(m_mask.rows()-1) - 0.5*(m_imSize-1)), (
int)(0.5*(m_mask.rows()-1) - 0.5*(m_imSize-1)), m_imSize, m_imSize);
1380 template<
typename _realT>
1383 if( m_mask.rows() != m_Nrows || m_mask.cols() != m_Ncols)
1385 std::cerr <<
"\nMask is not the same size as images.\n\n";
1388 m_maskCube.resize( m_Nrows, m_Ncols, m_Nims);
1390 for(
int i=0; i< m_Nims; ++i)
1392 m_maskCube.image(i) = m_mask;
1397 template<
typename _realT>
1403 if( m_maskFile !=
"" && m_preProcess_mask)
1405 std::cerr <<
"Masking . . .\n";
1406 #pragma omp parallel for
1407 for(
int i=0;i<ims.planes(); ++i)
1409 ims.
image(i) *= m_mask;
1411 std::cerr <<
"done\n";
1414 if( m_preProcess_subradprof )
1416 std::cerr <<
"subtracting radial profile . . .\n";
1418 #pragma omp parallel
1423 for(
int i=0;i<ims.planes(); ++i)
1425 Eigen::Map<Eigen::Array<realT, Eigen::Dynamic, Eigen::Dynamic> > imRef(ims.
image(i));
1430 std::cerr <<
"done\n";
1432 if( m_maskFile !=
"" && m_preProcess_mask)
1434 std::cerr <<
"Masking . . .\n";
1435 #pragma omp parallel for
1436 for(
int i=0;i<ims.planes(); ++i)
1438 ims.
image(i) *= m_mask;
1440 std::cerr <<
"done\n";
1444 if( m_preProcess_medianUSM_fwhm > 0 )
1446 std::cerr <<
"applying median USM . . .\n";
1449 medmask.resize(ims.rows(), ims.cols());
1450 medmask.setConstant(1);
1452 for(
int z = 0; z < (int)(0.5*m_preProcess_medianUSM_fwhm); ++z)
1455 medmask.row(medmask.rows()-1-z) = 0;
1457 medmask.col(medmask.cols()-1-z) = 0;
1460 #pragma omp parallel
1463 fim.resize(ims.rows(), ims.cols());
1464 im.resize(ims.rows(), ims.cols());
1467 for(
int i=0;i<ims.planes(); ++i)
1471 ims.
image(i) = (im-fim)*medmask;
1475 if( m_maskFile !=
"" && m_preProcess_mask)
1477 std::cerr <<
"Masking . . .\n";
1478 #pragma omp parallel for
1479 for(
int i=0;i<ims.planes(); ++i)
1481 ims.
image(i) *= m_mask;
1485 std::cerr <<
"done\n";
1488 if( m_preProcess_gaussUSM_fwhm > 0 )
1490 std::cerr <<
"applying Gauss USM . . .\n";
1493 #pragma omp parallel for
1494 for(
int i=0;i<ims.planes(); ++i)
1503 if( m_maskFile !=
"" && m_preProcess_mask)
1505 std::cerr <<
"Masking . . .\n";
1506 #pragma omp parallel for
1507 for(
int i=0;i<ims.planes(); ++i)
1509 ims.
image(i) *= m_mask;
1514 std::cerr <<
"done\n";
1517 if( m_preProcess_azUSM_azW && m_preProcess_azUSM_radW )
1521 std::cerr <<
"applying azimuthal USM . . .\n";
1523 #pragma omp parallel for
1524 for(
int i=0;i<ims.planes(); ++i)
1534 if( m_maskFile !=
"" && m_preProcess_mask)
1536 std::cerr <<
"Masking . . .\n";
1537 #pragma omp parallel for
1538 for(
int i=0;i<ims.planes(); ++i)
1540 ims.
image(i) *= m_mask;
1545 std::cerr <<
"done (" << t_azusm_end - t_azusm_begin <<
" sec) \n";
1552 template<
typename _realT>
1558 if(m_weightFile ==
"")
1560 mxError(
"HCIobservation::readWeights", MXE_PARAMNOTSET,
"m_weightFile not set");
1565 std::vector<std::string> wfileNames;
1566 std::vector<realT> imW;
1570 if(imW.size() < m_fileList.size())
1572 mxError(
"HCIobservation::readWeights", MXE_SIZEERR,
"not enough weights specified");
1576 std::map<std::string, realT> weights;
1577 for(
size_t i=0;i<wfileNames.size();++i) weights[
ioutils::pathFilename(wfileNames[i].c_str())] = imW[i];
1579 m_comboWeights.resize(m_fileList.size());
1582 realT weightSum = 0;
1583 for(
size_t i=0; i<m_fileList.size(); ++i)
1591 mxError(
"HCIobservation::readWeights", MXE_NOTFOUND,
"Weight for a file in m_fileList not found.");
1594 m_comboWeights[i] = wi;
1599 for(
size_t i=0; i< m_comboWeights.size(); ++i)
1601 m_comboWeights[i] /= weightSum;
1607 template<
typename _realT>
1627 if(m_sigmaThreshold > 0)
1636 else if(m_combineMethod == HCI::debug)
1638 method = HCI::debug;
1644 m_finim.resize(m_psfsub[0].rows(), m_psfsub[0].cols(), m_psfsub.size());
1647 for(
size_t n= 0; n < m_psfsub.size(); ++n)
1651 m_psfsub[n].median(tfinim);
1652 m_finim.image(n) = tfinim;
1656 if(m_comboWeights.size() == (
size_t) m_Nims)
1658 if( m_maskFile !=
"" )
1660 m_psfsub[n].mean(tfinim, m_comboWeights, m_maskCube, m_minGoodFract);
1664 m_psfsub[n].mean(tfinim, m_comboWeights);
1669 if( m_maskFile !=
"" )
1671 m_psfsub[n].mean(tfinim, m_maskCube, m_minGoodFract);
1675 m_psfsub[n].mean(tfinim);
1678 m_finim.image(n) = tfinim;
1682 if(m_comboWeights.size() == (
size_t) m_Nims)
1684 if( m_maskFile !=
"" )
1686 m_psfsub[n].sigmaMean(tfinim, m_comboWeights, m_maskCube, m_sigmaThreshold, m_minGoodFract);
1690 m_psfsub[n].sigmaMean(tfinim, m_comboWeights, m_sigmaThreshold);
1695 if( m_maskFile !=
"" )
1697 m_psfsub[n].sigmaMean(tfinim, m_maskCube, m_sigmaThreshold, m_minGoodFract);
1701 m_psfsub[n].sigmaMean(tfinim, m_sigmaThreshold);
1704 m_finim.image(n) = tfinim;
1706 else if(method == HCI::debug)
1708 m_finim.image(n) = m_psfsub[n].image(0);
1715 template<
typename _realT>
1718 if(m_preProcess_outputPrefix ==
"")
return;
1720 std::string bname, fname;
1725 for(
int i=0; i< m_Nims; ++i)
1727 bname = m_fileList[i];
1729 ff.
write(fname, m_tgtIms.image(i).data(), m_Ncols, m_Nrows, 1, m_heads[i]);
1733 template<
typename _realT>
1736 head.
append(
"", fits::fitsCommentType(),
"----------------------------------------");
1737 head.
append(
"", fits::fitsCommentType(),
"mx::HCIobservation parameters:");
1738 head.
append(
"", fits::fitsCommentType(),
"----------------------------------------");
1740 head.
append<
int>(
"FDELFRNT", m_deleteFront,
"images deleted from front of file list");
1741 head.
append<
int>(
"FDELBACK", m_deleteBack,
"images deleted from back of file list");
1745 head.
append<
realT>(
"QTHRESH", m_qualityThreshold,
"quality threshold");
1746 head.
append<
int>(
"NUMIMS", m_Nims,
"number of images processed");
1748 head.
append<
int>(
"IMSIZE", m_imSize,
"image size after reading");
1753 head.
append<
int>(
"COADIMNO", m_coaddMaxImno,
"max number of images in each coadd");
1754 head.
append<
realT>(
"COADTIME", m_coaddMaxTime,
"max time in each coadd");
1758 head.
append<
int>(
"COADIMNO", 0,
"max number of images in each coadd");
1759 head.
append<
realT>(
"COADTIME", 0,
"max time in each coadd");
1762 head.
append(
"MASKFILE", m_maskFile,
"mask file");
1764 head.
append<
int>(
"PREPROC BEFORE", m_preProcess_beforeCoadd,
"pre-process before coadd flag");
1765 head.
append<
int>(
"PREPROC MASK", m_preProcess_mask,
"pre-process mask flag");
1766 head.
append<
int>(
"PREPROC SUBRADPROF", m_preProcess_subradprof,
"pre-process subtract radial profile flag");
1767 head.
append<
realT>(
"PREPROC AZUSM AZWIDTH", m_preProcess_azUSM_azW,
"pre-process azimuthal USM azimuthal width [pixels]");
1768 head.
append<
realT>(
"PREPROC AZUSM MAXAZ", m_preProcess_azUSM_maxAz,
"pre-process azimuthal USM maximum azimuthal width [degrees]");
1769 head.
append<
realT>(
"PREPROC AZUSM RADWIDTH", m_preProcess_azUSM_radW,
"pre-process azimuthal USM radial width [pixels]");
1770 head.
append<
realT>(
"PREPROC MEDIANUSM FWHM", m_preProcess_medianUSM_fwhm,
"pre-process median USM fwhm [pixels]");
1771 head.
append<
realT>(
"PREPROC GAUSSUSM FWHM", m_preProcess_gaussUSM_fwhm,
"pre-process Gaussian USM fwhm [pixels]");
1775 template<
typename _realT>
1778 std::string fname = m_finimName;
1780 if(m_outputDir !=
"")
1782 mkdir(m_outputDir.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
1784 fname = m_outputDir +
"/" + fname;
1787 if(!m_exactFinimName)
1795 stdFitsHeader(head);
1800 if(m_weightFile !=
"")
1801 head.
append(
"WEIGHTF", m_weightFile,
"file containing weights for combination");
1805 head.
append<
realT>(
"SIGMAT", m_sigmaThreshold,
"threshold for sigma clipping");
1816 f.
write(fname, m_finim, head);
1818 std::cerr <<
"Final image written to: " << fname <<
"\n";
1821 template<
typename _realT>
1831 stdFitsHeader(head);
1845 if(m_comboWeights.size() > 0)
1847 fname = m_PSFSubPrefix +
"weights.dat";
1848 if(m_outputDir !=
"")
1850 mkdir(m_outputDir.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
1851 fname = m_outputDir +
"/" + fname;
1854 std::cerr <<
"writing comboWeights: " << fname <<
"\n";
1858 for(
size_t n=0; n<m_psfsub.size(); ++n)
1860 for(
int p=0; p< m_psfsub[n].planes(); ++p)
1862 snprintf(num, 256,
"_%03zu_%05d.fits",n,p);
1863 fname = m_PSFSubPrefix + num;
1865 if(m_outputDir !=
"")
1867 mkdir(m_outputDir.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
1868 fname = m_outputDir +
"/" + fname;
1873 h.append(m_heads[p]);
1876 f.
write(fname, m_psfsub[n].image(p).data(), m_psfsub[n].rows(), m_psfsub[n].cols(), 1,
h);
1878 if(m_comboWeights.size() > 0 && n == 0)
1880 wout << fname <<
" " << m_comboWeights[p] <<
"\n";
1885 if(m_comboWeights.size() > 0)
1895 template<
typename _realT>
1897 const std::string & prefix,
1898 const std::string & ext,
1904 m_psfsub.resize(nReductions);
1912 ff.
read(im, fh, flist[0]);
1914 if(fh.
count(
"FDELFRNT") == 0)
1916 mxError(
"KLIPReduction", MXE_PARAMNOTSET,
"FDELFRNT not found in FITS header.");
1919 m_deleteFront = fh[
"FDELFRNT"].value<
int>();
1920 std::cerr <<
"deleteFront: " << m_deleteFront <<
"\n";
1922 if(fh.
count(
"FDELBACK") == 0)
1924 mxError(
"KLIPReduction", MXE_PARAMNOTSET,
"FDELBACK not found in FITS header.");
1927 m_deleteBack = fh[
"FDELBACK"].value<
int>();
1928 std::cerr <<
"deleteBack: " << m_deleteBack <<
"\n";
1930 if(fh.
count(
"QFILE") == 0)
1932 mxError(
"KLIPReduction", MXE_PARAMNOTSET,
"QFILE not found in FITS header.");
1935 m_qualityFile = fh[
"QFILE"].String();
1936 std::cerr <<
"qualityFile: " << m_qualityFile <<
"\n";
1938 if(fh.
count(
"QTHRESH") == 0)
1940 mxError(
"KLIPReduction", MXE_PARAMNOTSET,
"QTHRESH not found in FITS header.");
1943 m_qualityThreshold = fh[
"QTHRESH"].value<
realT>();
1944 std::cerr <<
"qualityThreshold: " << m_qualityThreshold <<
"\n";
1946 if(fh.
count(
"COADMTHD") == 0)
1948 mxError(
"KLIPReduction", MXE_PARAMNOTSET,
"COADMTHD not found in FITS header.");
1952 std::cerr <<
"coaddCombineMethod: " << m_coaddCombineMethod <<
"\n";
1954 if(fh.
count(
"COADIMNO") != 0)
1956 m_coaddMaxImno = fh[
"COADIMNO"].value<
int>();
1957 std::cerr <<
"coaddMaxImno: " << m_coaddMaxImno <<
"\n";
1960 if(fh.
count(
"COADTIME") != 0)
1962 m_coaddMaxImno = fh[
"COADTIME"].value<
realT>();
1963 std::cerr <<
"coaddMaxtime: " << m_coaddMaxTime <<
"\n";
1966 if(m_maskFile ==
"")
1968 if(fh.
count(
"MASKFILE") == 0)
1970 mxError(
"KLIPReduction", MXE_PARAMNOTSET,
"MASKFILE not found in FITS header and not set in configuration.");
1973 m_maskFile = fh[
"MASKFILE"].String();
1975 std::cerr <<
"maskFile: " << m_maskFile <<
"\n";
1977 if(fh.
count(
"PPBEFORE") == 0)
1979 mxError(
"KLIPReduction", MXE_PARAMNOTSET,
"PPBEFORE not found in FITS header.");
1982 m_preProcess_beforeCoadd = fh[
"PPBEFORE"].value<
int>();
1983 std::cerr <<
"preProcess_beforeCoadd: " << m_preProcess_beforeCoadd <<
"\n";
1985 if(fh.
count(
"PPMASK") == 0)
1987 mxError(
"KLIPReduction", MXE_PARAMNOTSET,
"PPMASK not found in FITS header.");
1990 m_preProcess_mask = fh[
"PPMASK"].value<
int>();
1991 std::cerr <<
"preProcess_mask: " << m_preProcess_mask <<
"\n";
1993 if(fh.
count(
"PPSUBRAD") == 0)
1995 mxError(
"KLIPReduction", MXE_PARAMNOTSET,
"PPSUBRAD not found in FITS header.");
1998 m_preProcess_subradprof = fh[
"PPSUBRAD"].value<
int>();
1999 std::cerr <<
"preProcess_subradprof: " << m_preProcess_subradprof <<
"\n";
2001 if(fh.
count(
"PPAUSMAW") == 0)
2003 mxError(
"KLIPReduction", MXE_PARAMNOTSET,
"PPAUSMAW not found in FITS header.");
2006 m_preProcess_azUSM_azW = fh[
"PPAUSMAW"].value<
realT>();
2007 std::cerr <<
"preProcess_azUSM_azW: " << m_preProcess_azUSM_azW <<
"\n";
2009 if(fh.
count(
"PPAUSMRW") == 0)
2011 mxError(
"KLIPReduction", MXE_PARAMNOTSET,
"PPAUSMRW not found in FITS header.");
2014 m_preProcess_azUSM_radW = fh[
"PPAUSMRW"].value<
realT>();
2015 std::cerr <<
"preProcess_azUSM_radW: " << m_preProcess_azUSM_radW <<
"\n";
2017 if(fh.
count(
"PPGUSMFW") == 0)
2019 mxError(
"KLIPReduction", MXE_PARAMNOTSET,
"PPGUSMFW not found in FITS header.");
2022 m_preProcess_gaussUSM_fwhm = fh[
"PPGUSMFW"].value<
realT>();
2023 std::cerr <<
"preProcess_gaussUSM_fwhm: " << m_preProcess_gaussUSM_fwhm <<
"\n";
2028 if(m_MJDKeyword !=
"") head.
append(m_MJDKeyword);
2030 for(
size_t i=0;i<m_keywords.size();++i)
2032 head.
append(m_keywords[i]);
2035 for(
size_t n =0; n<nReductions; ++n)
2038 int nwr = snprintf(nstr,
sizeof(nstr),
"%03zu", n);
2039 if(nwr < 0 || n >=
sizeof(nstr))
2041 std::cerr <<
"possibly bad formatting in filename\n";
2045 std::string nprefix = prefix +
"_" + nstr +
"_";
2046 load_fileList(dir, nprefix, ext);
2048 if(m_fileList.size() == 0)
2050 mxError(
"HCIobservation", MXE_FILENOTFOUND,
"The m_fileList has 0 length, there are no files to be read.");
2054 Eigen::Array<realT, Eigen::Dynamic, Eigen::Dynamic> im;
2063 std::cerr << fh[
"FAKEPA"].String() <<
"\n";
2069 m_imSize = im.rows();
2070 if(m_imSize > im.cols()) m_imSize = im.cols();
2075 if(m_imSize > im.rows()) m_imSize = im.rows();
2076 if(m_imSize > im.cols()) m_imSize = im.cols();
2080 f.
setReadSize( floor(0.5*(im.rows()-1) - 0.5*(m_imSize-1) +0.1), floor(0.5*(im.cols()-1.0) - 0.5*(m_imSize-1.0)+0.1), m_imSize, m_imSize);
2081 im.resize(m_imSize, m_imSize);
2085 if(m_fileList.size() != (
size_t) m_Nims)
2087 mxError(
"HCIobservation", MXE_INVALIDARG,
"Different number of images in reductions.");
2090 if(m_Nrows != im.rows())
2092 mxError(
"HCIobservation", MXE_INVALIDARG,
"Different number of rows in reductions.");
2095 if(m_Ncols != im.cols())
2097 mxError(
"HCIobservation", MXE_INVALIDARG,
"Different number of cols in reductions.");
2103 std::cerr <<
"found " << nReductions <<
" sets of " << m_fileList.size() <<
" " << im.rows() <<
" x " << im.cols() <<
" files\n";
2105 m_Nims = m_fileList.size();
2106 m_Nrows = im.rows();
2107 m_Ncols = im.cols();
2108 m_Npix = im.rows()*im.cols();
2110 m_psfsub[n].resize(m_Nrows, m_Ncols, m_Nims);
2113 m_heads.resize(m_fileList.size(), head);
2117 f.
read(m_psfsub[n].data(), m_heads, m_fileList);
2121 if(m_MJDKeyword !=
"")
2123 m_imageMJD.resize(m_heads.size());
2127 for(
size_t i=0;i<m_imageMJD.size();++i)
2134 for(
size_t i=0;i<m_imageMJD.size();++i)
2136 m_imageMJD[i] = m_heads[i][m_MJDKeyword].template value<realT>()*m_MJDUnits;
2143 for(
size_t n=0; n<m_psfsub.size(); ++n)
2150 if(m_weightFile !=
"")
2152 std::vector<std::string> fn;
2155 std::cerr <<
"read: " << m_weightFile <<
" (" << m_comboWeights.size() <<
")\n";
2159 if( postReadFiles() < 0)
return -1;
Class to manage interactions with a FITS file.
int write(const dataT *im, int d1, int d2, int d3, fitsHeader *head)
Write the contents of a raw array to the FITS file.
void setReadSize()
Set to read all the pixels in the file.
int read(dataT *data)
Read the contents of the FITS file into an array.
void median(eigenT &mim)
Calculate the median image of the cube.
void mean(eigenT &mim)
Calculate the mean image of the cube.
Eigen::Map< Eigen::Array< dataT, Eigen::Dynamic, Eigen::Dynamic > > image(Index n)
Returns a 2D Eigen::Eigen::Map pointed at the specified image.
A class to track the number of iterations in an OMP parallelized loop.
void incrementAndOutputStatus()
Increment and output status.
An image cube with an Eigen API.
Tools for using the eigen library for image processing.
int readColumns(const std::string &fname, arrTs &... arrays)
Read in columns from a text file.
constexpr units::realT h()
Planck Constant.
Eigen::Array< scalarT, -1, -1 > eigenImage
Definition of the eigenImage type, which is an alias for Eigen::Array.
std::string getSequentialFilename(const std::string &basename, const std::string &extension="", const int startat=0, int ndigit=4)
Get the next file in a numbered sequence.
std::vector< std::string > getFileNames(const std::string &directory, const std::string &prefix, const std::string &substr, const std::string &extension)
Get a list of file names from the specified directory, specifying a prefix, a substring to match,...
std::string pathFilename(const std::string &fname)
Get the base filename.
void fitsHeaderGitStatus(fitsHeader &head, const std::string &repoName, const char *sha1, int modified)
Write the status of a Git repository to HISTORY in a FITS header.
combineMethods
Possible combination methods.
@ sigmaMeanCombine
Combine with the sigma clipped mean.
@ noCombine
Do not combine the images.
@ meanCombine
Combine with the mean.
@ medianCombine
Combine with the median.
int medianSmooth(imageTout &imOut, int &xMax, int &yMax, typename imageTout::Scalar &pMax, const imageTin &imIn, int medianFullWidth)
Smooth an image using the median in a rectangular box. Also Determines the location and value of the ...
void filterImage(imageOutT &fim, imageInT im, kernelT kernel, int maxr=0)
Filter an image with a mean kernel.
void zeroNaNCube(cubeT &imc)
Zero any NaNs in an image cube.
void radprofim(radprofT &radprofIm, eigenImT1 &im, const eigenImT2 &rad, const eigenImT3 *mask, bool subtract, bool mean=false)
Form a radial profile image, and optionally subtract it from the input.
typeT get_curr_time(timespec &tsp)
Get the current system time in seconds.
double ISO8601date2mjd(const std::string &fdate)
Parse an ISO8601 date of the form "YYYY-MM-DDTHH:MM:SS.S" and return the modified Julian date (MJD)
Image filters (smoothing, radial profiles, etc.)
Declares and defines functions to work with image masks.
Header for the image processing utilities.
int combineMethodFmStr(const std::string &method)
Get the combineMethod from the corresponding string name.
std::string combineMethodStr(int method)
Get the string name of the combineMethod integer.
The basic high contrast imaging data type.
int m_imSize
Set the image size. Images are cut down to this size after reading.
int m_RDIdeleteBack
Specify how many files from m_RDIfileList to delete from the back of the list.
bool m_preProcess_only
If true, then we stop after pre-processing.
_realT realT
The arithmetic type used for calculations. Does not have to match the type in images on disk.
std::vector< std::string > m_coaddKeywords
The values of these keywords will be averaged and replaced.
bool m_thresholdOnly
Just prints the names and qualities of the files which pass threshold, and stop.
void stdFitsHeader(fits::fitsHeader &head)
Fill in the HCIobservation standard FITS header.
std::string m_weightFile
Specifies a file containing the image weights, for combining with weighted mean.
std::vector< std::string > m_RDIfileList
The list of files to read in for the RDI basis.
std::vector< std::string > m_RDIkeywords
Vector of FITS header keywords to read from the files in m_fileList.
bool m_preProcess_mask
If true, the mask is applied during each pre-processing step.
std::string m_RDIqualityFile
File containing 2 space-delimited columns of fileMame qualityValue pairs for the reference images.
eigenCube< realT > m_tgtIms
The target image cube.
bool m_RDIfilesRead
Whether or not the reference files have been read.
std::vector< double > m_RDIimageMJD
Vector of reference image times, in MJD.
HCIobservation()
Default c'tor.
realT m_MJDUnits
If the date is not ISO 8601, this specifies the conversion to Julian Days (i.e. seconds to days)
int m_preProcess_medianUSM_fwhm
Kernel FWHM for symmetric box median unsharp mask (USM)
bool m_exactFinimName
Use m_finimName exactly as specified, without appending a number or an extension.
int readRDIFiles()
Read the list of reference files, cut to size, and preprocess.
void writeFinim(fits::fitsHeader *addHead=0)
Write the final combined image to disk.
std::vector< fits::fitsHeader > m_RDIheads
Vector of FITS headers, one per reference file, populated with the values for the keywords.
std::string m_preProcess_outputPrefix
Set path and file prefix to output the pre-processed images.
int m_Nrows
Number of rows of the images in m_tgtIms.
void load_RDIfileList(const std::string &dir, const std::string &prefix, const std::string &ext)
Load the RDI basis file list.
int readPSFSub(const std::string &dir, const std::string &prefix, const std::string &ext, size_t nReductions)
Read in already PSF-subtracted files.
int m_deleteBack
Specify how many files from m_fileList to delete from the back of the list.
realT m_minGoodFract
The minimum fraction of good (un-masked) pixels to include in the final combination (0....
std::string m_qualityFile
File containing 2 space-delimited columns of fileVame qualityValue pairs.
eigenImageT m_mask
The mask.
int readWeights()
Read the image weights from m_weightFile.
int m_combineMethod
Determine how to combine the PSF subtracted images.
Eigen::Array< realT, Eigen::Dynamic, Eigen::Dynamic > eigenImageT
The Eigen image array type basted on realT.
int readFiles()
Read the list of files, cut to size, and preprocess.
realT m_preProcess_azUSM_radW
Radial boxcar width for azimuthal unsharp mask [pixels].
realT m_sigmaThreshold
The standard deviation threshold used if combineMethod == HCI::sigmaMeanCombine.
std::string m_finimName
The base file name of the output final image.
bool m_skipPreProcess
Don't do any of the pre-processing steps (including coadding).
int m_Ncols
Number of columns of the images in m_tgtIms.
int m_Nims
Number of images in m_tgtIms.
void readMask()
Read the mask file, resizing to imSize if needed.
int m_coaddMaxImno
Maximum number of images to coadd.
bool m_MJDisISO8601
Whether or not the date is in ISO 8601 format.
bool m_filesRead
Whether or not the m_fileList has been read.
std::string m_outputDir
The directory where to write output files.
bool m_preProcess_subradprof
If true, a radial profile is subtracted from each image.
std::vector< std::string > m_fileList
The list of files to read in.
realT m_coaddMaxTime
Maximum elapsed time over which to coadd the images.
eigenCube< realT > m_maskCube
A cube of masks, one for each input image, which may be modified versions (e.g. rotated) of mask.
virtual void makeMaskCube()
Populate the mask cube which is used for post-processing. Derived classes can do this as appropriate,...
void outputRDIPreProcessed()
Output the pre-processed reference images.
virtual int postCoadd()
Perform post-coadd actions for the target images, for use by derived classes.
void outputPSFSub(fits::fitsHeader *addHead=0)
Write the PSF subtracted images to disk.
std::vector< eigenCube< realT > > m_psfsub
The PSF subtracted images.
std::string m_PSFSubPrefix
Prefix of the FITS file names used to write individual PSF subtracted images to disk if m_doOutputPSF...
bool m_preProcess_beforeCoadd
controls whether pre-processing takes place before or after coadding
void load_fileList(const std::string &dir, const std::string &prefix, const std::string &ext)
Load the file list.
int m_Npix
Pixels per image, that is Nrows*Ncols.
int threshold(std::vector< std::string > &fileList, const std::string &qualityFile, realT qualityThreshold)
Read the image qualities from a qualityFile and apply the threshold to a fileList.
std::string m_MJDKeyword
Name of the keyword to use for the image date.
eigenCube< realT > m_refIms
The optional reference image cube.
std::vector< std::string > m_keywords
Vector of FITS header keywords to read from the files in m_fileList.
bool m_doOutputPSFSub
Controls whether or not the individual PSF subtracted images are written to disk.
realT m_RDIqualityThreshold
Threshold to apply to qualityValues read from qualityFile.
int m_coaddCombineMethod
Determine how to coadd the raw images.
realT m_qualityThreshold
Threshold to apply to qualityValues read from qualityFile.
virtual int postRDIReadFiles()
Perform post-read actions for the RDI images, for use by derived classes.
int m_deleteFront
Specify how many files from m_fileList to delete from the front of the list.
realT m_preProcess_gaussUSM_fwhm
Kernel FWHM for symmetric Gaussian unsharp mask (USM)
virtual int postReadFiles()
Perform post-read actions for the target images, for use by derived classes.
realT m_preProcess_azUSM_azW
Azimuthal boxcar width for azimuthal unsharp mask [pixels].
void coaddImages(int coaddCombineMethod, int coaddMaxImno, int coaddMaxTime, std::vector< std::string > &coaddKeywords, std::vector< double > &imageMJD, std::vector< fits::fitsHeader > &heads, eigenCube< realT > &ims)
Coadd the images.
std::vector< realT > m_comboWeights
Vector to hold the image weights read from the m_weightFile.
std::vector< fits::fitsHeader > m_heads
Vector of FITS headers, one per file, populated with the values for the keywords.
std::string m_maskFile
Specify a mask file to apply.
int m_doWriteFinim
Set whether the final combined image is written to disk.
virtual int postRDICoadd()
Perform post-coadd actions, for use by derived classes.
bool m_filesDeleted
Whether or not the specified files have been deleted from m_fileList.
void combineFinim()
Combine the images into a single final image.
realT m_preProcess_azUSM_maxAz
Mazimum azimuthal boxcar width for azimuthal unsharp mask [degrees].
void preProcess(eigenCube< realT > &ims)
Do the pre-processing.
int m_RDIdeleteFront
Specify how many files from m_RDIfileList to delete from the front of the list.
std::vector< double > m_imageMJD
Vector of target image times, in MJD.
void outputPreProcessed()
Output the pre-processed target images.
eigenCube< realT > m_finim
The final combined images, one for each cube in psfsub.
bool m_RDIfilesDeleted
Whether or not the specified files have been deleted from m_RDIfileList.
Azimuthally variable boxcare kernel.
Symetric Gaussian smoothing kernel.