Skip to content

Commit

Permalink
Add generic method to add fits header keywords. Remove observer and o…
Browse files Browse the repository at this point in the history
…bject properties
  • Loading branch information
knro committed Mar 16, 2023
1 parent 7d4ed1e commit eb96c94
Show file tree
Hide file tree
Showing 2 changed files with 111 additions and 29 deletions.
129 changes: 105 additions & 24 deletions libs/indibase/indiccd.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -404,10 +404,10 @@ bool CCD::initProperties()
/****************** FITS Header****************/
/**********************************************/

IUFillText(&FITSHeaderT[FITS_OBSERVER], "FITS_OBSERVER", "Observer", "Unknown");
IUFillText(&FITSHeaderT[FITS_OBJECT], "FITS_OBJECT", "Object", "Unknown");
IUFillTextVector(&FITSHeaderTP, FITSHeaderT, 2, getDeviceName(), "FITS_HEADER", "FITS Header", INFO_TAB, IP_RW, 60,
IPS_IDLE);
FITSHeaderTP[KEYWORD_NAME].fill("KEYWORD_NAME", "Name", nullptr);
FITSHeaderTP[KEYWORD_VALUE].fill("KEYWORD_VALUE", "Value", nullptr);
FITSHeaderTP[KEYWORD_COMMENT].fill("KEYWORD_COMMENT", "Comment", nullptr);
FITSHeaderTP.fill(getDeviceName(), "FITS_HEADER", "FITS Header", INFO_TAB, IP_WO, 60, IPS_IDLE);

/**********************************************/
/****************** Exposure Looping **********/
Expand Down Expand Up @@ -544,7 +544,7 @@ bool CCD::updateProperties()
if (CanBin())
defineProperty(&PrimaryCCD.ImageBinNP);

defineProperty(&FITSHeaderTP);
defineProperty(FITSHeaderTP);

if (HasGuideHead())
{
Expand Down Expand Up @@ -655,7 +655,7 @@ bool CCD::updateProperties()
}
#endif

deleteProperty(FITSHeaderTP.name);
deleteProperty(FITSHeaderTP);

