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 }