summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJasem Mutlaq <mutlaqja@ikarustech.com>2016-09-05 22:08:44 (GMT)
committerJasem Mutlaq <mutlaqja@ikarustech.com>2016-09-05 22:08:44 (GMT)
commit38e52bb4d5e57c7d438537931d6052cceaab2029 (patch)
tree7cdfda8bf437e88e7f24ec786f98fbdbc34a7361
parent842b5341cc5a1877f696e72559f12a89b539f006 (diff)
+ Dark Library working in capture module.
+ Fix issues with setting FITS dir + Fix issue with Preview tab title being hidden after a capture when the previous capture is a batch image. + Autostretch only runs on FITS_NONE images. + Remove useless and broken gamma slider. + White space cleanups.
-rw-r--r--kstars/auxiliary/ksuserdb.cpp10
-rw-r--r--kstars/dialogs/fovdialog.cpp2
-rw-r--r--kstars/ekos/capture.cpp63
-rw-r--r--kstars/ekos/capture.h8
-rw-r--r--kstars/ekos/darklibrary.cpp212
-rw-r--r--kstars/ekos/darklibrary.h30
-rw-r--r--kstars/ekos/ekosmanager.cpp2
-rw-r--r--kstars/ekos/focus.cpp8
-rw-r--r--kstars/ekos/opsekos.ui39
-rw-r--r--kstars/fitsviewer/fitscommon.h2
-rw-r--r--kstars/fitsviewer/fitsdata.h3
-rw-r--r--kstars/fitsviewer/fitshistogram.cpp4
-rw-r--r--kstars/fitsviewer/fitstab.cpp1
-rw-r--r--kstars/fitsviewer/fitsview.cpp61
-rw-r--r--kstars/fitsviewer/fitsview.h5
-rw-r--r--kstars/fitsviewer/fitsviewer.cpp26
-rw-r--r--kstars/fitsviewer/fitsviewer.h2
-rw-r--r--kstars/indi/indiccd.cpp8
-rw-r--r--kstars/indi/indiccd.h2
-rw-r--r--kstars/kstars.kcfg4
20 files changed, 336 insertions, 156 deletions
diff --git a/kstars/auxiliary/ksuserdb.cpp b/kstars/auxiliary/ksuserdb.cpp
index 54666b0..662ea8d 100644
--- a/kstars/auxiliary/ksuserdb.cpp
+++ b/kstars/auxiliary/ksuserdb.cpp
@@ -883,7 +883,7 @@ bool KSUserDB::ImportUsers() {
}
}
}
- }
+ }
delete reader_;
usersfile.close();
return true;
@@ -1015,7 +1015,7 @@ void KSUserDB::readScope() {
driver = reader_->readElementText();
}
}
-
+
AddScope(model, vendor, driver, type, focalLength, aperture);
}
@@ -1040,7 +1040,7 @@ void KSUserDB::readEyepiece() {
}
}
}
-
+
AddEyepiece(vendor, model, focalLength.toDouble(), fov.toDouble(), fovUnit);
}
@@ -1062,7 +1062,7 @@ void KSUserDB::readLens() {
}
}
}
-
+
AddLens(vendor, model, factor.toDouble());
}
@@ -1185,7 +1185,7 @@ void KSUserDB::AddHorizon(ArtificialHorizonEntity *horizon)
QSqlQuery query(userdb_);
query.exec(tableQuery);
- QSqlTableModel points(0, userdb_);
+ QSqlTableModel points(0, userdb_);
points.setTable(tableName);
diff --git a/kstars/dialogs/fovdialog.cpp b/kstars/dialogs/fovdialog.cpp
index 385c5e0..b402b4d 100644
--- a/kstars/dialogs/fovdialog.cpp
+++ b/kstars/dialogs/fovdialog.cpp
@@ -269,7 +269,7 @@ void NewFOV::slotUpdateFOV() {
f.setColor( ui->ColorButton->color().name() );
okB->setEnabled(!f.name().isEmpty() && okX && okY );
-
+
ui->ViewBox->setFOV( &f );
ui->ViewBox->update();
}
diff --git a/kstars/ekos/capture.cpp b/kstars/ekos/capture.cpp
index cd885c5..1f6295d 100644
--- a/kstars/ekos/capture.cpp
+++ b/kstars/ekos/capture.cpp
@@ -845,53 +845,44 @@ void Capture::newFITS(IBLOB *bp)
return;
disconnect(currentCCD, SIGNAL(BLOBUpdated(IBLOB*)), this, SLOT(newFITS(IBLOB*)));
- disconnect(currentCCD, SIGNAL(newImage(QImage*, ISD::CCDChip*)), this, SLOT(sendNewImage(QImage*, ISD::CCDChip*)));
+ disconnect(currentCCD, SIGNAL(newImage(QImage*, ISD::CCDChip*)), this, SLOT(sendNewImage(QImage*, ISD::CCDChip*)));
- // TODO implement this tomorrow
- /*
if (useGuideHead == false && darkSubCheck->isChecked() && activeJob->isPreview())
{
FITSView *currentImage = targetChip->getImage(FITS_NORMAL);
+ FITSData *darkData = NULL;
- if (DarkLibrary::Instance()->hasDarkFrame(targetChip))
- DarkLibrary::Instance()->subtract(targetChip, currentImage);
- else
- {
+ darkData = DarkLibrary::Instance()->getDarkFrame(targetChip, activeJob->getExposure());
- connect(DarkLibrary::Instance(), SIGNAL(darkFrameSubtracted()), this, SLOT(setCaptureComplete()));
- DarkLibrary::Instance()->captureAndSubtract(targetChip, currentImage);
- }
+ connect(DarkLibrary::Instance(), SIGNAL(darkFrameCompleted(bool)), this, SLOT(setDarkCaptureComplete(bool)));
+ connect(DarkLibrary::Instance(), SIGNAL(newLog(QString)), this, SLOT(appendLogText(QString)));
- }*/
+ if (darkData)
+ DarkLibrary::Instance()->subtract(darkData, currentImage, activeJob->getSubX(), activeJob->getSubY());
+ else
+ DarkLibrary::Instance()->captureAndSubtract(targetChip, activeJob->getExposure(), activeJob->getSubX(), activeJob->getSubY(), currentImage);
- /*if (calibrationState == CALIBRATE_START)
- {
- calibrationState = CALIBRATE_DONE;
- startNextExposure();
return;
}
+ }
- if (darkSubCheck->isChecked() && calibrationState == CALIBRATE_DONE)
- {
- calibrationState = CALIBRATE_NONE;
-
- FITSView *calibrateImage = targetChip->getImage(FITS_CALIBRATE);
- FITSView *currentImage = targetChip->getImage(FITS_NORMAL);
-
- FITSData *image_data = NULL;
+ setCaptureComplete();
- if (currentImage)
- image_data = currentImage->getImageData();
+}
- if (image_data && calibrateImage && currentImage)
- image_data->subtract(calibrateImage->getImageData()->getImageBuffer());
- }*/
- }
+void Capture::setDarkCaptureComplete(bool result)
+{
+ if (result == false)
+ appendLogText(i18n("Dark frame processing failed."));
- //TODO Move this to setCaptureComplete() function
+ setCaptureComplete();
+}
+void Capture::setCaptureComplete()
+{
disconnect(currentCCD, SIGNAL(newExposureValue(ISD::CCDChip*,double,IPState)), this, SLOT(updateCaptureProgress(ISD::CCDChip*,double,IPState)));
- secondsLabel->setText(i18n("Complete."));
+ DarkLibrary::Instance()->disconnect(this);
+ secondsLabel->setText(i18n("Complete."));
// If it was initially set as preview job
if (seqTotalCount <= 0)
@@ -1327,7 +1318,7 @@ void Capture::updateCaptureProgress(ISD::CCDChip * tChip, double value, IPState
}
void Capture::updateCCDTemperature(double value)
-{
+{
if (temperatureCheck->isEnabled() == false)
checkCCD();
@@ -1382,7 +1373,7 @@ void Capture::addJob(bool preview)
job->setWallCoord(wallCoord);
job->setTargetADU(targetADU);
- imagePrefix = prefixIN->text();
+ imagePrefix = prefixIN->text();
constructPrefix(imagePrefix);
@@ -1429,7 +1420,7 @@ void Capture::addJob(bool preview)
{
currentRow = queueTable->rowCount();
- queueTable->insertRow(currentRow);
+ queueTable->insertRow(currentRow);
}
else
currentRow = queueTable->currentRow();
@@ -2484,9 +2475,7 @@ void Capture::syncGUIToJob(SequenceJob *job)
preMountPark = job->isPreMountPark();
preDomePark = job->isPreDomePark();
- QString rootDir = job->getRootFITSDir();
- rootDir = rootDir.remove(QString("/%1").arg(frameTypeCombo->currentText()));
- fitsDir->setText(rootDir);
+ fitsDir->setText(job->getRootFITSDir());
if (ISOCombo->isEnabled())
ISOCombo->setCurrentIndex(job->getISOIndex());
diff --git a/kstars/ekos/capture.h b/kstars/ekos/capture.h
index 34718a4..7b6cd68 100644
--- a/kstars/ekos/capture.h
+++ b/kstars/ekos/capture.h
@@ -251,7 +251,6 @@ public:
void syncTelescopeInfo();
void syncFilterInfo();
- void appendLogText(const QString &);
void clearLog();
QString getLogText() { return logText.join("\n"); }
@@ -379,6 +378,8 @@ public slots:
*/
void setTemperature();
+ void appendLogText(const QString &);
+
private slots:
/**
@@ -393,7 +394,6 @@ private slots:
void saveFITSDirectory();
void setDefaultCCD(QString ccd);
void setNewRemoteFile(QString file);
-
void setGuideChip(ISD::CCDChip* chip) { guideChip = chip; }
// Sequence Queue
@@ -425,6 +425,10 @@ private slots:
// Send image info
void sendNewImage(QImage *image, ISD::CCDChip *myChip);
+ // Capture
+ void setDarkCaptureComplete(bool result);
+ void setCaptureComplete();
+
// Temporary for post capture script
void postScriptFinished(int exitCode);
diff --git a/kstars/ekos/darklibrary.cpp b/kstars/ekos/darklibrary.cpp
index df5ad43..4b9dd8f 100644
--- a/kstars/ekos/darklibrary.cpp
+++ b/kstars/ekos/darklibrary.cpp
@@ -7,11 +7,16 @@
version 2 of the License, or (at your option) any later version.
*/
+#include <QVariantMap>
+
#include "darklibrary.h"
#include "Options.h"
#include "kstars.h"
+#include "kspaths.h"
#include "kstarsdata.h"
+#include "fitsviewer/fitsview.h"
+#include "fitsviewer/fitsdata.h"
#include "auxiliary/ksuserdb.h"
namespace Ekos
@@ -29,26 +34,217 @@ DarkLibrary * DarkLibrary::Instance()
DarkLibrary::DarkLibrary(QObject *parent) : QObject(parent)
{
- //if ccd TEXT NOT NULL, chip INTEGER DEFAULT 0, binX INTEGER, binY INTEGER, temperature REAL, duration REAL, filename TEXT NOT NULL, timestamp DATETIME DEFAULT CURRENT_TIMESTAMP)"))
+ KStarsData::Instance()->userdb()->GetAllDarkFrames(darkFrames);
- //KStarsData::Instance()->userdb()->AddDarkFrame(test);
- /*KStarsData::Instance()->userdb()->DeleteDarkFrame("/home/jasem/foo.fits");
+ subtractParams.duration=0;
+ subtractParams.offsetX=0;
+ subtractParams.offsetY=0;
+ subtractParams.targetChip=0;
+ subtractParams.targetImage=0;
- KStarsData::Instance()->userdb()->GetAllDarkFrames(darkFrames);
+ QDir writableDir;
+ writableDir.mkdir(KSPaths::writableLocation(QStandardPaths::GenericDataLocation) + "darks");
+}
+
+DarkLibrary::~DarkLibrary()
+{
+ qDeleteAll(darkFiles);
+}
+FITSData * DarkLibrary::getDarkFrame(ISD::CCDChip *targetChip, double duration)
+{
foreach(QVariantMap map, darkFrames)
{
- for(QVariantMap::const_iterator iter = map.begin(); iter != map.end(); ++iter)
- qDebug() << iter.key() << " --> " << iter.value();
- }*/
+ // First check CCD name matches
+ if (map["ccd"].toString() == targetChip->getCCD()->getDeviceName())
+ {
+ // Then check we are on the correct chip
+ if (map["chip"].toInt() == static_cast<int>(targetChip->getType()))
+ {
+ int binX, binY;
+ targetChip->getBinning(&binX, &binY);
+
+ // Then check if binning is the same
+ if (map["binX"].toInt() == binX && map["binY"].toInt() == binY)
+ {
+ // Then check for temperature
+ if (targetChip->getCCD()->hasCooler())
+ {
+ double temperature=0;
+ targetChip->getCCD()->getTemperature(&temperature);
+ // TODO make this configurable value, the threshold
+ if (fabs(map["temperature"].toDouble()-temperature) > 0.1)
+ continue;
+ }
+
+ // Then check for duration
+ // TODO make this value configurable
+ if (fabs(map["duration"].toDouble() - duration) > 0.05)
+ continue;
+
+ // Finaly check if the duration is acceptable
+ QDateTime frameTime = QDateTime::fromString(map["timestamp"].toString(), Qt::ISODate);
+ if (frameTime.daysTo(QDateTime::currentDateTime()) > Options::darkLibraryDuration())
+ continue;
+
+ QString filename = map["filename"].toString();
+
+ if (darkFiles.contains(filename))
+ return darkFiles[filename];
+
+ // Finally we made it, let's put it in the hash
+ bool rc = loadDarkFile(filename);
+ if (rc)
+ return darkFiles[filename];
+ else
+ return NULL;
+ }
+ }
+ }
+ }
+
+ return NULL;
+}
+
+bool DarkLibrary::loadDarkFile(const QString &filename)
+{
+ FITSData *darkData = new FITSData();
+ bool rc = darkData->loadFITS(filename);
+ if (rc)
+ darkFiles[filename] = darkData;
+ else
+ {
+ emit newLog(i18n("Failed to load dark frame file %1", filename));
+ delete (darkData);
+ }
+
+ return rc;
}
-DarkLibrary::~DarkLibrary()
+bool DarkLibrary::saveDarkFile(FITSData *darkData)
+{
+ QDateTime ts = QDateTime::currentDateTime();
+
+ QString path = KSPaths::writableLocation(QStandardPaths::GenericDataLocation) + "darks/darkframe_" + ts.toString(Qt::ISODate) + ".fits";
+
+ if (darkData->saveFITS(path) != 0)
+ return false;
+
+ darkFiles[path] = darkData;
+
+ QVariantMap map;
+ int binX, binY;
+ double temperature=0;
+
+ subtractParams.targetChip->getBinning(&binX, &binY);
+ subtractParams.targetChip->getCCD()->getTemperature(&temperature);
+
+ map["ccd"] = subtractParams.targetChip->getCCD()->getDeviceName();
+ map["chip"] = static_cast<int>(subtractParams.targetChip->getType());
+ map["binX"] = binX;
+ map["binY"] = binY;
+ map["temperature"] = temperature;
+ map["duration"] = subtractParams.duration;
+ map["filename"] = path;
+
+ darkFrames.append(map);
+
+ emit newLog(i18n("Dark frame saved to %1", path));
+
+ KStarsData::Instance()->userdb()->AddDarkFrame(map);
+
+ return true;
+}
+
+bool DarkLibrary::subtract(FITSData *darkData, FITSView *lightImage, uint16_t offsetX, uint16_t offsetY)
+{
+ Q_ASSERT(darkData);
+ Q_ASSERT(lightImage);
+
+ FITSData *lightData = lightImage->getImageData();
+
+ float *darkBuffer = darkData->getImageBuffer();
+ float *lightBuffer = lightData->getImageBuffer();
+
+ int darkoffset = offsetX + offsetY * darkData->getWidth();
+ int darkW = darkData->getWidth();
+
+ int lightOffset = 0;
+ int lightW = lightData->getWidth();
+ int lightH = lightData->getHeight();
+
+ for (int i=0; i < lightH; i++)
+ {
+ for (int j=0; j < lightW; j++)
+ {
+ lightBuffer[j+lightOffset] -= darkBuffer[j+darkoffset];
+ if (lightBuffer[j+lightOffset] < 0)
+ lightBuffer[j+lightOffset] = 0;
+ }
+
+ lightOffset += lightW;
+ darkoffset += darkW;
+ }
+
+ lightImage->rescale(ZOOM_KEEP_LEVEL);
+ lightImage->updateFrame();
+
+ emit darkFrameCompleted(true);
+
+ return true;
+}
+
+void DarkLibrary::captureAndSubtract(ISD::CCDChip *targetChip, double duration, uint16_t offsetX, uint16_t offsetY, FITSView*targetImage)
{
+ targetChip->resetFrame();
+ targetChip->setCaptureMode(FITS_CALIBRATE);
+ targetChip->setFrameType(FRAME_DARK);
+
+ subtractParams.targetChip = targetChip;
+ subtractParams.duration = duration;
+ subtractParams.offsetX = offsetX;
+ subtractParams.offsetY = offsetY;
+ subtractParams.targetImage= targetImage;
+
+ connect(targetChip->getCCD(), SIGNAL(BLOBUpdated(IBLOB*)), this, SLOT(newFITS(IBLOB*)));
+
+ emit newLog(i18n("Capturing dark frame..."));
+
+ targetChip->capture(duration);
}
+
+void DarkLibrary::newFITS(IBLOB *bp)
+{
+ INDI_UNUSED(bp);
+
+ Q_ASSERT(subtractParams.targetChip);
+
+ disconnect(subtractParams.targetChip->getCCD(), SIGNAL(BLOBUpdated(IBLOB*)), this, SLOT(newFITS(IBLOB*)));
+
+ FITSView *calibrationView = subtractParams.targetChip->getImage(FITS_CALIBRATE);
+
+ emit newLog(i18n("Dark frame received."));
+
+ FITSData *calibrationData = new FITSData();
+
+ // Deep copy of the data
+ if (calibrationData->loadFITS(calibrationView->getImageData()->getFilename()))
+ {
+ saveDarkFile(calibrationData);
+ subtract(calibrationData, subtractParams.targetImage, subtractParams.offsetX, subtractParams.offsetY);
+ }
+ else
+ {
+ emit darkFrameCompleted(false);
+ emit newLog(i18n("Warning: Cannot load calibration file %1", calibrationView->getImageData()->getFilename()));
+ }
}
+}
+
+
+
diff --git a/kstars/ekos/darklibrary.h b/kstars/ekos/darklibrary.h
index 67504a9..4409579 100644
--- a/kstars/ekos/darklibrary.h
+++ b/kstars/ekos/darklibrary.h
@@ -11,6 +11,7 @@
#define DARKLIBRARY_H
#include <QObject>
+#include "indi/indiccd.h"
namespace Ekos
{
@@ -31,12 +32,41 @@ public:
static DarkLibrary *Instance();
+ FITSData * getDarkFrame(ISD::CCDChip *targetChip, double duration);
+ bool subtract(FITSData *darkData, FITSView *lightImage, uint16_t offsetX, uint16_t offsetY);
+ void captureAndSubtract(ISD::CCDChip *targetChip, double duration, uint16_t offsetX, uint16_t offsetY, FITSView*targetImage);
+
+signals:
+ void darkFrameCompleted(bool);
+ void newLog(const QString &message);
+
+public slots:
+ /**
+ * @brief newFITS A new FITS blob is received by the CCD driver.
+ * @param bp pointer to blob data
+ */
+ void newFITS(IBLOB *bp);
+
private:
DarkLibrary(QObject *parent);
~DarkLibrary();
static DarkLibrary * _DarkLibrary;
+ bool loadDarkFile(const QString &filename);
+ bool saveDarkFile(FITSData *darkData);
+
QList<QVariantMap> darkFrames;
+ QHash<QString, FITSData *> darkFiles;
+
+ struct
+ {
+ ISD::CCDChip *targetChip;
+ double duration;
+ uint16_t offsetX;
+ uint16_t offsetY;
+ FITSView *targetImage;
+ } subtractParams;
+
};
diff --git a/kstars/ekos/ekosmanager.cpp b/kstars/ekos/ekosmanager.cpp
index 7bed361..5a116b4 100644
--- a/kstars/ekos/ekosmanager.cpp
+++ b/kstars/ekos/ekosmanager.cpp
@@ -1892,7 +1892,7 @@ void EkosManager::updateFocusStatus(Ekos::FocusState status)
focusStatus->setText(Ekos::getFocusStatusString(status));
if (status >= Ekos::FOCUS_PROGRESS)
- {
+ {
if (focusPI->isAnimated() == false)
focusPI->startAnimation();
}
diff --git a/kstars/ekos/focus.cpp b/kstars/ekos/focus.cpp
index df95efa..9e59765 100644
--- a/kstars/ekos/focus.cpp
+++ b/kstars/ekos/focus.cpp
@@ -857,7 +857,7 @@ void Focus::capture()
if (ISOCombo->isEnabled() && ISOCombo->currentIndex() != -1 && targetChip->getISOIndex() != ISOCombo->currentIndex())
targetChip->setISOIndex(ISOCombo->currentIndex());
- connect(currentCCD, SIGNAL(BLOBUpdated(IBLOB*)), this, SLOT(newFITS(IBLOB*)));
+ connect(currentCCD, SIGNAL(BLOBUpdated(IBLOB*)), this, SLOT(newFITS(IBLOB*)));
targetChip->setFrameType(ccdFrame);
@@ -1065,7 +1065,7 @@ void Focus::newFITS(IBLOB *bp)
currentCCD->setUploadMode(rememberUploadMode);
}
- captureInProgress = false;
+ captureInProgress = false;
FITSData *image_data = targetChip->getImageData();
@@ -1273,7 +1273,7 @@ void Focus::newFITS(IBLOB *bp)
appendLogText(i18n("Capture complete. Select a star to focus."));
//if (fw == 0 || fh == 0)
- //targetChip->getFrame(&fx, &fy, &fw, &fh);
+ //targetChip->getFrame(&fx, &fy, &fw, &fh);
int subBinX=1,subBinY=1;
targetChip->getBinning(&subBinX, &subBinY);
@@ -2131,7 +2131,7 @@ void Focus::focusStarSelected(int x, int y)
QRect starRect;
if (subFramed == false && kcfg_subFrame->isChecked() && targetChip->canSubframe())
- {
+ {
int minX, maxX, minY, maxY, minW, maxW, minH, maxH;//, fx,fy,fw,fh;
targetChip->getFrameMinMax(&minX, &maxX, &minY, &maxY, &minW, &maxW, &minH, &maxH);
diff --git a/kstars/ekos/opsekos.ui b/kstars/ekos/opsekos.ui
index e27aeac..2c1130c 100644
--- a/kstars/ekos/opsekos.ui
+++ b/kstars/ekos/opsekos.ui
@@ -7,7 +7,7 @@
<x>0</x>
<y>0</y>
<width>502</width>
- <height>470</height>
+ <height>488</height>
</rect>
</property>
<property name="windowTitle">
@@ -231,6 +231,43 @@
</layout>
</item>
<item>
+ <layout class="QHBoxLayout" name="horizontalLayout_12">
+ <item>
+ <widget class="QLabel" name="label_6">
+ <property name="toolTip">
+ <string>Reuse dark frames from the dark library for this many days. If exceeded, a new dark frame shall be captured and stored for future use.</string>
+ </property>
+ <property name="text">
+ <string>Dark Library</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QSpinBox" name="kcfg_DarkLibraryDuration">
+ <property name="maximum">
+ <number>365</number>
+ </property>
+ <property name="singleStep">
+ <number>10</number>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer_3">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ <item>
<widget class="QCheckBox" name="kcfg_AutoFocusOnFilterChange">
<property name="toolTip">
<string>Perform Autofocus when changing filter wheels during exposure sequence.</string>
diff --git a/kstars/fitsviewer/fitscommon.h b/kstars/fitsviewer/fitscommon.h
index f56a2ee..30b41eb 100644
--- a/kstars/fitsviewer/fitscommon.h
+++ b/kstars/fitsviewer/fitscommon.h
@@ -18,7 +18,7 @@
#define FITSCOMMON_H
typedef enum { FITS_NORMAL, FITS_FOCUS, FITS_GUIDE, FITS_CALIBRATE, FITS_WCSM } FITSMode;
-typedef enum { FITS_WCS, FITS_VALUE, FITS_POSITION, FITS_ZOOM , FITS_RESOLUTION, FITS_GAMMA, FITS_LED, FITS_MESSAGE } FITSBar;
+typedef enum { FITS_WCS, FITS_VALUE, FITS_POSITION, FITS_ZOOM , FITS_RESOLUTION, FITS_LED, FITS_MESSAGE } FITSBar;
typedef enum { FITS_NONE, FITS_AUTO_STRETCH, FITS_HIGH_CONTRAST, FITS_EQUALIZE, FITS_HIGH_PASS, FITS_MEDIAN, FITS_ROTATE_CW, FITS_ROTATE_CCW, FITS_FLIP_H, FITS_FLIP_V, FITS_AUTO , FITS_LINEAR, FITS_LOG, FITS_SQRT, FITS_CUSTOM } FITSScale;
typedef enum { ZOOM_FIT_WINDOW, ZOOM_KEEP_LEVEL, ZOOM_FULL } FITSZoom;
typedef enum { HFR_AVERAGE, HFR_MAX } HFRType;
diff --git a/kstars/fitsviewer/fitsdata.h b/kstars/fitsviewer/fitsdata.h
index 765d214..0ece205 100644
--- a/kstars/fitsviewer/fitsdata.h
+++ b/kstars/fitsviewer/fitsdata.h
@@ -167,6 +167,9 @@ public:
int getRotCounter() const;
void setRotCounter(int value);
+ // Filename
+ const QString & getFilename() { return filename; }
+
// Horizontal flip counter. We keep count to rotate WCS keywords on save
int getFlipHCounter() const;
void setFlipHCounter(int value);
diff --git a/kstars/fitsviewer/fitshistogram.cpp b/kstars/fitsviewer/fitshistogram.cpp
index 4204de1..23973c6 100644
--- a/kstars/fitsviewer/fitshistogram.cpp
+++ b/kstars/fitsviewer/fitshistogram.cpp
@@ -458,8 +458,6 @@ void FITSHistogramCommand::redo()
QApplication::setOverrideCursor(Qt::WaitCursor);
- gamma = image->getGammaValue();
-
if (delta != NULL)
{
double min,max,stddev,average,median,snr;
@@ -591,8 +589,6 @@ void FITSHistogramCommand::undo()
image->rescale(ZOOM_KEEP_LEVEL);
image->updateFrame();
- image->setGammaValue(gamma);
-
QApplication::restoreOverrideCursor();
}
diff --git a/kstars/fitsviewer/fitstab.cpp b/kstars/fitsviewer/fitstab.cpp
index 602ed77..44abf5f 100644
--- a/kstars/fitsviewer/fitstab.cpp
+++ b/kstars/fitsviewer/fitstab.cpp
@@ -335,7 +335,6 @@ void FITSTab::ZoomDefault()
void FITSTab::tabPositionUpdated()
{
undoStack->setActive(true);
- emit newStatus(QString("%1").arg(view->getGammaValue()), FITS_GAMMA);
emit newStatus(QString("%1%").arg(view->getCurrentZoom()), FITS_ZOOM);
emit newStatus(QString("%1x%2").arg(view->getImageData()->getWidth()).arg(view->getImageData()->getHeight()), FITS_RESOLUTION);
}
diff --git a/kstars/fitsviewer/fitsview.cpp b/kstars/fitsviewer/fitsview.cpp
index 4ee30a4..58d44d6 100644
--- a/kstars/fitsviewer/fitsview.cpp
+++ b/kstars/fitsviewer/fitsview.cpp
@@ -62,8 +62,6 @@
#define ZOOM_LOW_INCR 10
#define ZOOM_HIGH_INCR 50
-#define DECAY_CONSTANT -0.04
-
//#define FITS_DEBUG
FITSLabel::FITSLabel(FITSView *img, QWidget *parent) : QLabel(parent)
@@ -252,7 +250,6 @@ FITSView::FITSView(QWidget * parent, FITSMode fitsMode, FITSScale filterType) :
firstLoad = true;
trackingBoxEnabled=false;
trackingBoxUpdated=false;
- gammaValue=0;
filter = filterType;
mode = fitsMode;
@@ -343,13 +340,6 @@ bool FITSView::loadFITS (const QString &inFilename , bool silent)
maxPixel = image_data->getMax();
minPixel = image_data->getMin();
- if (gammaValue != 0 && (filter== FITS_NONE || filter >= FITS_FLIP_H))
- {
- double maxGammaPixel = maxPixel* (100 * exp(DECAY_CONSTANT * gammaValue))/100.0;
- // If calculated maxPixel after gamma is different from image data max pixel, then we apply filter immediately.
- image_data->applyFilter(FITS_LINEAR, NULL, minPixel, maxGammaPixel);
- }
-
if (mode == FITS_NORMAL)
{
if (fitsProg.wasCanceled())
@@ -413,7 +403,7 @@ int FITSView::rescale(FITSZoom type)
float *display_buffer = image_buffer;
unsigned int size = image_data->getSize();
- if (Options::autoStretch() && filter != FITS_AUTO_STRETCH)
+ if (Options::autoStretch() && filter == FITS_NONE)
{
display_buffer = new float[image_data->getSize() * image_data->getNumOfChannels()];
memset(display_buffer, 0, image_data->getSize() * image_data->getNumOfChannels() * sizeof(float));
@@ -443,11 +433,6 @@ int FITSView::rescale(FITSZoom type)
else
image_data->getMinMax(&min, &max);
- calculateMaxPixel(min, max);
-
- min = minPixel;
- max = maxGammaPixel;
-
if (min == max)
{
display_image->fill(Qt::white);
@@ -483,8 +468,6 @@ int FITSView::rescale(FITSZoom type)
for (int i = 0; i < image_width; i++)
{
val = display_buffer[j * image_width + i];
- if (gammaValue > 0)
- val = qBound(minPixel, val, maxGammaPixel);
scanLine[i]= (val * bscale + bzero);
}
}
@@ -503,12 +486,6 @@ int FITSView::rescale(FITSZoom type)
rval = display_buffer[j * image_width + i];
gval = display_buffer[j * image_width + i + size];
bval = display_buffer[j * image_width + i + size * 2];
- if (gammaValue > 0)
- {
- rval = qBound(minPixel, rval, maxGammaPixel);
- gval = qBound(minPixel, gval, maxGammaPixel);
- gval = qBound(minPixel, gval, maxGammaPixel);
- }
value = qRgb(rval* bscale + bzero, gval* bscale + bzero, bval* bscale + bzero);
@@ -739,7 +716,7 @@ void FITSView::drawTrackingBox(QPainter *painter)
painter->setPen(QPen(Qt::green, 2));
if (trackingBox.isNull())
- return;
+ return;
int x1 = trackingBox.x() * (currentZoom / ZOOM_DEFAULT);
int y1 = trackingBox.y() * (currentZoom / ZOOM_DEFAULT);
@@ -830,40 +807,6 @@ void FITSView::setTrackingBoxEnabled(bool enable)
updateFrame();
}
}
-int FITSView::getGammaValue() const
-{
- return gammaValue;
-}
-
-void FITSView::setGammaValue(int value)
-{
- if (value == gammaValue)
- return;
-
- gammaValue = value;
-
- calculateMaxPixel(minPixel, maxPixel);
-
- // If calculated maxPixel after gamma is different from image data max pixel, then we apply filter immediately.
- //image_data->applyFilter(FITS_LINEAR, NULL, minPixel, maxGammaPixel);
- qApp->processEvents();
- rescale(ZOOM_KEEP_LEVEL);
- qApp->processEvents();
- updateFrame();
-
-}
-
-void FITSView::calculateMaxPixel(double min, double max)
-{
- minPixel=min;
- maxPixel=max;
-
- if (gammaValue == 0)
- maxGammaPixel = maxPixel;
- else
- maxGammaPixel = maxPixel* (100 * exp(DECAY_CONSTANT * gammaValue))/100.0;
-}
-
void FITSView::wheelEvent(QWheelEvent* event)
{
diff --git a/kstars/fitsviewer/fitsview.h b/kstars/fitsviewer/fitsview.h
index 19ce830..0f6074c 100644
--- a/kstars/fitsviewer/fitsview.h
+++ b/kstars/fitsviewer/fitsview.h
@@ -122,8 +122,6 @@ public:
void updateMode(FITSMode mode);
FITSMode getMode() { return mode;}
- int getGammaValue() const;
- void setGammaValue(int value);
void setFilter(FITSScale newFilter) { filter = newFilter;}
protected:
@@ -156,8 +154,7 @@ private:
QImage *display_image; /* FITS image that is displayed in the GUI */
FITSHistogram *histogram;
- int gammaValue;
- double maxPixel, maxGammaPixel, minPixel;
+ double maxPixel, minPixel;
bool firstLoad;
bool markStars;
diff --git a/kstars/fitsviewer/fitsviewer.cpp b/kstars/fitsviewer/fitsviewer.cpp
index e21e420..9146bc1 100644
--- a/kstars/fitsviewer/fitsviewer.cpp
+++ b/kstars/fitsviewer/fitsviewer.cpp
@@ -89,24 +89,15 @@ FITSViewer::FITSViewer (QWidget *parent)
fitsPosition.setAlignment(Qt::AlignCenter);
fitsValue.setAlignment(Qt::AlignCenter);
- gammaSlider.setMinimum(0);
- gammaSlider.setMaximum(100);
- gammaSlider.setValue(0);
- gammaSlider.setOrientation(Qt::Horizontal);
- gammaSlider.setFixedWidth(100);
-
//fitsPosition.setFixedWidth(100);
//fitsValue.setFixedWidth(100);
fitsWCS.setVisible(false);
- connect(&gammaSlider, SIGNAL(valueChanged(int)), this, SLOT(setGamma(int)));
-
statusBar()->insertPermanentWidget(FITS_WCS, &fitsWCS);
statusBar()->insertPermanentWidget(FITS_VALUE, &fitsValue);
statusBar()->insertPermanentWidget(FITS_POSITION, &fitsPosition);
statusBar()->insertPermanentWidget(FITS_ZOOM, &fitsZoom);
statusBar()->insertPermanentWidget(FITS_RESOLUTION, &fitsResolution);
- statusBar()->insertPermanentWidget(FITS_GAMMA, &gammaSlider);
statusBar()->insertPermanentWidget(FITS_LED, &led);
QAction *action;
@@ -390,7 +381,7 @@ bool FITSViewer::updateFITS(const QUrl *imageName, int fitsUID, FITSScale filter
if (tabIndex != -1 && tab->getView()->getMode() == FITS_NORMAL)
{
if ( (imageName->path().startsWith("/tmp") || imageName->path().contains("/Temp")) && Options::singlePreviewFITS())
- fitsTab->setTabText(tabIndex, tab->getPreviewText());
+ fitsTab->setTabText(tabIndex, tab->getPreviewText().isEmpty()? i18n("Preview") : tab->getPreviewText());
else
fitsTab->setTabText(tabIndex, imageName->fileName());
}
@@ -641,8 +632,6 @@ void FITSViewer::updateStatusBar(const QString &msg, FITSBar id)
{
switch (id)
{
- case FITS_GAMMA:
- gammaSlider.setValue(msg.toInt());
case FITS_POSITION:
fitsPosition.setText(msg);
break;
@@ -724,8 +713,9 @@ void FITSViewer::closeTab(int index)
FITSTab *tab = fitsTabs[index];
- if (tab->getView()->getMode() != FITS_NORMAL)
- return;
+ // N.B. We will allow closing of all tabs
+ //if (tab->getView()->getMode() != FITS_NORMAL)
+ // return;
/* Disabling user confirmation for saving edited FITS
Since in most cases the modifications are done to enhance the view and not to change the data
@@ -803,14 +793,6 @@ FITSView *FITSViewer::getCurrentView()
return fitsTabs[fitsTab->currentIndex()]->getView();
}
-void FITSViewer::setGamma(int value)
-{
- if (fitsTab->currentIndex() < 0 || fitsTab->currentIndex() > fitsTabs.count())
- return;
-
- fitsTabs[fitsTab->currentIndex()]->getView()->setGammaValue(value);
-}
-
void FITSViewer::setDebayerAction(bool enable)
{
actionCollection()->addAction("fits_debayer")->setEnabled(enable);
diff --git a/kstars/fitsviewer/fitsviewer.h b/kstars/fitsviewer/fitsviewer.h
index 619c25c..bc67315 100644
--- a/kstars/fitsviewer/fitsviewer.h
+++ b/kstars/fitsviewer/fitsviewer.h
@@ -114,7 +114,6 @@ public slots:
void rotateCCW();
void flipHorizontal();
void flipVertical();
- void setGamma(int value);
void setDebayerAction(bool);
private:
@@ -124,7 +123,6 @@ private:
FITSDebayer *debayerDialog;
KLed led;
QLabel fitsPosition, fitsValue, fitsResolution, fitsZoom, fitsWCS, fitsMessage;
- QSlider gammaSlider;
QAction *saveFileAction, *saveFileAsAction;
QList<FITSTab*> fitsTabs;
int fitsID;
diff --git a/kstars/indi/indiccd.cpp b/kstars/indi/indiccd.cpp
index 06a844f..f59c08a 100644
--- a/kstars/indi/indiccd.cpp
+++ b/kstars/indi/indiccd.cpp
@@ -1115,13 +1115,15 @@ void CCD::processBLOB(IBLOB* bp)
int nr, n=0;
QTemporaryFile tmpFile(QDir::tempPath() + "/fitsXXXXXX");
- if (currentDir.endsWith('/'))
- currentDir.truncate(sizeof(currentDir)-1);
+ //if (currentDir.endsWith('/'))
+ //currentDir.truncate(currentDir.size()-1);
if (QDir(currentDir).exists() == false)
QDir().mkpath(currentDir);
- QString filename(currentDir + '/');
+ QString filename(currentDir);
+ if (filename.endsWith('/') == false)
+ filename.append('/');
// Create temporary name if ANY of the following conditions are met:
// 1. file is preview or batch mode is not enabled
diff --git a/kstars/indi/indiccd.h b/kstars/indi/indiccd.h
index 470b236..687de21 100644
--- a/kstars/indi/indiccd.h
+++ b/kstars/indi/indiccd.h
@@ -70,7 +70,7 @@ public:
bool getBinning(int *bin_x, int *bin_y);
bool getMaxBin(int *max_xbin, int *max_ybin);
ChipType getType() const { return type; }
- ISD::CCD *getParentCCD() { return parentCCD;}
+ ISD::CCD *getCCD() { return parentCCD;}
bool isCapturing();
bool abortExposure();
diff --git a/kstars/kstars.kcfg b/kstars/kstars.kcfg
index 2aeca5c..6c0d4c0 100644
--- a/kstars/kstars.kcfg
+++ b/kstars/kstars.kcfg
@@ -1405,6 +1405,10 @@
<label>When starting a new capture job, check if files were previously captured and resume capture afterwards.</label>
<default>true</default>
</entry>
+ <entry name="DarkLibraryDuration" type="UInt">
+ <label>Reuse dark frames from the dark library for this many days. If exceeded, a new dark frame shall be captured and stored for future use.</label>
+ <default>30</default>
+ </entry>
<entry name="AutoFocusOnFilterChange" type="Bool">
<label>Perform an autofocus operation when changing filter wheels during an exposure sequence.</label>
<default>false</default>