if (HasGuideHead())
{
Expand Down Expand Up @@ -974,11 +974,76 @@ bool CCD::ISNewText(const char * dev, const char * name, char * texts[], char *
return true;
}

if (!strcmp(name, FITSHeaderTP.name))
// FITS Header
if (FITSHeaderTP.isNameMatch(name))
{
IUUpdateText(&FITSHeaderTP, texts, names, n);
FITSHeaderTP.s = IPS_OK;
IDSetText(&FITSHeaderTP, nullptr);
FITSHeaderTP.update(texts, names, n);

std::string name = FITSHeaderTP[KEYWORD_NAME].getText();
std::string value = FITSHeaderTP[KEYWORD_VALUE].getText();
std::string comment = FITSHeaderTP[KEYWORD_COMMENT].getText();

if (name.empty() && value.empty() && comment.empty())
{
LOG_ERROR("Cannot add an empty FITS record.");
FITSHeaderTP.setState(IPS_ALERT);
}
else
{
FITSHeaderTP.setState(IPS_OK);
// Specical keyword
if (name == "INDI_CLEAR")
{
m_CustomFITSKeywords.clear();
LOG_INFO("Custom FITS headers cleared.");
}
else if (name.empty() == false && value.empty() == false)
{
// Double regex
std::regex checkDouble("^[-+]?([0-9]*?[.,][0-9]+|[0-9]+)$");
// Integer regex
std::regex checkInteger("^[-+]?([0-9]*)$");

try
{
// Try long
if (std::regex_match(value, checkInteger))
{
auto lValue = std::stol(value);
FITSRecord record(name.c_str(), lValue, comment.c_str());
m_CustomFITSKeywords[name.c_str()] = record;
}
// Try double
else if (std::regex_match(value, checkDouble))
{
auto dValue = std::stod(value);
FITSRecord record(name.c_str(), dValue, 6, comment.c_str());
m_CustomFITSKeywords[name.c_str()] = record;
}
// Store as text
else
{
// String
FITSRecord record(name.c_str(), value.c_str(), comment.c_str());
m_CustomFITSKeywords[name.c_str()] = record;
}
}
// In case conversion fails
catch (std::exception &e)
{
// String
FITSRecord record(name.c_str(), value.c_str(), comment.c_str());
m_CustomFITSKeywords[name.c_str()] = record;
}
}
else if (comment.empty() == false)
{
FITSRecord record(comment.c_str());
m_CustomFITSKeywords[comment.c_str()] = record;
}
}

FITSHeaderTP.apply();
return true;
}

Expand Down Expand Up @@ -1899,12 +1964,6 @@ void CCD::addFITSKeywords(CCDChip * targetChip, std::vector<FITSRecord> &fitsKey
if (std::isnan(effectiveAperture))
LOG_WARN("Telescope aperture is missing.");

// Observer
fitsKeywords.push_back({"OBSERVER", FITSHeaderT[FITS_OBSERVER].text, "Observer name"});

// Object
fitsKeywords.push_back({"OBJECT", FITSHeaderT[FITS_OBJECT].text, "Object name"});

double subPixSize1 = static_cast<double>(targetChip->getPixelSizeX());
double subPixSize2 = static_cast<double>(targetChip->getPixelSizeY());
uint32_t subW = targetChip->getSubW();
Expand Down Expand Up @@ -2280,7 +2339,13 @@ bool CCD::ExposureCompletePrivate(CCDChip * targetChip)
}

std::vector<FITSRecord> fitsKeywords;

addFITSKeywords(targetChip, fitsKeywords);

// Add all custom keywords next
for (auto &record : m_CustomFITSKeywords)
fitsKeywords.push_back(record.second);

for (auto &keyword : fitsKeywords)
{
int key_status = 0;
Expand Down Expand Up @@ -2358,18 +2423,34 @@ bool CCD::ExposureCompletePrivate(CCDChip * targetChip)
targetChip->getNAxis() == 2 ? 1 : 3);
switch(targetChip->getBPP())
{
case 8: image.setSampleFormat(LibXISF::Image::UInt8); break;
case 16: image.setSampleFormat(LibXISF::Image::UInt16); break;
case 32: image.setSampleFormat(LibXISF::Image::UInt32); break;
default: LOGF_ERROR("Unsupported bits per pixel value %d", targetChip->getBPP()); return false;
case 8:
image.setSampleFormat(LibXISF::Image::UInt8);
break;
case 16:
image.setSampleFormat(LibXISF::Image::UInt16);
break;
case 32:
image.setSampleFormat(LibXISF::Image::UInt32);
break;
default:
LOGF_ERROR("Unsupported bits per pixel value %d", targetChip->getBPP());
return false;
}

switch(targetChip->getFrameType())
{
case CCDChip::LIGHT_FRAME: image.setImageType(LibXISF::Image::Light); break;
case CCDChip::BIAS_FRAME: image.setImageType(LibXISF::Image::Bias); break;
case CCDChip::DARK_FRAME: image.setImageType(LibXISF::Image::Dark); break;
case CCDChip::FLAT_FRAME: image.setImageType(LibXISF::Image::Flat); break;
case CCDChip::LIGHT_FRAME:
image.setImageType(LibXISF::Image::Light);
break;
case CCDChip::BIAS_FRAME:
image.setImageType(LibXISF::Image::Bias);
break;
case CCDChip::DARK_FRAME:
image.setImageType(LibXISF::Image::Dark);
break;
case CCDChip::FLAT_FRAME:
image.setImageType(LibXISF::Image::Flat);
break;
}

if (targetChip->SendCompressed)
Expand Down
11 changes: 6 additions & 5 deletions libs/indibase/indiccd.h
Original file line number Diff line number Diff line change
Expand Up @@ -768,13 +768,12 @@ class CCD : public DefaultDevice, GuiderInterface
double m_UploadTime = { 0 };
std::chrono::system_clock::time_point FastExposureToggleStartup;

// FITS Header
IText FITSHeaderT[2] {};
ITextVectorProperty FITSHeaderTP;
INDI::PropertyText FITSHeaderTP {3};
enum
{
FITS_OBSERVER,
FITS_OBJECT
KEYWORD_NAME,
KEYWORD_VALUE,
KEYWORD_COMMENT,
};

private:
Expand All @@ -785,6 +784,8 @@ class CCD : public DefaultDevice, GuiderInterface
int m_ConfigEncodeFormatIndex {-1};
int m_ConfigFastExposureIndex {INDI_DISABLED};

std::map<std::string, FITSRecord> m_CustomFITSKeywords;

///////////////////////////////////////////////////////////////////////////////
/// Utility Functions
///////////////////////////////////////////////////////////////////////////////
Expand Down

0 comments on commit eb96c94

Please sign in to comment.