way too many updates

This commit is contained in:
2024-09-19 12:02:21 +02:00
parent 631fd901b1
commit 3d128d8ecc
9 changed files with 1378 additions and 282 deletions
+86 -37
View File
@@ -64,6 +64,10 @@ class AstrodataGUI(QtWidgets.QMainWindow):
self.flaredetectorPreview.periodsCalculated.connect(self.updatePeriods) self.flaredetectorPreview.periodsCalculated.connect(self.updatePeriods)
self.flaredetectorPreview.epochCalculated.connect(self.updateEpochPeriod) self.flaredetectorPreview.epochCalculated.connect(self.updateEpochPeriod)
self.rbLinearFit.toggled.connect(self.rbFoldedPlotTypeChanged)
self.rbSineFit.toggled.connect(self.rbFoldedPlotTypeChanged)
self.rbPolynomialFit.toggled.connect(self.rbFoldedPlotTypeChanged)
self.setupCustomSimbadQueries() self.setupCustomSimbadQueries()
self.show() self.show()
self.loadDB() self.loadDB()
@@ -109,51 +113,52 @@ class AstrodataGUI(QtWidgets.QMainWindow):
if not diag.exec(): if not diag.exec():
return return
try: try:
result = self.simbad.query_object(diag.starIdentifier) results = self.simbad.query_object(diag.starIdentifier)
except: except:
self.showErrorMessage("Simbad Error", "Failed to fetcch information from Simbad, aborting...") self.showErrorMessage("Simbad Error", "Failed to fetcch information from Simbad, aborting...")
return return
results = results.split(";")
for result in results:
try:
mainName = result["MAIN_ID"][0]
except:
self.showErrorMessage("Main Identifier Error", "Failed to grab main identifier, aborting...")
return
try: try:
mainName = result["MAIN_ID"][0] altNames = Simbad.query_objectids(mainName)
except: except:
self.showErrorMessage("Main Identifier Error", "Failed to grab main identifier, aborting...") self.showErrorMessage("Identifier Error", "Failed to grab all identifiers, aborting...")
return return
try: try:
altNames = Simbad.query_objectids(mainName) specType = result["SP_TYPE"][0]
except: if(specType == ""):
self.showErrorMessage("Identifier Error", "Failed to grab all identifiers, aborting...") specType = "-"
return except:
print("No spectral type found")
try:
specType = result["SP_TYPE"][0]
if(specType == ""):
specType = "-" specType = "-"
except:
print("No spectral type found")
specType = "-"
rotVel = -1 rotVel = -1
rotVelUnit = "" rotVelUnit = ""
try: try:
if(result["RVZ_TYPE"][0] == "v"): if(result["RVZ_TYPE"][0] == "v"):
rotVel = result["RV_VALUE"][0] rotVel = result["RV_VALUE"][0]
rotVelUnit = str(result["RV_VALUE"].unit) rotVelUnit = str(result["RV_VALUE"].unit)
except: except:
print("No radial velocity found") print("No radial velocity found")
try: try:
dist = float(result["Distance_distance"][0]) dist = float(result["Distance_distance"][0])
if(np.isnan(dist)): if(np.isnan(dist)):
dist = -1
distUnit = result["Distance_unit"][0]
except:
dist = -1 dist = -1
distUnit = result["Distance_unit"][0] distUnit = ""
except:
dist = -1
distUnit = ""
self.starDB.insertStar(mainName, altNames, diag.productManifest, self.starDB.insertStar(mainName, altNames, diag.productManifest,
specType, rotVel, rotVelUnit, dist, distUnit) specType, rotVel, rotVelUnit, dist, distUnit)
self.updateStarList() self.updateStarList()
@@ -184,14 +189,41 @@ class AstrodataGUI(QtWidgets.QMainWindow):
else: else:
self.lbDistance.setText("-") self.lbDistance.setText("-")
def updateStarFoldedFitType(self, foldedFitType):
self.rbLinearFit.blockSignals(True)
self.rbSineFit.blockSignals(True)
self.rbPolynomialFit.blockSignals(True)
if(foldedFitType == "linear"):
self.rbLinearFit.setChecked(True)
self.rbSineFit.setChecked(False)
self.rbPolynomialFit.setChecked(False)
elif(foldedFitType == "sine"):
self.rbLinearFit.setChecked(False)
self.rbSineFit.setChecked(True)
self.rbPolynomialFit.setChecked(False)
elif(foldedFitType == "poly"):
self.rbLinearFit.setChecked(False)
self.rbSineFit.setChecked(False)
self.rbPolynomialFit.setChecked(True)
else:
self.rbLinearFit.setChecked(False)
self.rbSineFit.setChecked(False)
self.rbPolynomialFit.setChecked(False)
self.rbLinearFit.blockSignals(False)
self.rbSineFit.blockSignals(False)
self.rbPolynomialFit.blockSignals(False)
def starSelected(self, item): def starSelected(self, item):
self.currentStarMainName = item.text()
seqs = self.starDB.getStarSequences(item.text()) seqs = self.starDB.getStarSequences(item.text())
infos = self.starDB.getStarInfos(item.text()) infos = self.starDB.getStarInfos(item.text())
altNames = self.starDB.getStarAltNames(item.text()) altNames = self.starDB.getStarAltNames(item.text())
self.foldedFitType = self.starDB.getFoldedFitType(item.text())
self.lbMainID.setText(item.text()) self.lbMainID.setText(item.text())
self.updateSequenceList(seqs) self.updateSequenceList(seqs)
self.updateStarInfo(infos) self.updateStarInfo(infos)
self.updateStarAltNames(altNames) self.updateStarAltNames(altNames)
self.updateStarFoldedFitType(self.foldedFitType)
def sequenceSelected(self, item): def sequenceSelected(self, item):
self.gbPlotOptions.setEnabled(True) self.gbPlotOptions.setEnabled(True)
@@ -202,6 +234,21 @@ class AstrodataGUI(QtWidgets.QMainWindow):
seq = seqText[1] seq = seqText[1]
filePath = self.starDB.getFilePath(mainName, source, seq) filePath = self.starDB.getFilePath(mainName, source, seq)
self.flaredetectorPreview.setFitsFile(filePath, mainName) self.flaredetectorPreview.setFitsFile(filePath, mainName)
self.flaredetectorPreview.setFoldedFitType(self.foldedFitType)
def rbFoldedPlotTypeChanged(self, state):
if(state):
print("Folded fit type changed")
self.foldedFitType = ""
match(self.sender()):
case self.rbLinearFit:
self.foldedFitType = "linear"
case self.rbSineFit:
self.foldedFitType = "sine"
case self.rbPolynomialFit:
self.foldedFitType = "poly"
self.starDB.updateFoldedFitType(self.currentStarMainName, self.foldedFitType)
self.flaredetectorPreview.setFoldedFitType(self.foldedFitType)
def updatePeriods(self, periods: list): def updatePeriods(self, periods: list):
self.edPlotFoldPeriod.setText(str(periods[0].value)) self.edPlotFoldPeriod.setText(str(periods[0].value))
@@ -378,18 +425,20 @@ class AstrodataGUI(QtWidgets.QMainWindow):
"DistanceUnit", "DistanceUnit",
"Source", "Source",
"Sequence", "Sequence",
"FilePath"]) "FilePath",
"FitType"])
for starName in self.starDB.getAllStars(): for starName in self.starDB.getAllStars():
sequences = self.starDB.getStarSequences(starName) sequences = self.starDB.getStarSequences(starName)
infos = self.starDB.getStarInfos(starName) infos = self.starDB.getStarInfos(starName)
fitType = self.starDB.getFoldedFitType(starName)
for sourceSeq in sequences: for sourceSeq in sequences:
source = sourceSeq["Source"] source = sourceSeq["Source"]
seq = sourceSeq["Sequence"] seq = sourceSeq["Sequence"]
filePath = self.starDB.getFilePath(starName, source, seq) filePath = self.starDB.getFilePath(starName, source, seq)
allStarsDictList.loc[len(allStarsDictList.index)] = \ allStarsDictList.loc[len(allStarsDictList.index)] = \
[starName, infos["SpType"], infos["RotVel"], infos["RotVelUnit"], [starName, infos["SpType"], infos["RotVel"], infos["RotVelUnit"],
infos["Distance"], infos["DistanceUnit"], source, seq, filePath] infos["Distance"], infos["DistanceUnit"], source, seq, filePath, fitType]
self.calcAllFlaresThread = CalcAllFlaresThread(allStarsDictList) self.calcAllFlaresThread = CalcAllFlaresThread(allStarsDictList)
self.calcAllFlaresThread.finished.connect(self.btCountAllFlaresClickedDone) self.calcAllFlaresThread.finished.connect(self.btCountAllFlaresClickedDone)
+80 -68
View File
@@ -6,76 +6,88 @@ import pandas as pd
from ..flaredetector.flaredetector import calculateFlareFitsForLightcurve from ..flaredetector.flaredetector import calculateFlareFitsForLightcurve
from ..flaredetector.util import * from ..flaredetector.util import *
import warnings
warnings.filterwarnings("ignore")
def getFlareCount(filesDict): def getFlareCount(filesDict):
lc = read(filesDict["FilePath"]) try:
lc.flux = lc["sap_flux"] print(f"Starting {filesDict['StarName']}, {filesDict['Sequence']}")
lc.flux_err = lc["sap_flux_err"] lc = read(filesDict["FilePath"])
sapPeaks, sapFits = calculateFlareFitsForLightcurve(lc.flatten()) lc.flux = lc["sap_flux"]
sapValSec, sapTds = getTotalValidDataInSeconds(lc, "sap_flux") lc.flux_err = lc["sap_flux_err"]
sapPeriodogram = lc.to_periodogram() sapPeaks, sapFits = calculateFlareFitsForLightcurve(lc.flatten())
sapPeakPeriod = sapPeriodogram.period[findMaxIndices(sapPeriodogram, num=4, distance=100, sortByHighest=True)[0]] sapValSec, sapTds = getTotalValidDataInSeconds(lc, "sap_flux")
sapEpochTime = getEpochTime(lc) sapPeriodogram = lc.to_periodogram()
sapFoldedLC = lc.fold(period=sapPeakPeriod, epoch_time=sapEpochTime) sapPeakPeriod = sapPeriodogram.period[findMaxIndices(sapPeriodogram, num=4, distance=100, sortByHighest=True)[0]]
sapPhase, sapSineFit, sapFitType = getFoldedBestFit(sapFoldedLC) sapEpochTime = getEpochTime(lc)
sapMinima, sapMaxima = getFoldedFitPeakValley(sapSineFit) sapFoldedLC = lc.fold(period=sapPeakPeriod, epoch_time=sapEpochTime)
sapminPhasesBounds, sapmaxPhasesBounds = getPhaseRangesNearPeak((sapMinima, sapMaxima), sapPhase, returnPhaseValue=True) sapPhase, sapSineFit, sapFitType = getFoldedBestFit(sapFoldedLC, fitType=filesDict["FitType"])
sapFoldedPeaks = [] sapMinima, sapMaxima = getFoldedFitPeakValley(sapSineFit)
sapFoldedPeaksPhasePair = [] sapminPhasesBounds, sapmaxPhasesBounds = getPhaseRangesNearPeak((sapMinima, sapMaxima), sapPhase, returnPhaseValue=True)
for peak in sapPeaks: sapFoldedPeaks = []
cycle, foldedIndex = convertStarndardIndexToFoldedIndex(sapFoldedLC, peak["StandardIndex"]) sapFoldedPeaksPhasePair = []
sapFoldedPeaks.append({"Cycle: ": cycle, "Index": foldedIndex}) for peak in sapPeaks:
sapFoldedPeaksPhasePair.append({"Phase": sapFoldedLC.phase[sapFoldedLC.cycle == cycle][foldedIndex], "Peak": peak}) cycle, foldedIndex = convertStarndardIndexToFoldedIndex(sapFoldedLC, peak["StandardIndex"])
sapFoldedPeaks.append({"Cycle: ": cycle, "Index": foldedIndex})
sapFoldedPeaksPhasePair.append({"Phase": sapFoldedLC.phase[sapFoldedLC.cycle == cycle][foldedIndex], "Peak": peak})
lc.flux = lc["pdcsap_flux"] lc.flux = lc["pdcsap_flux"]
lc.flux_err = lc["pdcsap_flux_err"] lc.flux_err = lc["pdcsap_flux_err"]
pdcsapPeaks, pdcsapFits = calculateFlareFitsForLightcurve(lc.flatten()) pdcsapPeaks, pdcsapFits = calculateFlareFitsForLightcurve(lc.flatten())
pdcsapValSec, pdcsapTds = getTotalValidDataInSeconds(lc, "pdcsap_flux") pdcsapValSec, pdcsapTds = getTotalValidDataInSeconds(lc, "pdcsap_flux")
pdcsapPeriodogram = lc.to_periodogram() pdcsapPeriodogram = lc.to_periodogram()
pdcsapPeakPeriod = pdcsapPeriodogram.period[findMaxIndices(pdcsapPeriodogram, num=4, distance=100, sortByHighest=True)[0]] pdcsapPeakPeriod = pdcsapPeriodogram.period[findMaxIndices(pdcsapPeriodogram, num=4, distance=100, sortByHighest=True)[0]]
pdcsapEpochTime = getEpochTime(lc) pdcsapEpochTime = getEpochTime(lc)
pdcsapFoldedLC = lc.fold(period=pdcsapPeakPeriod, epoch_time=pdcsapEpochTime) pdcsapFoldedLC = lc.fold(period=pdcsapPeakPeriod, epoch_time=pdcsapEpochTime)
pdcsapPhase, pdcsapSineFit, pdcsapFitType = getFoldedBestFit(pdcsapFoldedLC) pdcsapPhase, pdcsapSineFit, pdcsapFitType = getFoldedBestFit(pdcsapFoldedLC, fitType=filesDict["FitType"])
pdcsapMinima, pdcsapMaxima = getFoldedFitPeakValley(pdcsapSineFit) pdcsapMinima, pdcsapMaxima = getFoldedFitPeakValley(pdcsapSineFit)
pdcsapminPhasesBounds, pdcsapmaxPhasesBounds = getPhaseRangesNearPeak((pdcsapMinima, pdcsapMaxima), pdcsapPhase, returnPhaseValue=True) pdcsapminPhasesBounds, pdcsapmaxPhasesBounds = getPhaseRangesNearPeak((pdcsapMinima, pdcsapMaxima), pdcsapPhase, returnPhaseValue=True)
pdcsapFoldedPeaks = [] pdcsapFoldedPeaks = []
pdcsapFoldedPeaksPhasePair = [] pdcsapFoldedPeaksPhasePair = []
for peak in sapPeaks: for peak in sapPeaks:
cycle, foldedIndex = convertStarndardIndexToFoldedIndex(pdcsapFoldedLC, peak["StandardIndex"]) cycle, foldedIndex = convertStarndardIndexToFoldedIndex(pdcsapFoldedLC, peak["StandardIndex"])
pdcsapFoldedPeaks.append({"Cycle: ": cycle, "Index": foldedIndex}) pdcsapFoldedPeaks.append({"Cycle: ": cycle, "Index": foldedIndex})
pdcsapFoldedPeaksPhasePair.append({"Phase": pdcsapFoldedLC.phase[pdcsapFoldedLC.cycle == cycle][foldedIndex], "Peak": peak}) pdcsapFoldedPeaksPhasePair.append({"Phase": pdcsapFoldedLC.phase[pdcsapFoldedLC.cycle == cycle][foldedIndex], "Peak": peak})
filesDict["sapPeaks"] = sapPeaks filesDict["sapPeaks"] = sapPeaks
filesDict["sapPeaksCount"] = len(sapPeaks) filesDict["sapPeaksCount"] = len(sapPeaks)
filesDict["sapFits"] = sapFits filesDict["sapFits"] = sapFits
filesDict["sapValidTimespans"] = sapTds filesDict["sapValidTimespans"] = sapTds
filesDict["sapValidSeconds"] = sapValSec filesDict["sapValidSeconds"] = sapValSec
filesDict["sapFoldedCycle"] = sapFoldedLC.cycle filesDict["sapFoldedCycle"] = sapFoldedLC.cycle
#filesDict["sapFoldedPhase"] = sapFoldedLC.phase.value #filesDict["sapFoldedPhase"] = sapFoldedLC.phase.value
#filesDict["sapFoldedFitPhase"] = sapPhase #filesDict["sapFoldedFitPhase"] = sapPhase
filesDict["sapFoldedFitPhaseStarEnd"] = (sapFoldedLC.phase.value[0], sapFoldedLC.phase.value[-1]) filesDict["sapFoldedFitPhaseStarEnd"] = (sapFoldedLC.phase.value[0], sapFoldedLC.phase.value[-1])
filesDict["sapFoldedPeaksPhasePair"] = sapFoldedPeaksPhasePair filesDict["sapFoldedPeaksPhasePair"] = sapFoldedPeaksPhasePair
filesDict["sapPeriod"] = sapPeakPeriod.value filesDict["sapPeriod"] = sapPeakPeriod.value
filesDict["sapPeriodMinima"] = sapMinima filesDict["sapPeriodMinima"] = sapMinima
filesDict["sapPeriodMinimaBoundaries"] = sapminPhasesBounds filesDict["sapPeriodMinimaBoundaries"] = sapminPhasesBounds
filesDict["sapPeriodMaxima"] = sapMaxima filesDict["sapPeriodMaxima"] = sapMaxima
filesDict["sapPeriodMaximaBoundaries"] = sapmaxPhasesBounds filesDict["sapPeriodMaximaBoundaries"] = sapmaxPhasesBounds
filesDict["pdcsapPeaks"] = pdcsapPeaks filesDict["pdcsapPeaks"] = pdcsapPeaks
filesDict["pdcsapPeaksCount"] = len(pdcsapPeaks) filesDict["pdcsapPeaksCount"] = len(pdcsapPeaks)
filesDict["pdcsapFits"] = pdcsapFits filesDict["pdcsapFits"] = pdcsapFits
filesDict["pdcsapValidTimespans"] = pdcsapTds filesDict["pdcsapValidTimespans"] = pdcsapTds
filesDict["pdcsapValidSeconds"] = pdcsapValSec filesDict["pdcsapValidSeconds"] = pdcsapValSec
filesDict["pdcsapFoldedCycle"] = sapFoldedLC.cycle filesDict["pdcsapFoldedCycle"] = sapFoldedLC.cycle
#filesDict["pdcsapFoldedPhase"] = sapFoldedLC.phase.value #filesDict["pdcsapFoldedPhase"] = sapFoldedLC.phase.value
#filesDict["pdcsapFoldedFitPhase"] = pdcsapPhase #filesDict["pdcsapFoldedFitPhase"] = pdcsapPhase
filesDict["pdcsapFoldedFitPhaseStarEnd"] = (pdcsapFoldedLC.phase.value[0], pdcsapFoldedLC.phase.value[-1]) filesDict["pdcsapFoldedFitPhaseStarEnd"] = (pdcsapFoldedLC.phase.value[0], pdcsapFoldedLC.phase.value[-1])
filesDict["pdcsapFoldedPeaksPhasePair"] = pdcsapFoldedPeaksPhasePair filesDict["pdcsapFoldedPeaksPhasePair"] = pdcsapFoldedPeaksPhasePair
filesDict["pdcsapPeriod"] = pdcsapPeakPeriod.value filesDict["pdcsapPeriod"] = pdcsapPeakPeriod.value
filesDict["pdcsapPeriodMinima"] = pdcsapMinima filesDict["pdcsapPeriodMinima"] = pdcsapMinima
filesDict["pdcsapPeriodMinimaBoundaries"] = pdcsapminPhasesBounds filesDict["pdcsapPeriodMinimaBoundaries"] = pdcsapminPhasesBounds
filesDict["pdcsapPeriodMaxima"] = pdcsapMaxima filesDict["pdcsapPeriodMaxima"] = pdcsapMaxima
filesDict["pdcsapPeriodMaximaBoundaries"] = pdcsapmaxPhasesBounds filesDict["pdcsapPeriodMaximaBoundaries"] = pdcsapmaxPhasesBounds
del lc del lc
return filesDict print(f"Finished {filesDict['StarName']}, {filesDict['Sequence']}")
return filesDict
except Exception as e:
print("------------------------------------------------------------------------")
print(f"Exception in {filesDict['StarName']}, {filesDict['Sequence']}")
print(e)
print("------------------------------------------------------------------------")
return None
class CalcAllFlaresThread(QThread): class CalcAllFlaresThread(QThread):
progress = pyqtSignal(int) progress = pyqtSignal(int)
@@ -89,7 +101,7 @@ class CalcAllFlaresThread(QThread):
def run(self): def run(self):
cpuCount = multiprocessing.cpu_count() cpuCount = multiprocessing.cpu_count()
executor = concurrent.futures.ProcessPoolExecutor(cpuCount) executor = concurrent.futures.ProcessPoolExecutor(cpuCount)
#resFrame = pd.DataFrame([getFlareCount(entry) for entry in self.allFlaresDictList.to_dict(orient="records")])
resFrame = pd.DataFrame(executor.map(getFlareCount, self.allFlaresDictList.to_dict(orient="records"))) resFrame = pd.DataFrame(executor.map(getFlareCount, self.allFlaresDictList.to_dict(orient="records")))
self.finished.emit(resFrame) self.finished.emit(resFrame)
File diff suppressed because it is too large Load Diff
+80 -36
View File
@@ -968,6 +968,13 @@
<layout class="QHBoxLayout" name="horizontalLayout_6"> <layout class="QHBoxLayout" name="horizontalLayout_6">
<item> <item>
<layout class="QGridLayout" name="gridLayout"> <layout class="QGridLayout" name="gridLayout">
<item row="1" column="0">
<widget class="QLabel" name="label_3">
<property name="text">
<string>Alt. IDs:</string>
</property>
</widget>
</item>
<item row="2" column="2"> <item row="2" column="2">
<widget class="QLabel" name="lbSpType"> <widget class="QLabel" name="lbSpType">
<property name="sizePolicy"> <property name="sizePolicy">
@@ -981,23 +988,10 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="3" column="2"> <item row="2" column="0">
<widget class="QLabel" name="lbRotVel"> <widget class="QLabel" name="label_4">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Maximum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text"> <property name="text">
<string>-</string> <string>Spectral Type: </string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_3">
<property name="text">
<string>Alt. IDs:</string>
</property> </property>
</widget> </widget>
</item> </item>
@@ -1021,13 +1015,6 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="2" column="0">
<widget class="QLabel" name="label_4">
<property name="text">
<string>Spectral Type: </string>
</property>
</widget>
</item>
<item row="4" column="0"> <item row="4" column="0">
<widget class="QLabel" name="label_6"> <widget class="QLabel" name="label_6">
<property name="text"> <property name="text">
@@ -1035,19 +1022,6 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="0" column="2">
<widget class="QLabel" name="lbMainID">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Maximum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>-</string>
</property>
</widget>
</item>
<item row="3" column="0"> <item row="3" column="0">
<widget class="QLabel" name="label_5"> <widget class="QLabel" name="label_5">
<property name="text"> <property name="text">
@@ -1077,6 +1051,73 @@
</property> </property>
</widget> </widget>
</item> </item>
<item row="3" column="2">
<widget class="QLabel" name="lbRotVel">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Maximum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>-</string>
</property>
</widget>
</item>
<item row="0" column="2">
<widget class="QLabel" name="lbMainID">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Maximum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>-</string>
</property>
</widget>
</item>
<item row="5" column="0">
<widget class="QLabel" name="label_24">
<property name="text">
<string>Fit Type:</string>
</property>
</widget>
</item>
<item row="5" column="2">
<layout class="QVBoxLayout" name="verticalLayout_11">
<item>
<widget class="QRadioButton" name="rbLinearFit">
<property name="text">
<string>Linear</string>
</property>
<attribute name="buttonGroup">
<string notr="true">bgFitType</string>
</attribute>
</widget>
</item>
<item>
<widget class="QRadioButton" name="rbSineFit">
<property name="text">
<string>Sine</string>
</property>
<attribute name="buttonGroup">
<string notr="true">bgFitType</string>
</attribute>
</widget>
</item>
<item>
<widget class="QRadioButton" name="rbPolynomialFit">
<property name="text">
<string>Poly</string>
</property>
<attribute name="buttonGroup">
<string notr="true">bgFitType</string>
</attribute>
</widget>
</item>
</layout>
</item>
</layout> </layout>
</item> </item>
</layout> </layout>
@@ -1156,4 +1197,7 @@
</customwidgets> </customwidgets>
<resources/> <resources/>
<connections/> <connections/>
<buttongroups>
<buttongroup name="bgFitType"/>
</buttongroups>
</ui> </ui>
+17 -9
View File
@@ -1,7 +1,7 @@
from enum import Enum from enum import Enum
import sqlite3 import sqlite3
supportedFitTypes = ["sine", "linear", "poly"] supportedFoldedFitTypes = ["sine", "linear", "poly"]
class StarDBError(Enum): class StarDBError(Enum):
NO_ERROR = 0 NO_ERROR = 0
@@ -153,11 +153,12 @@ class StarDB():
self.connection.commit() self.connection.commit()
def updateFitType(self, mainName, fitType: str): def updateFoldedFitType(self, mainName, fitType: str):
if(fitType in supportedFoldedFitTypes): if(fitType in supportedFoldedFitTypes):
self.dbCursor.execute(f"""UPDATE starFoldedFitType print("Updating fit type for ", mainName, " to ", fitType)
SET foldedFitType = '{fitType}' self.dbCursor.execute(f"""INSERT OR REPLACE INTO
WHERE mainName = '{mainName}';""") starFoldedFitType (mainName, foldedFitType)
VALUES ('{mainName}', '{fitType}');""")
self.connection.commit() self.connection.commit()
else: else:
raise Exception(f"Fit type {fitType} not supported, must be one of {supportedFitTypes}") raise Exception(f"Fit type {fitType} not supported, must be one of {supportedFitTypes}")
@@ -214,8 +215,15 @@ class StarDB():
def getFoldedFitType(self, mainName): def getFoldedFitType(self, mainName):
res = self.dbCursor.execute(f"""SELECT foldedFitType FROM starFoldedFitType res = self.dbCursor.execute(f"""SELECT foldedFitType FROM starFoldedFitType
WHERE mainName = \"{mainName}\";""") WHERE mainName = \"{mainName}\";""")
ret = res.fetchone()[0] try:
if(ret in supportedFoldedFitTypes): ret = res.fetchone()[0]
return ret print("Fit type for star ", mainName, ": ",ret)
else: if(ret in supportedFoldedFitTypes):
return ret
else:
print("fit type not supported, return default")
return "sine"
except Exception as e:
print("No custom fit type found, return default")
print(e)
return "sine" return "sine"
+23 -4
View File
@@ -9,6 +9,7 @@ import lightkurve as lk
from ...flaredetector.util import * from ...flaredetector.util import *
from ...flaredetector.flaredetector import calculateFlareFitsForLightcurve from ...flaredetector.flaredetector import calculateFlareFitsForLightcurve
from ...astrodatagui.db.StarsDB import supportedFoldedFitTypes
class FlaredetectorWidget(QtWidgets.QWidget): class FlaredetectorWidget(QtWidgets.QWidget):
@@ -64,6 +65,8 @@ class FlaredetectorWidget(QtWidgets.QWidget):
def setFitsFile(self, fitsFilePath, mainName: str): def setFitsFile(self, fitsFilePath, mainName: str):
print(f"Plotting: {fitsFilePath}") print(f"Plotting: {fitsFilePath}")
self.currentLC = lk.read(fitsFilePath) self.currentLC = lk.read(fitsFilePath)
if(isinstance(self.currentLC, lk.lightcurve.KeplerLightCurve)):
print(f"Kepler Quarter: {self.currentLC.hdu[0].header['QUARTER']}")
self.currentLCCollection = None self.currentLCCollection = None
self.currentMainName = mainName self.currentMainName = mainName
self.updateFit() self.updateFit()
@@ -184,6 +187,17 @@ class FlaredetectorWidget(QtWidgets.QWidget):
self.ShowQualityState["Enabled"] = enabled self.ShowQualityState["Enabled"] = enabled
self.updatePlot() self.updatePlot()
def setFoldedFitType(self, foldedFitType):
print("Setting folded Fit Type")
if(foldedFitType in supportedFoldedFitTypes):
self.foldedFitType = foldedFitType
else:
print("Unsupported fit type:", foldedFitType)
print("Setting default: sine")
self.foldedFitType = "sine"
if(hasattr(self, "currentLC")):
self.updatePlot()
def normalizeStichedLightCurve(self, lc): def normalizeStichedLightCurve(self, lc):
lc.flux = lc[self.fluxType] lc.flux = lc[self.fluxType]
lc.flux_err = lc[self.fluxErrType] lc.flux_err = lc[self.fluxErrType]
@@ -254,10 +268,15 @@ class FlaredetectorWidget(QtWidgets.QWidget):
cycle, foldedIndex = convertStarndardIndexToFoldedIndex(lc, peak["StandardIndex"]) cycle, foldedIndex = convertStarndardIndexToFoldedIndex(lc, peak["StandardIndex"])
self.figureAxis.plot(lc.phase[lc.cycle == cycle][foldedIndex].value, self.figureAxis.plot(lc.phase[lc.cycle == cycle][foldedIndex].value,
lc.flux[lc.cycle == cycle][foldedIndex], "x", color="red") lc.flux[lc.cycle == cycle][foldedIndex], "x", color="red")
phase, sineFit, _ = getFoldedBestFit(lc) try:
self.figureAxis.plot(phase, sineFit, color="red") phase, sineFit, _ = getFoldedBestFit(lc, fitType=self.foldedFitType)
minPhasesBoundsIndices, maxPhasesBoundsIndices = getPhaseRangesNearPeak(getFoldedFitPeakValley(sineFit), phase) self.figureAxis.plot(phase, sineFit, color="red")
plotPhaseRangesNearPeak((minPhasesBoundsIndices, maxPhasesBoundsIndices), phase, ax=self.figureAxis) print(phase, sineFit)
minPhasesBoundsIndices, maxPhasesBoundsIndices = getPhaseRangesNearPeak(getFoldedFitPeakValley(sineFit), phase)
plotPhaseRangesNearPeak((minPhasesBoundsIndices, maxPhasesBoundsIndices), phase, ax=self.figureAxis)
except Exception as e:
print("Failed to get fit")
print(e)
elif(self.PeriodogramState["Enabled"]): elif(self.PeriodogramState["Enabled"]):
lc.plot(label=label, ax=self.figureAxis, view=self.PeriodogramState["View"]) lc.plot(label=label, ax=self.figureAxis, view=self.PeriodogramState["View"])
if(self.PeriodogramState["View"] == "period"): if(self.PeriodogramState["View"] == "period"):
+15 -9
View File
@@ -3,6 +3,8 @@ from PyQt5.QtWidgets import QDialog, QListWidgetItem
from PyQt5 import uic from PyQt5 import uic
import os import os
from astropy.table import vstack
from ...astrodatadownloader.astrodatadownloader import (ObservationSource, from ...astrodatadownloader.astrodatadownloader import (ObservationSource,
getStarObservations, downloadStarProducts) getStarObservations, downloadStarProducts)
@@ -49,16 +51,20 @@ class NewStarDialog(QDialog):
k2Kadences = [self.cbK2ShortCadence.isChecked(), k2Kadences = [self.cbK2ShortCadence.isChecked(),
self.cbK2LongCadence.isChecked()] self.cbK2LongCadence.isChecked()]
obs = getStarObservations(star, keplerKadences, k2Kadences, sources) allObs = []
if(len(obs) == 0): stars = star.split(";")
self.showErrorMessage("No observations found",
"No observationnal data has been found with the current filters")
return
self.listPreview.clear() self.listPreview.clear()
for o in obs: for s in stars:
print(o) s = s.strip()
self.listPreview.addItem(QListWidgetItem(f"{star} - {o['obs_collection']} - {o['sequence_number']}")) obs = getStarObservations(s, keplerKadences, k2Kadences, sources)
if(len(obs) == 0):
self.showErrorMessage("No observations found",
"No observationnal data has been found with the current filters")
return
allObs.append(obs)
for o in obs:
self.listPreview.addItem(QListWidgetItem(f"{s} - {o['obs_collection']} - {o['sequence_number']}"))
obs = vstack(allObs)
self.currentObservations = obs self.currentObservations = obs
self.starIdentifier = star self.starIdentifier = star
+182 -46
View File
@@ -94,8 +94,8 @@ def fitPolynomial(phase, flux, degree):
def linear(t, k, d): def linear(t, k, d):
return k*t + d return k*t + d
def fitLinear(phase, flux, degree): def fitLinear(phase, flux):
popt, _ = curve_fit(linear, phase, flux, maxfev=300) popt, _ = curve_fit(linear, phase, flux, maxfev=3000)
return linear(phase, *popt) return linear(phase, *popt)
def compureRSS(fit, flux): def compureRSS(fit, flux):
@@ -122,14 +122,23 @@ def getFoldedBestFit(foldedLc, fitType="sine"):
flux = flux[filt] flux = flux[filt]
polyDegree = 7 polyDegree = 7
fitThreshold = 0.0 fitThreshold = 0.0
smoothed_flux = np.convolve(flux, np.ones(len(flux)//100)/(len(flux)//100), mode="valid")
peaks, _ = find_peaks(smoothed_flux, height=np.mean(smoothed_flux))
#print("Num peaks: ", peaks)
if(fitType == "sine"): if(fitType == "sine"):
retFit = fitSingleSine(phase, flux) try:
print("using sine")
retFit = fitSingleSine(phase, flux)
except: # if its supposed to be a sine, but we cant find one, use a polynomial
print("Use polynomial instead")
retFit = fitPolynomial(phase, flux, polyDegree)
fitType = "poly"
elif(fitType == "poly"): elif(fitType == "poly"):
retFit = fitPolynomial(phase, flux, polyDegree) try:
print("using poly")
retFit = fitPolynomial(phase, flux, polyDegree)
except: # other way around for poly to sine
print("Use sine instead")
retFit = fitSingleSine(phase, flux)
fitType = "sine"
elif(fitType == "linear"): elif(fitType == "linear"):
retFit = fitLinear(phase, flux) retFit = fitLinear(phase, flux)
else: else:
@@ -174,6 +183,27 @@ def getFoldedFitPeakValley(sineFit):
else: else:
maxima = np.array((len(sineFit)-1), ndmin=1) maxima = np.array((len(sineFit)-1), ndmin=1)
# TODO: if theres a minima and maxima extremely close to the edge of data, remove them
if(len(minima) > 1 and len(maxima) > 1):
lenArray = len(sineFit)
minBorder = lenArray * 0.05
maxBorder = lenArray - minBorder
minInBorder = -1
maxInBorder = -1
for mini in minima:
if(mini < minBorder or mini > maxBorder):
minInBorder = mini
break
for maxi in maxima:
if(maxi < minBorder or maxi > maxBorder):
maxInBorder = maxi
break
if(minInBorder > 0 and maxInBorder > 0):
indMin = np.argwhere(minima == minInBorder)
indMax = np.argwhere(maxima == maxInBorder)
minima = np.delete(minima, indMin)
maxima = np.delete(maxima, indMax)
return minima, maxima return minima, maxima
def findNearestIndexOfValue(array, value): def findNearestIndexOfValue(array, value):
@@ -185,47 +215,153 @@ def getPhaseRangesNearPeak(maxArgs, phase, returnPhaseValue=False):
minPhases = phase[maxArgs[0]] minPhases = phase[maxArgs[0]]
maxPhases = phase[maxArgs[1]] maxPhases = phase[maxArgs[1]]
totalPhase = abs(phase[0]) + abs(phase[-1]) totalPhase = abs(phase[0]) + abs(phase[-1])
phasePart = totalPhase * 0.3 / (len(minPhases) + len(maxPhases))
minPhasesBounds = []
for minPhase in minPhases:
minPhaseBounds = []
if(minPhase - phasePart < phase[0]):
minPhaseBounds.append((phase[0], minPhase + phasePart))
minPhaseBounds.append((phase[-1] + (minPhase - phasePart - phase[0]), phase[-1]))
elif(minPhase + phasePart > phase[-1]):
minPhaseBounds.append((minPhase - phasePart, phase[-1]))
minPhaseBounds.append((phase[0], phase[0] + (minPhase + phasePart - phase[-1])))
else:
minPhaseBounds.append((minPhase - phasePart, minPhase + phasePart))
minPhasesBounds.append(minPhaseBounds)
maxPhasesBounds = []
for maxPhase in maxPhases:
maxPhaseBounds = []
if(maxPhase - phasePart < phase[0]):
maxPhaseBounds.append((phase[0], maxPhase + phasePart))
maxPhaseBounds.append((phase[-1] + (maxPhase - phasePart - phase[0]), phase[-1]))
elif(maxPhase + phasePart > phase[-1]):
maxPhaseBounds.append((maxPhase - phasePart, phase[-1]))
maxPhaseBounds.append((phase[0], phase[0] + (maxPhase + phasePart - phase[-1])))
else:
maxPhaseBounds.append((maxPhase - phasePart, maxPhase + phasePart))
maxPhasesBounds.append(maxPhaseBounds)
minPhasesBoundsIndices = [] minPhasesBoundsIndices = []
for minPhaseBounds in minPhasesBounds:
minPhaseBoundsIndices = []
for l in minPhaseBounds:
minPhaseBoundsIndices.append([phase[findNearestIndexOfValue(phase, lv)] if returnPhaseValue else findNearestIndexOfValue(phase, lv) for lv in l])
minPhasesBoundsIndices.append(minPhaseBoundsIndices)
maxPhasesBoundsIndices = [] maxPhasesBoundsIndices = []
for maxPhaseBounds in maxPhasesBounds:
maxPhaseBoundsIndices = [] if((len(minPhases) + len(maxPhases)) > 0):
for l in maxPhaseBounds: phasePart = totalPhase * 0.4 / (len(minPhases) + len(maxPhases))
maxPhaseBoundsIndices.append([phase[findNearestIndexOfValue(phase, lv)] if returnPhaseValue else findNearestIndexOfValue(phase, lv) for lv in l]) minPhasesBounds = []
maxPhasesBoundsIndices.append(maxPhaseBoundsIndices) for minPhase in minPhases:
minPhaseBounds = []
if(minPhase - phasePart < phase[0]):
minPhaseBounds.append([phase[0], minPhase + phasePart])
minPhaseBounds.append([phase[-1] + minPhase - phasePart - phase[0], phase[-1]])
elif(minPhase + phasePart > phase[-1]):
minPhaseBounds.append([minPhase - phasePart, phase[-1]])
minPhaseBounds.append([phase[0], phase[0] + minPhase + phasePart - phase[-1]])
else:
minPhaseBounds.append([minPhase - phasePart, minPhase + phasePart])
minPhasesBounds.append(minPhaseBounds)
maxPhasesBounds = []
for maxPhase in maxPhases:
maxPhaseBounds = []
if(maxPhase - phasePart < phase[0]):
maxPhaseBounds.append([phase[0], maxPhase + phasePart])
maxPhaseBounds.append([phase[-1] + maxPhase - phasePart - phase[0], phase[-1]])
elif(maxPhase + phasePart > phase[-1]):
maxPhaseBounds.append([maxPhase - phasePart, phase[-1]])
maxPhaseBounds.append([phase[0], phase[0] + maxPhase + phasePart - phase[-1]])
else:
maxPhaseBounds.append([maxPhase - phasePart, maxPhase + phasePart])
maxPhasesBounds.append(maxPhaseBounds)
i = 0; j = 0
while i < len(minPhasesBounds) and j < len(maxPhasesBounds):
#print(f"i: {i}", f"j: {j}")
if(len(minPhasesBounds[i]) == 1):
start_min, end_min = minPhasesBounds[i][0]
elif(len(minPhasesBounds[i]) == 2):
start_min, end_min = minPhasesBounds[i]
if(len(maxPhasesBounds[j]) == 1):
start_max, end_max = maxPhasesBounds[j][0]
elif(len(maxPhasesBounds[j]) == 2):
start_max, end_max = maxPhasesBounds[j]
#print(f"start_min type {type(start_min)}, {start_min}")
#print(f"end_min type {type(end_min)}, {end_min}")
#print(f"start_max type {type(start_max)}, {start_max}")
#print(f"end_max type {type(end_max)}, {end_max}")
if(isinstance(start_min, np.float64) and isinstance(end_min, np.float64) and
isinstance(start_max, np.float64) and isinstance(end_max, np.float64)):
#print("Case 1")
if(start_max < end_min and start_max > start_min):
overlap_start = max(start_min, start_max)
overlap_end = min(end_min, end_max)
midpoint = (overlap_start + overlap_end) / 2
minPhasesBounds[i] = [[start_min, midpoint - 0.01]]
maxPhasesBounds[j] = [[midpoint + 0.01, end_max]]
i += 1
j += 1
elif(start_min < end_max and start_max < start_min):
overlap_start = max(start_min, start_max)
overlap_end = min(end_min, end_max)
midpoint = (overlap_start + overlap_end) / 2
minPhasesBounds[i] = [[midpoint + 0.01, end_min]]
maxPhasesBounds[j] = [[start_max, midpoint - 0.01]]
i += 1
j += 1
else:
if end_min < start_max:
i += 1
elif end_max < start_min:
j += 1
elif(isinstance(start_max, np.float64) and isinstance(end_max, np.float64)): # Case 2
#print("Case 2")
if(start_min[0] < end_min[0]):
start_min1, end_min1 = start_min[0], start_min[1]
start_min2, end_min2 = end_min[0], end_min[1]
else:
start_min2, end_min2 = start_min[0], start_min[1]
start_min1, end_min1 = end_min[0], end_min[1]
if(start_max < start_min2 and end_max > start_min2): # 1
midpoint = (start_min2 + end_max) / 2
minPhasesBounds[i] = [[start_min1, end_min1], [midpoint + 0.01, end_min2]]
maxPhasesBounds[j] = [[start_max, midpoint - 0.01]]
i += 1
j += 1
elif(start_max > start_min1 and start_max < end_min1): # 2
midpoint = (start_max + end_min1) / 2
minPhasesBounds[i] = [[start_min1, midpoint - 0.01], [start_min2, end_min2]]
maxPhasesBounds[j] = [[midpoint + 0.01, end_max]]
i += 1
j += 1
else:
i += 1
j += 1
elif(isinstance(start_min, np.float64) and isinstance(end_min, np.float64)): # Case 3
#print("Case 3")
if(start_max[0] < end_max[0]):
start_max1, end_max1 = start_max[0], start_max[1]
start_max2, end_max2 = end_max[0], end_max[1]
else:
start_max2, end_max2 = start_max[0], start_max[1]
start_max1, end_max1 = end_max[0], end_max[1]
if(start_min > start_max1 and start_min < end_max1): # 1
midpoint = (start_min + end_max1) / 2
minPhasesBounds[i] = [[midpoint + 0.01, end_min]]
maxPhasesBounds[j] = [[start_max1, midpoint - 0.01], [start_max2, end_max2]]
i += 1
j += 1
elif(start_min < start_max2 and end_min > start_max2): # 2
midpoint = (start_max2 + end_min) / 2
minPhasesBounds[i] = [[start_min, midpoint - 0.01]]
maxPhasesBounds[j] = [[start_max1, end_max1], [midpoint + 0.01, end_max2]]
i += 1
j += 1
else:
i += 1
j += 1
else:
print("Rare case of both going over the border, this shouldnt happen, remove them")
minPhasesBounds.pop(i)
maxPhasesBounds.pop(j)
for minPhaseBounds in minPhasesBounds:
minPhaseBoundsIndices = []
for l in minPhaseBounds:
minPhaseBoundsIndices.append([phase[findNearestIndexOfValue(phase, lv)] if returnPhaseValue else findNearestIndexOfValue(phase, lv) for lv in l])
minPhasesBoundsIndices.append(minPhaseBoundsIndices)
for maxPhaseBounds in maxPhasesBounds:
maxPhaseBoundsIndices = []
for l in maxPhaseBounds:
maxPhaseBoundsIndices.append([phase[findNearestIndexOfValue(phase, lv)] if returnPhaseValue else findNearestIndexOfValue(phase, lv) for lv in l])
maxPhasesBoundsIndices.append(maxPhaseBoundsIndices)
return minPhasesBoundsIndices, maxPhasesBoundsIndices return minPhasesBoundsIndices, maxPhasesBoundsIndices
BIN
View File
Binary file not shown.