File indexing completed on 2024-04-14 14:11:40

0001 /*
0002     SPDX-FileCopyrightText: 2005 Pablo de Vicente <p.devicente@wanadoo.es>
0003 
0004     SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 
0007 #include "modcalcvlsr.h"
0008 
0009 #include "dms.h"
0010 #include "geolocation.h"
0011 #include "ksnumbers.h"
0012 #include "kstars.h"
0013 #include "ksnotification.h"
0014 #include "kstarsdata.h"
0015 #include "kstarsdatetime.h"
0016 #include "dialogs/locationdialog.h"
0017 #include "dialogs/finddialog.h"
0018 #include "skyobjects/skypoint.h"
0019 #include "widgets/dmsbox.h"
0020 
0021 #include <KLocalizedString>
0022 
0023 #include <QPointer>
0024 #include <QFileDialog>
0025 
0026 modCalcVlsr::modCalcVlsr(QWidget *parentSplit) : QFrame(parentSplit), velocityFlag(0)
0027 {
0028     setupUi(this);
0029     RA->setUnits(dmsBox::HOURS);
0030 
0031     Date->setDateTime(KStarsDateTime::currentDateTime());
0032     initGeo();
0033 
0034     VLSR->setValidator(new QDoubleValidator(VLSR));
0035     VHelio->setValidator(new QDoubleValidator(VHelio));
0036     VGeo->setValidator(new QDoubleValidator(VGeo));
0037     VTopo->setValidator(new QDoubleValidator(VTopo));
0038 
0039     // signals and slots connections
0040     connect(Date, SIGNAL(dateTimeChanged(QDateTime)), this, SLOT(slotCompute()));
0041     connect(NowButton, SIGNAL(clicked()), this, SLOT(slotNow()));
0042     connect(LocationButton, SIGNAL(clicked()), this, SLOT(slotLocation()));
0043     connect(ObjectButton, SIGNAL(clicked()), this, SLOT(slotFindObject()));
0044     connect(RA, SIGNAL(editingFinished()), this, SLOT(slotCompute()));
0045     connect(Dec, SIGNAL(editingFinished()), this, SLOT(slotCompute()));
0046     connect(VLSR, SIGNAL(editingFinished()), this, SLOT(slotCompute()));
0047     connect(VHelio, SIGNAL(editingFinished()), this, SLOT(slotCompute()));
0048     connect(VGeo, SIGNAL(editingFinished()), this, SLOT(slotCompute()));
0049     connect(VTopo, SIGNAL(editingFinished()), this, SLOT(slotCompute()));
0050 
0051     connect(RunButtonBatch, SIGNAL(clicked()), this, SLOT(slotRunBatch()));
0052 
0053     show();
0054 }
0055 
0056 void modCalcVlsr::initGeo(void)
0057 {
0058     geoPlace = KStarsData::Instance()->geo();
0059     LocationButton->setText(geoPlace->fullName());
0060 }
0061 
0062 void modCalcVlsr::slotNow()
0063 {
0064     Date->setDateTime(KStarsDateTime::currentDateTime());
0065     slotCompute();
0066 }
0067 
0068 void modCalcVlsr::slotFindObject()
0069 {
0070     if (FindDialog::Instance()->exec() == QDialog::Accepted)
0071     {
0072         SkyObject *o = FindDialog::Instance()->targetObject();
0073         RA->show(o->ra0());
0074         Dec->show(o->dec0());
0075     }
0076 }
0077 
0078 void modCalcVlsr::slotLocation()
0079 {
0080     QPointer<LocationDialog> ld(new LocationDialog(this));
0081 
0082     if (ld->exec() == QDialog::Accepted && ld)
0083     {
0084         GeoLocation *newGeo = ld->selectedCity();
0085         if (newGeo)
0086         {
0087             geoPlace = newGeo;
0088             LocationButton->setText(geoPlace->fullName());
0089         }
0090     }
0091     delete ld;
0092 
0093     slotCompute();
0094 }
0095 
0096 void modCalcVlsr::slotCompute()
0097 {
0098     bool ok1(false), ok2(false);
0099     SkyPoint sp(RA->createDms(&ok1), Dec->createDms(&ok2));
0100     if (!ok1 || !ok2)
0101         return;
0102 
0103     KStarsDateTime dt(Date->dateTime());
0104     double vst[3];
0105 
0106     geoPlace->TopocentricVelocity(vst, dt.gst());
0107 
0108     if (sender()->objectName() == "VLSR")
0109         velocityFlag = 0;
0110     if (sender()->objectName() == "VHelio")
0111         velocityFlag = 1;
0112     if (sender()->objectName() == "VGeo")
0113         velocityFlag = 2;
0114     if (sender()->objectName() == "VTopo")
0115         velocityFlag = 3;
0116 
0117     switch (velocityFlag)
0118     {
0119         case 0: //Hold VLSR constant, compute the others
0120         {
0121             double vlsr   = VLSR->text().toDouble();
0122             double vhelio = sp.vHeliocentric(vlsr, dt.djd());
0123             double vgeo   = sp.vGeocentric(vhelio, dt.djd());
0124 
0125             VHelio->setText(QString::number(vhelio));
0126             VGeo->setText(QString::number(vgeo));
0127             VTopo->setText(QString::number(sp.vTopocentric(vgeo, vst)));
0128             break;
0129         }
0130 
0131         case 1: //Hold VHelio constant, compute the others
0132         {
0133             double vhelio = VHelio->text().toDouble();
0134             double vlsr   = sp.vHelioToVlsr(vhelio, dt.djd());
0135             double vgeo   = sp.vGeocentric(vhelio, dt.djd());
0136 
0137             VLSR->setText(QString::number(vlsr));
0138             VGeo->setText(QString::number(vgeo));
0139             VTopo->setText(QString::number(sp.vTopocentric(vgeo, vst)));
0140             break;
0141         }
0142 
0143         case 2: //Hold VGeo constant, compute the others
0144         {
0145             double vgeo   = VGeo->text().toDouble();
0146             double vhelio = sp.vGeoToVHelio(vgeo, dt.djd());
0147             double vlsr   = sp.vHelioToVlsr(vhelio, dt.djd());
0148 
0149             VLSR->setText(QString::number(vlsr));
0150             VHelio->setText(QString::number(vhelio));
0151             VTopo->setText(QString::number(sp.vTopocentric(vgeo, vst)));
0152             break;
0153         }
0154 
0155         case 3: //Hold VTopo constant, compute the others
0156         {
0157             double vtopo  = VTopo->text().toDouble();
0158             double vgeo   = sp.vTopoToVGeo(vtopo, vst);
0159             double vhelio = sp.vGeoToVHelio(vgeo, dt.djd());
0160             double vlsr   = sp.vHelioToVlsr(vhelio, dt.djd());
0161 
0162             VLSR->setText(QString::number(vlsr));
0163             VHelio->setText(QString::number(vhelio));
0164             VGeo->setText(QString::number(vgeo));
0165             break;
0166         }
0167 
0168         default: //oops
0169             qDebug() << Q_FUNC_INFO << "Error: do not know which velocity to use for input.";
0170             break;
0171     }
0172 }
0173 
0174 void modCalcVlsr::slotUtChecked()
0175 {
0176     if (UTCheckBatch->isChecked())
0177         UTBoxBatch->setEnabled(false);
0178     else
0179     {
0180         UTBoxBatch->setEnabled(true);
0181     }
0182 }
0183 
0184 void modCalcVlsr::slotDateChecked()
0185 {
0186     if (DateCheckBatch->isChecked())
0187         DateBoxBatch->setEnabled(false);
0188     else
0189     {
0190         DateBoxBatch->setEnabled(true);
0191     }
0192 }
0193 
0194 void modCalcVlsr::slotRaChecked()
0195 {
0196     if (RACheckBatch->isChecked())
0197     {
0198         RABoxBatch->setEnabled(false);
0199     }
0200     else
0201     {
0202         RABoxBatch->setEnabled(true);
0203     }
0204 }
0205 
0206 void modCalcVlsr::slotDecChecked()
0207 {
0208     if (DecCheckBatch->isChecked())
0209     {
0210         DecBoxBatch->setEnabled(false);
0211     }
0212     else
0213     {
0214         DecBoxBatch->setEnabled(true);
0215     }
0216 }
0217 
0218 void modCalcVlsr::slotEpochChecked()
0219 {
0220     if (EpochCheckBatch->isChecked())
0221         EpochBoxBatch->setEnabled(false);
0222     else
0223         EpochBoxBatch->setEnabled(true);
0224 }
0225 
0226 void modCalcVlsr::slotLongChecked()
0227 {
0228     if (LongCheckBatch->isChecked())
0229         LongitudeBoxBatch->setEnabled(false);
0230     else
0231         LongitudeBoxBatch->setEnabled(true);
0232 }
0233 
0234 void modCalcVlsr::slotLatChecked()
0235 {
0236     if (LatCheckBatch->isChecked())
0237         LatitudeBoxBatch->setEnabled(false);
0238     else
0239     {
0240         LatitudeBoxBatch->setEnabled(true);
0241     }
0242 }
0243 
0244 void modCalcVlsr::slotHeightChecked()
0245 {
0246     if (ElevationCheckBatch->isChecked())
0247         ElevationBoxBatch->setEnabled(false);
0248     else
0249     {
0250         ElevationBoxBatch->setEnabled(true);
0251     }
0252 }
0253 
0254 void modCalcVlsr::slotVlsrChecked()
0255 {
0256     if (InputVelocityCheckBatch->isChecked())
0257         InputVelocityBoxBatch->setEnabled(false);
0258     else
0259     {
0260         InputVelocityBoxBatch->setEnabled(true);
0261     }
0262 }
0263 
0264 void modCalcVlsr::slotInputFile()
0265 {
0266     const QString inputFileName = QFileDialog::getOpenFileName(KStars::Instance(), QString(), QString());
0267     if (!inputFileName.isEmpty())
0268         InputFileBoxBatch->setUrl(QUrl::fromLocalFile(inputFileName));
0269 }
0270 
0271 void modCalcVlsr::slotOutputFile()
0272 {
0273     const QString outputFileName = QFileDialog::getSaveFileName();
0274     if (!outputFileName.isEmpty())
0275         OutputFileBoxBatch->setUrl(QUrl::fromLocalFile(outputFileName));
0276 }
0277 
0278 void modCalcVlsr::slotRunBatch()
0279 {
0280     const QString inputFileName = InputFileBoxBatch->url().toLocalFile();
0281 
0282     // We open the input file and read its content
0283 
0284     if (QFile::exists(inputFileName))
0285     {
0286         QFile f(inputFileName);
0287         if (!f.open(QIODevice::ReadOnly))
0288         {
0289             KSNotification::sorry(i18n("Could not open file %1.", f.fileName()), i18n("Could Not Open File"));
0290             return;
0291         }
0292 
0293         //      processLines(&f);
0294         QTextStream istream(&f);
0295         processLines(istream);
0296         //      readFile( istream );
0297         f.close();
0298     }
0299     else
0300     {
0301         KSNotification::sorry(i18n("Invalid file: %1", inputFileName), i18n("Invalid file"));
0302         InputFileBoxBatch->setUrl(QUrl());
0303     }
0304 }
0305 
0306 void modCalcVlsr::processLines(QTextStream &istream)
0307 {
0308     // we open the output file
0309 
0310     //  QTextStream istream(&fIn);
0311     QString outputFileName;
0312     outputFileName = OutputFileBoxBatch->url().toLocalFile();
0313     QFile fOut(outputFileName);
0314     fOut.open(QIODevice::WriteOnly);
0315     QTextStream ostream(&fOut);
0316 
0317     QString line;
0318     QChar space = ' ';
0319     int i       = 0;
0320     long double jd0;
0321     SkyPoint spB;
0322     double sra, cra, sdc, cdc;
0323     dms raB, decB, latB, longB;
0324     QString epoch0B;
0325     double vhB, vgB, vtB, vlsrB, heightB;
0326     double vtopo[3];
0327     QTime utB;
0328     QDate dtB;
0329     KStarsDateTime dt0B;
0330 
0331     while (!istream.atEnd())
0332     {
0333         line = istream.readLine();
0334         line = line.trimmed();
0335 
0336         //Go through the line, looking for parameters
0337 
0338         QStringList fields = line.split(' ');
0339 
0340         i = 0;
0341 
0342         // Read Ut and write in ostream if corresponds
0343 
0344         if (UTCheckBatch->isChecked())
0345         {
0346             utB = QTime::fromString(fields[i]);
0347             i++;
0348         }
0349         else
0350             utB = UTBoxBatch->time();
0351 
0352         if (AllRadioBatch->isChecked())
0353             ostream << QLocale().toString(utB) << space;
0354         else if (UTCheckBatch->isChecked())
0355             ostream << QLocale().toString(utB) << space;
0356 
0357         // Read date and write in ostream if corresponds
0358 
0359         if (DateCheckBatch->isChecked())
0360         {
0361             dtB = QDate::fromString(fields[i]);
0362             i++;
0363         }
0364         else
0365             dtB = DateBoxBatch->date();
0366         if (AllRadioBatch->isChecked())
0367             ostream << QLocale().toString(dtB, QLocale::LongFormat).append(space);
0368         else if (DateCheckBatch->isChecked())
0369             ostream << QLocale().toString(dtB, QLocale::LongFormat).append(space);
0370 
0371         // Read RA and write in ostream if corresponds
0372 
0373         if (RACheckBatch->isChecked())
0374         {
0375             raB = dms::fromString(fields[i], false);
0376             i++;
0377         }
0378         else
0379             raB = RABoxBatch->createDms();
0380 
0381         if (AllRadioBatch->isChecked())
0382             ostream << raB.toHMSString() << space;
0383         else if (RACheckBatch->isChecked())
0384             ostream << raB.toHMSString() << space;
0385 
0386         // Read DEC and write in ostream if corresponds
0387 
0388         if (DecCheckBatch->isChecked())
0389         {
0390             decB = dms::fromString(fields[i], true);
0391             i++;
0392         }
0393         else
0394             decB = DecBoxBatch->createDms();
0395 
0396         if (AllRadioBatch->isChecked())
0397             ostream << decB.toDMSString() << space;
0398         else if (DecCheckBatch->isChecked())
0399             ostream << decB.toDMSString() << space;
0400 
0401         // Read Epoch and write in ostream if corresponds
0402 
0403         if (EpochCheckBatch->isChecked())
0404         {
0405             epoch0B = fields[i];
0406             i++;
0407         }
0408         else
0409             epoch0B = EpochBoxBatch->text();
0410 
0411         if (AllRadioBatch->isChecked())
0412             ostream << epoch0B << space;
0413         else if (EpochCheckBatch->isChecked())
0414             ostream << epoch0B << space;
0415 
0416         // Read vlsr and write in ostream if corresponds
0417 
0418         if (InputVelocityCheckBatch->isChecked())
0419         {
0420             vlsrB = fields[i].toDouble();
0421             i++;
0422         }
0423         else
0424             vlsrB = InputVelocityComboBatch->currentText().toDouble();
0425 
0426         if (AllRadioBatch->isChecked())
0427             ostream << vlsrB << space;
0428         else if (InputVelocityCheckBatch->isChecked())
0429             ostream << vlsrB << space;
0430 
0431         // Read Longitude and write in ostream if corresponds
0432 
0433         if (LongCheckBatch->isChecked())
0434         {
0435             longB = dms::fromString(fields[i], true);
0436             i++;
0437         }
0438         else
0439             longB = LongitudeBoxBatch->createDms();
0440 
0441         if (AllRadioBatch->isChecked())
0442             ostream << longB.toDMSString() << space;
0443         else if (LongCheckBatch->isChecked())
0444             ostream << longB.toDMSString() << space;
0445 
0446         // Read Latitude
0447 
0448         if (LatCheckBatch->isChecked())
0449         {
0450             latB = dms::fromString(fields[i], true);
0451             i++;
0452         }
0453         else
0454             latB = LatitudeBoxBatch->createDms();
0455         if (AllRadioBatch->isChecked())
0456             ostream << latB.toDMSString() << space;
0457         else if (LatCheckBatch->isChecked())
0458             ostream << latB.toDMSString() << space;
0459 
0460         // Read height and write in ostream if corresponds
0461 
0462         if (ElevationCheckBatch->isChecked())
0463         {
0464             heightB = fields[i].toDouble();
0465             i++;
0466         }
0467         else
0468             heightB = ElevationBoxBatch->text().toDouble();
0469 
0470         if (AllRadioBatch->isChecked())
0471             ostream << heightB << space;
0472         else if (ElevationCheckBatch->isChecked())
0473             ostream << heightB << space;
0474 
0475         // We make the first calculations
0476 
0477         spB = SkyPoint(raB, decB);
0478         dt0B.setFromEpoch(epoch0B);
0479         vhB = spB.vHeliocentric(vlsrB, dt0B.djd());
0480         jd0 = KStarsDateTime(dtB, utB).djd();
0481         vgB = spB.vGeocentric(vlsrB, jd0);
0482         geoPlace->setLong(longB);
0483         geoPlace->setLat(latB);
0484         geoPlace->setElevation(heightB);
0485         dms gsidt = KStarsDateTime(dtB, utB).gst();
0486         geoPlace->TopocentricVelocity(vtopo, gsidt);
0487         spB.ra().SinCos(sra, cra);
0488         spB.dec().SinCos(sdc, cdc);
0489         vtB = vgB - (vtopo[0] * cdc * cra + vtopo[1] * cdc * sra + vtopo[2] * sdc);
0490 
0491         ostream << vhB << space << vgB << space << vtB << '\n';
0492     }
0493 
0494     fOut.close();
0495 }