File indexing completed on 2024-04-14 03:41:20

0001 /*
0002     SPDX-FileCopyrightText: 2021 Valentin Boettcher <hiro at protagon.space; @hiro98:tchncs.de>
0003 
0004     SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 
0007 #include "addcatalogobject.h"
0008 #include "ui_addcatalogobject.h"
0009 #include "kstars_debug.h"
0010 
0011 #include <QInputDialog>
0012 #include <QPushButton>
0013 
0014 AddCatalogObject::AddCatalogObject(QWidget *parent, const CatalogObject &obj)
0015     : QDialog(parent), ui(new Ui::AddCatalogObject), m_object{ obj }
0016 {
0017     ui->setupUi(this);
0018     ui->ra->setUnits(dmsBox::HOURS);
0019     fill_form_from_object();
0020 
0021     connect(ui->name, &QLineEdit::textChanged,
0022             [&](const auto &name) { m_object.setName(name); });
0023 
0024     connect(ui->long_name, &QLineEdit::textChanged,
0025             [&](const auto &name) { m_object.setLongName(name); });
0026 
0027     connect(ui->catalog_identifier, &QLineEdit::textChanged,
0028             [&](const auto &ident) { m_object.setCatalogIdentifier(ident); });
0029 
0030     connect(ui->type, QOverload<int>::of(&QComboBox::currentIndexChanged),
0031             [&](const auto index) {
0032                 if (index > SkyObject::TYPE_UNKNOWN)
0033                     m_object.setType(SkyObject::TYPE_UNKNOWN);
0034 
0035                 m_object.setType(index);
0036 
0037                 refresh_flux();
0038             });
0039 
0040     auto validateAndStoreCoordinates = [&]() {
0041         bool raOk(false), decOk(false);
0042         auto ra = ui->ra->createDms(&raOk);
0043         auto dec = ui->dec->createDms(&decOk);
0044         auto* okButton = ui->buttonBox->button(QDialogButtonBox::Ok);
0045         Q_ASSERT(!!okButton);
0046         okButton->setEnabled(raOk && decOk);
0047         if (raOk && decOk) {
0048             m_object.setRA0(ra);
0049             m_object.setDec0(dec);
0050         }
0051     };
0052 
0053     connect(ui->ra, &dmsBox::textChanged, validateAndStoreCoordinates);
0054     connect(ui->dec, &dmsBox::textChanged, validateAndStoreCoordinates);
0055 
0056     auto updateMag = [&]()
0057     {
0058         m_object.setMag(
0059             ui->magUnknown->isChecked() ? NaN::f : static_cast<float>(ui->mag->value()));
0060     };
0061     connect(ui->mag, QOverload<double>::of(&QDoubleSpinBox::valueChanged), updateMag);
0062     connect(ui->magUnknown, &QCheckBox::stateChanged, updateMag);
0063 
0064     connect(ui->maj, QOverload<double>::of(&QDoubleSpinBox::valueChanged),
0065             [&](const auto value) { m_object.setMaj(static_cast<float>(value)); });
0066 
0067     connect(ui->min, QOverload<double>::of(&QDoubleSpinBox::valueChanged),
0068             [&](const auto value) { m_object.setMin(static_cast<float>(value)); });
0069 
0070     connect(ui->flux, QOverload<double>::of(&QDoubleSpinBox::valueChanged),
0071             [&](const auto value) { m_object.setFlux(static_cast<float>(value)); });
0072 
0073     connect(ui->position_angle, QOverload<double>::of(&QDoubleSpinBox::valueChanged),
0074             [&](const auto value) { m_object.setPA(value); });
0075 
0076     connect(ui->guessFromTextButton, &QPushButton::clicked, [this]() { this->guess_form_contents_from_text(); });
0077 }
0078 
0079 AddCatalogObject::~AddCatalogObject()
0080 {
0081     delete ui;
0082 }
0083 
0084 void AddCatalogObject::fill_form_from_object()
0085 {
0086     if (m_object.hasName()) // N.B. Avoid filling name fields with "unnamed"
0087         ui->name->setText(m_object.name());
0088     if (m_object.hasLongName())
0089         ui->long_name->setText(m_object.longname());
0090     ui->catalog_identifier->setText(m_object.catalogIdentifier());
0091 
0092     for (int k = 0; k < SkyObject::NUMBER_OF_KNOWN_TYPES; ++k)
0093     {
0094         ui->type->addItem(SkyObject::typeName(k));
0095     }
0096     ui->type->addItem(SkyObject::typeName(SkyObject::TYPE_UNKNOWN));
0097     ui->type->setCurrentIndex((int)(m_object.type()));
0098 
0099     dms ra0 = m_object.ra0();
0100     dms dec0 = m_object.dec0(); // Make a copy to avoid overwriting by signal-slot connection
0101     ui->ra->show(ra0);
0102     ui->dec->show(dec0);
0103     if (std::isnan(m_object.mag()))
0104     {
0105         ui->magUnknown->setChecked(true);
0106     }
0107     else
0108     {
0109         ui->mag->setValue(m_object.mag());
0110         ui->magUnknown->setChecked(false);
0111     }
0112     ui->flux->setValue(m_object.flux());
0113     ui->position_angle->setValue(m_object.pa());
0114     ui->maj->setValue(m_object.a());
0115     ui->min->setValue(m_object.b());
0116     refresh_flux();
0117 }
0118 
0119 void AddCatalogObject::refresh_flux()
0120 {
0121     ui->flux->setEnabled(m_object.type() == SkyObject::RADIO_SOURCE);
0122 
0123     if (!ui->flux->isEnabled())
0124         ui->flux->setValue(0);
0125 }
0126 
0127 void AddCatalogObject::guess_form_contents_from_text()
0128 {
0129     bool accepted = false;
0130     QString text = QInputDialog::getMultiLineText(
0131         this,
0132         i18n("Guess object data from text"),
0133         i18n("Copy-paste a text blurb with data on the object, and KStars will try to guess the contents of the fields from the text. The result is just a guess, so please verify the coordinates and the other information."),
0134         QString(),
0135         &accepted);
0136     if (accepted && !text.isEmpty())
0137     {
0138         guess_form_contents_from_text(text);
0139     }
0140 }
0141 
0142 void AddCatalogObject::guess_form_contents_from_text(QString text)
0143 {
0144     // Parse text to fill in the entries in the form, using regexes to
0145     // guess the field values
0146 
0147     // TODO: Guess type from catalog name if the type match failed
0148 
0149     QRegularExpression matchJ2000Line("^(.*)(?:J2000|ICRS|FK5|\\(2000(?:\\.0)?\\))(.*)$");
0150     matchJ2000Line.setPatternOptions(QRegularExpression::MultilineOption);
0151     QRegularExpression matchCoords("(?:^|[^-\\d])([-+]?\\d\\d?)(?:h ?|d ?|[^\\d]?° ?|:| )(\\d\\d)(?:m ?|\' ?|’ ?|′ "
0152                                    "?|:| )(\\d\\d(?:\\.\\d+)?)?(?:s|\"|\'\'|”|″)?\\b");
0153     QRegularExpression matchCoords2("J?\\d{6,6}[-+]\\d{6,6}");
0154     QRegularExpression findMag1(
0155         "(?:[mM]ag(?:nitudes?)?\\s*(?:\\([vV]\\))?|V(?=\\b))(?:\\s*=|:)?\\s*(-?\\d{1,2}(?:\\.\\d{1,3})?)");
0156     QRegularExpression findMag2("\\b(-?\\d{1,2}\\.\\d{1,3})?\\s*(?:[mM]ag|V|B)\\b");
0157     QRegularExpression findSize1("\\b(\\d{1,3}(?:\\.\\d{1,2})?)\\s*(°|\'|\"|\'\')?\\s*[xX×]\\s*(\\d{1,3}(?:\\.\\d{1,2})"
0158                                  "?)\\s*(°|\'|\"|\'\')?\\b");
0159     QRegularExpression findSize2("\\b(?:[Ss]ize|[Dd]imensions?|[Dd]iameter)[: "
0160                                  "](?:\\([vV]\\))?\\s*(\\d{1,3}(?:\\.\\d{1,2})?)\\s*(°|\'|\"|\'\')?\\b");
0161     QRegularExpression findMajorAxis("\\b[Mm]ajor\\s*[Aa]xis:?\\s*(\\d{1,3}(?:\\.\\d{1,2})?)\\s*(°|\'|\"|\'\')?\\b");
0162     QRegularExpression findMinorAxis("\\b[Mm]inor\\s*[Aa]xis:?\\s*(\\d{1,3}(?:\\.\\d{1,2})?)\\s*(°|\'|\"|\'\')?\\b");
0163     QRegularExpression findPA(
0164         "\\b(?:[Pp]osition *[Aa]ngle|PA|[pP]\\.[aA]\\.):?\\s*(\\d{1,3}(\\.\\d{1,2})?)(?:°|[Ddeg])?\\b");
0165     QRegularExpression findName1(
0166         "\\b(?:(?:[nN]ames?|NAMES?)[: ]|[iI]dent(?:ifier)?:|[dD]esignation:)\\h*\"?([-+\'A-Za-z0-9 ]*)\"?\\b");
0167     QStringList catalogNames;
0168     catalogNames << "NGC"
0169                  << "IC"
0170                  << "M"
0171                  << "PGC"
0172                  << "UGC"
0173                  << "UGCA"
0174                  << "MCG"
0175                  << "ESO"
0176                  << "SDSS"
0177                  << "LEDA"
0178                  << "IRAS"
0179                  << "PNG"
0180                  << "Abell"
0181                  << "ACO"
0182                  << "HCG"
0183                  << "CGCG"
0184                  << "[IV]+ ?Zw"
0185                  << "Hickson"
0186                  << "AGC"
0187                  << "2MASS"
0188                  << "RCS2"
0189                  << "Terzan"
0190                  << "PN [A-Z0-9]"
0191                  << "VV"
0192                  << "PK"
0193                  << "GSC2"
0194                  << "LBN"
0195                  << "LDN"
0196                  << "Caldwell"
0197                  << "HIP"
0198                  << "AM"
0199                  << "vdB"
0200                  << "Barnard"
0201                  << "Shkh?"
0202                  << "KTG"
0203                  << "Palomar"
0204                  << "KPG"
0205                  << "CGPG"
0206                  << "TYC"
0207                  << "Arp"
0208                  << "Minkowski"
0209                  << "KUG"
0210                  << "DDO"
0211         ;
0212     QList<QPair<QString, SkyObject::TYPE>> objectTypes;
0213     objectTypes.append({"[Op]pen ?[Cc]luster|OCL|\\*Cl|Cl\\*|OpC|Cl\\?|Open Cl\\.", SkyObject::OPEN_CLUSTER});
0214     objectTypes.append({"Globular ?Cluster|GlC|GCl|Glob\\. Cl\\.|Globular|Gl\\?", SkyObject::GLOBULAR_CLUSTER});
0215     objectTypes.append({"(?:[Gg]as(?:eous)?|Diff(?:\\.|use)?|Emission|Ref(?:\\.|lection)?) ?[Nn]eb(?:ula|\\.)?|Neb|RfN|HII|GNe", SkyObject::GASEOUS_NEBULA});
0216     objectTypes.append({"PN|PNe|Pl\\.? ?[Nn]eb\\.?|(?:[Pp]re[- ]?)[Pp]lanetary|PPNe|PPN|pA\\*|post[- ]?AGB", SkyObject::PLANETARY_NEBULA});
0217     objectTypes.append({"SNR|[Ss]upernova ?[Rr]em(?:\\.|nant)?|SNRem(?:\\.|nant)?", SkyObject::SUPERNOVA_REMNANT});
0218     objectTypes.append({"Gxy?|HIIG|H2G|[bB]CG|SBG|AGN|EmG|LINER|LIRG|GiG|GinP", SkyObject::GALAXY});
0219     objectTypes.append({"Ast\\.?|Asterism", SkyObject::ASTERISM});
0220     objectTypes.append({"ClG|GrG|CGG|[Gg](?:ala)?xy ?(?:[Gg]roup|[Cc]luster|[Pp]air|[Tt]rio|[Tt]riple)|GClus|GGrp|GGroup|GClstr|GPair|GTrpl|GTrio", SkyObject::GALAXY_CLUSTER});
0221     objectTypes.append({"ISM|DNeb?|[dD](?:k\\.?|ark) ?[Nn]eb(?:ula|\\.)?", SkyObject::DARK_NEBULA});
0222     objectTypes.append({"QSO|[qQ]uasar", SkyObject::QUASAR});
0223     objectTypes.append({"(?:[Dd]ouble|[Dd]bl\\.?|[Tt]riple|[Mm]ult(?:iple|\\.)? ?[Ss]tar)|\\*\\*|Mult\\.? ?\\*", SkyObject::MULT_STAR});
0224     objectTypes.append({"[nN]ebula", SkyObject::GASEOUS_NEBULA}); // Catch all nebula
0225     objectTypes.append({"[gG]alaxy", SkyObject::GALAXY}); // Catch all galaxy
0226 
0227     QRegularExpression findName2("\\b(" + catalogNames.join("|") + ")\\s+(J?[-+0-9\\.]+[A-Da-h]?)\\b");
0228     QRegularExpression findName3("\\b([A-Za-z]+[0-9]?)\\s+(J?[-+0-9]+[A-Da-h]?)\\b");
0229 
0230     // FIXME: This code will clean up by a lot if std::optional<> can be used
0231     QString coordText;
0232     bool coordsFound = false,
0233         magFound = false,
0234         sizeFound = false,
0235         nameFound = false,
0236         positionAngleFound = false,
0237         catalogDetermined = false,
0238         typeFound = false;
0239 
0240     dms RA, Dec;
0241     float mag           = NaN::f;
0242     float majorAxis     = NaN::f;
0243     float minorAxis     = NaN::f;
0244     float positionAngle = 0;
0245     QString name;
0246     QString catalogName;
0247     QString catalogIdentifier;
0248     SkyObject::TYPE type = SkyObject::TYPE_UNKNOWN;
0249 
0250     // Note: The following method is a proxy to support older versions of Qt.
0251     // In Qt 5.5 and above, the QString::indexOf(const QRegularExpression &re, int from, QRegularExpressionMatch *rmatch) method obviates the need for the following.
0252     auto indexOf = [](const QString & s, const QRegularExpression & regExp, int from, QRegularExpressionMatch * m) -> int
0253     {
0254         *m = regExp.match(s, from);
0255         return m->capturedStart(0);
0256     };
0257 
0258     auto countNonOverlappingMatches = [indexOf](const QString & string, const QRegularExpression & regExp,
0259                                       QStringList *list = nullptr) -> int
0260     {
0261         int count           = 0;
0262         int matchIndex      = -1;
0263         int lastMatchLength = 1;
0264         QRegularExpressionMatch rmatch;
0265         while ((matchIndex = indexOf(string, regExp, matchIndex + lastMatchLength, &rmatch)) >= 0)
0266         {
0267             ++count;
0268             lastMatchLength = rmatch.captured(0).length();
0269             if (list)
0270                 list->append(rmatch.captured(0));
0271         }
0272         return count;
0273     };
0274 
0275     QRegularExpressionMatch rmatch;
0276     int nonOverlappingMatchCount;
0277     std::size_t coordTextIndex = 0;
0278     if ((nonOverlappingMatchCount = countNonOverlappingMatches(text, matchCoords)) == 2)
0279     {
0280         coordText = text;
0281     }
0282     else if (nonOverlappingMatchCount > 2)
0283     {
0284         qCDebug(KSTARS) << "Found more than 2 coordinate matches. Trying to match J2000 line.";
0285         if ((coordTextIndex = indexOf(text, matchJ2000Line, 0, &rmatch)) >= 0)
0286         {
0287             coordText = rmatch.captured(1) + rmatch.captured(2);
0288             qCDebug(KSTARS) << "Found a J2000 line match: " << coordText;
0289         }
0290     }
0291 
0292     if (!coordText.isEmpty())
0293     {
0294         int coord1 = indexOf(coordText, matchCoords, 0, &rmatch);
0295         if (coord1 >= 0) {
0296             std::size_t length1 = rmatch.captured(0).length();
0297             RA         = dms(rmatch.captured(1) + ' ' + rmatch.captured(2) + ' ' + rmatch.captured(3), false);
0298             int coord2 = indexOf(coordText, matchCoords, coord1 + length1, &rmatch);
0299             if (coord2 >= 0) {
0300                 Dec = dms(rmatch.captured(1) + ' ' + rmatch.captured(2) + ' ' + rmatch.captured(3), true);
0301                 qCDebug(KSTARS) << "Extracted coordinates: " << RA.toHMSString() << " " << Dec.toDMSString();
0302                 coordsFound = true;
0303 
0304                 // Remove the coordinates from the original string so subsequent tasks don't confuse it
0305                 std::size_t length2 = rmatch.captured(0).length();
0306                 qCDebug(KSTARS) << "Eliminating text: " << text.midRef(coordTextIndex + coord1, length1) << " and " << text.midRef(coordTextIndex + coord2, length2);
0307                 text.replace(coordTextIndex + coord1, length1, "\n");
0308                 text.replace(coordTextIndex + coord2 - length1 + 1, length2, "\n");
0309                 qCDebug(KSTARS) << "Text now: " << text;
0310             }
0311         }
0312     }
0313     else
0314     {
0315         if (text.contains(matchCoords2, &rmatch))
0316         {
0317             QString matchString = rmatch.captured(0);
0318             QRegularExpression extractCoords2("(\\d\\d)(\\d\\d)(\\d\\d)([-+]\\d\\d)(\\d\\d)(\\d\\d)");
0319             Q_ASSERT(matchString.contains(extractCoords2, &rmatch));
0320             RA          = dms(rmatch.captured(1) + ' ' + rmatch.captured(2) + ' ' + rmatch.captured(3), false);
0321             Dec         = dms(rmatch.captured(4) + ' ' + rmatch.captured(5) + ' ' + rmatch.captured(6), true);
0322             coordsFound = true;
0323 
0324             // Remove coordinates to avoid downstream confusion with it
0325             qCDebug(KSTARS) << "Eliminating text: " << text.midRef(rmatch.capturedStart(), rmatch.captured(0).length());
0326             text.replace(rmatch.capturedStart(), rmatch.captured(0).length(), "\n");
0327                 qCDebug(KSTARS) << "Text now: " << text;
0328         }
0329         else
0330         {
0331             QStringList matches;
0332             qCDebug(KSTARS) << "Could not extract RA/Dec. Found " << countNonOverlappingMatches(text, matchCoords, &matches)
0333                      << " coordinate matches:";
0334             qCDebug(KSTARS) << matches;
0335         }
0336     }
0337 
0338     // Type determination: Support full names of types, or SIMBAD/NED shorthands
0339     for (const auto& p : objectTypes)
0340     {
0341         QRegularExpression findType("\\b(?:" + p.first + ")\\b");
0342         if (text.contains(findType, &rmatch)) {
0343             type = p.second;
0344             typeFound = true;
0345             qCDebug(KSTARS) << "Found Type: " << SkyObject::typeName(p.second);
0346             qCDebug(KSTARS) << "Eliminating text: " << text.midRef(rmatch.capturedStart(), rmatch.captured(0).length());
0347             text.replace(rmatch.capturedStart(), rmatch.captured(0).length(), "\n"); // Remove to avoid downstream confusion
0348             qCDebug(KSTARS) << "Text now: " << text;
0349             break;
0350         }
0351     }
0352     if (!typeFound) {
0353         qCDebug(KSTARS) << "Type not found";
0354     }
0355 
0356     nameFound = true;
0357     catalogDetermined = true; // Transition to std::optional with C++17
0358     if (text.contains(findName1, &rmatch)) // Explicit name search
0359     {
0360         qCDebug(KSTARS) << "Found explicit name field: " << rmatch.captured(1) << " in text " << rmatch.captured(0);
0361         name = rmatch.captured(1);
0362         catalogDetermined = false;
0363     }
0364     else if (text.contains(findName2, &rmatch))
0365     {
0366         catalogDetermined = true;
0367         catalogName = rmatch.captured(1);
0368         catalogIdentifier = rmatch.captured(2);
0369         name = catalogName + ' ' + catalogIdentifier;
0370         qCDebug(KSTARS) << "Found known catalog field: " << name
0371                         << " in text " << rmatch.captured(0);
0372     }
0373     else if (text.contains(findName3, &rmatch))
0374     {
0375         // N.B. This case is not strong enough to assume catalog name was found correctly
0376         name = rmatch.captured(1) + ' ' + rmatch.captured(2);
0377         qCDebug(KSTARS) << "Found something that looks like a catalog designation: "
0378                         << name << " in text " << rmatch.captured(0);
0379     }
0380     else
0381     {
0382         qCDebug(KSTARS) << "Could not find name.";
0383         nameFound = false;
0384         catalogDetermined = false;
0385     }
0386 
0387     magFound = true;
0388     if (text.contains(findMag1, &rmatch))
0389     {
0390         qCDebug(KSTARS) << "Found magnitude: " << rmatch.captured(1) << " in text " << rmatch.captured(0);
0391         mag = rmatch.captured(1).toFloat();
0392     }
0393     else if (text.contains(findMag2, &rmatch))
0394     {
0395         qCDebug(KSTARS) << "Found magnitude: " << rmatch.captured(1) << " in text " << rmatch.captured(0);
0396         mag = rmatch.captured(1).toFloat();
0397     }
0398     else
0399     {
0400         qCDebug(KSTARS) << "Could not find magnitude.";
0401         magFound = false;
0402     }
0403 
0404     sizeFound = true;
0405     if (text.contains(findSize1, &rmatch))
0406     {
0407         qCDebug(KSTARS) << "Found size: " << rmatch.captured(1) << " x " << rmatch.captured(3) << " with units "
0408                  << rmatch.captured(4) << " in text " << rmatch.captured(0);
0409         majorAxis = rmatch.captured(1).toFloat();
0410         QString unitText2;
0411         if (rmatch.captured(2).isEmpty())
0412         {
0413             unitText2 = rmatch.captured(4);
0414         }
0415         else
0416         {
0417             unitText2 = rmatch.captured(2);
0418         }
0419 
0420         if (unitText2.contains("°"))
0421             majorAxis *= 60;
0422         else if (unitText2.contains("\"") || unitText2.contains("\'\'"))
0423             majorAxis /= 60;
0424 
0425         minorAxis = rmatch.captured(3).toFloat();
0426         if (rmatch.captured(4).contains("°"))
0427             minorAxis *= 60;
0428         else if (rmatch.captured(4).contains("\"") || rmatch.captured(4).contains("\'\'"))
0429             minorAxis /= 60;
0430         qCDebug(KSTARS) << "Major axis = " << majorAxis << "; minor axis = " << minorAxis << " in arcmin";
0431     }
0432     else if (text.contains(findSize2, &rmatch))
0433     {
0434         majorAxis = rmatch.captured(1).toFloat();
0435         if (rmatch.captured(2).contains("°"))
0436             majorAxis *= 60;
0437         else if (rmatch.captured(2).contains("\"") || rmatch.captured(2).contains("\'\'"))
0438             majorAxis /= 60;
0439         minorAxis = majorAxis;
0440     }
0441     else if (text.contains(findMajorAxis, &rmatch))
0442     {
0443         majorAxis = rmatch.captured(1).toFloat();
0444         if (rmatch.captured(2).contains("°"))
0445             majorAxis *= 60;
0446         else if (rmatch.captured(2).contains("\"") || rmatch.captured(2).contains("\'\'"))
0447             majorAxis /= 60;
0448         minorAxis = majorAxis;
0449         if (text.contains(findMinorAxis, &rmatch))
0450         {
0451             minorAxis = rmatch.captured(1).toFloat();
0452             if (rmatch.captured(2).contains("°"))
0453                 minorAxis *= 60;
0454             else if (rmatch.captured(2).contains("\"") || rmatch.captured(2).contains("\'\'"))
0455                 minorAxis /= 60;
0456         }
0457     }
0458 
0459     else
0460     {
0461         qCDebug(KSTARS)
0462                 << "Could not find size."; // FIXME: Improve to include separate major and minor axis matches, and size matches for round objects.
0463         sizeFound = false;
0464     }
0465 
0466     positionAngleFound = true;
0467     if (text.contains(findPA, &rmatch))
0468     {
0469         qCDebug(KSTARS) << "Found position angle: " << rmatch.captured(1) << " in text " << rmatch.captured(0);
0470         positionAngle = rmatch.captured(1).toFloat();
0471     }
0472     else
0473     {
0474         qCDebug(KSTARS) << "Could not find position angle.";
0475         positionAngleFound = false;
0476     }
0477 
0478     if (typeFound)
0479         ui->type->setCurrentIndex((int)type);
0480     if (nameFound)
0481         ui->name->setText(name);
0482     if (magFound)
0483     {
0484         ui->mag->setValue(mag);
0485         ui->magUnknown->setChecked(false);
0486     } else
0487     {
0488         ui->magUnknown->setChecked(true);
0489     }
0490     if (coordsFound)
0491     {
0492         ui->ra->show(RA);
0493         ui->dec->show(Dec);
0494     }
0495     if (positionAngleFound)
0496         ui->position_angle->setValue(positionAngle);
0497     if (sizeFound)
0498     {
0499         ui->maj->setValue(majorAxis);
0500         ui->min->setValue(minorAxis);
0501     }
0502     if (catalogDetermined)
0503     {
0504         ui->catalog_identifier->setText(catalogIdentifier);
0505     }
0506     refresh_flux();
0507 }