Skip to content

Commit

Permalink
Merge branch 'dev' into feature/auto-focus
Browse files Browse the repository at this point in the history
  • Loading branch information
tiagohm committed Apr 1, 2024
2 parents f321e0e + 17e5b39 commit 3666fe4
Show file tree
Hide file tree
Showing 331 changed files with 9,560 additions and 7,207 deletions.
3 changes: 2 additions & 1 deletion .gitattributes
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,12 @@
*.jar binary
*.fit binary
*.fits binary
*.xisf binary
*.ttf binary
*.xcf binary
*.png binary
*.db binary
*.gz binary
*.dll binary
*.so binary
*.zip binary
*.zip binary
3 changes: 0 additions & 3 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,9 @@ on:
branches: [ main ]
paths:
- '**.kt'
- '**/src/test/resources/**'
pull_request:
branches: [ main ]
paths:
- '**.kt'
- '**/src/test/resources/**'
workflow_dispatch:

jobs:
Expand Down
3 changes: 0 additions & 3 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,3 @@ libobjectbox*.dylib
.kotlin

# End of https://www.toptal.com/developers/gitignore/api/intellij,kotlin,java,gradle

**/saved/*.png
**/saved/*.jpg
2 changes: 1 addition & 1 deletion GitHub CI.run.xml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
<option name="externalSystemIdString"
value="GRADLE"/>
<option name="scriptParameters"
value="-Dgithub=true"/>
value="-Dgithub=true --continue"/>
<option name="taskDescriptions">
<list/>
</option>
Expand Down
7 changes: 4 additions & 3 deletions api/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import org.springframework.boot.gradle.tasks.bundling.BootJar

plugins {
kotlin("jvm")
id("org.springframework.boot") version "3.2.3"
id("org.springframework.boot") version "3.2.4"
id("io.spring.dependency-management") version "1.1.4"
kotlin("plugin.spring")
kotlin("kapt")
Expand All @@ -19,7 +19,7 @@ dependencies {
implementation(project(":nebulosa-guiding-phd2"))
implementation(project(":nebulosa-hips2fits"))
implementation(project(":nebulosa-horizons"))
implementation(project(":nebulosa-imaging"))
implementation(project(":nebulosa-image"))
implementation(project(":nebulosa-indi-client"))
implementation(project(":nebulosa-log"))
implementation(project(":nebulosa-lx200-protocol"))
Expand All @@ -29,6 +29,7 @@ dependencies {
implementation(project(":nebulosa-stellarium-protocol"))
implementation(project(":nebulosa-watney"))
implementation(project(":nebulosa-wcs"))
implementation(project(":nebulosa-xisf"))
implementation(libs.apache.codec)
implementation(libs.csv)
implementation(libs.eventbus)
Expand All @@ -45,7 +46,7 @@ dependencies {
implementation("org.springframework.boot:spring-boot-starter-undertow")
implementation("org.jetbrains.kotlin:kotlin-reflect")
implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")
kapt("org.springframework:spring-context-indexer:6.1.4")
kapt("org.springframework:spring-context-indexer:6.1.5")
testImplementation(project(":nebulosa-astrobin-api"))
testImplementation(project(":nebulosa-skycatalog-stellarium"))
testImplementation(project(":nebulosa-test"))
Expand Down
2 changes: 1 addition & 1 deletion api/src/main/kotlin/nebulosa/api/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ URL: `localhost:{PORT}/ws`
"offset": 0,
"offsetMin": 0,
"offsetMax": 0,
"hasGuiderHead": false,
"hasGuideHead": false,
"pixelSizeX": 0,
"pixelSizeY": 0,
"capturesPath": "",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,12 @@ import nebulosa.batch.processing.ExecutionContext.Companion.getDouble
import nebulosa.batch.processing.ExecutionContext.Companion.getDuration
import nebulosa.batch.processing.delay.DelayStep
import nebulosa.batch.processing.delay.DelayStepListener
import nebulosa.image.format.ImageRepresentation
import nebulosa.indi.device.camera.Camera
import nebulosa.indi.device.camera.FrameType
import nebulosa.indi.device.guide.GuideOutput
import java.nio.file.Files
import java.nio.file.Path
import java.time.Duration

data class DARVJob(
Expand Down Expand Up @@ -65,8 +67,8 @@ data class DARVJob(
onNext(DARVEvent.Finished(id))
}

override fun onExposureFinished(step: CameraExposureStep, stepExecution: StepExecution) {
onNext(CameraExposureFinished(stepExecution.jobExecution, step.camera, 1, 1, Duration.ZERO, 1.0, Duration.ZERO, step.savedPath!!))
override fun onExposureFinished(step: CameraExposureStep, stepExecution: StepExecution, image: ImageRepresentation?, savedPath: Path) {
onNext(CameraExposureFinished(stepExecution.jobExecution, step.camera, 1, 1, Duration.ZERO, 1.0, Duration.ZERO, savedPath))
}

override fun onGuidePulseElapsed(step: GuidePulseStep, stepExecution: StepExecution) {
Expand Down
21 changes: 13 additions & 8 deletions api/src/main/kotlin/nebulosa/api/alignment/polar/tppa/TPPAStep.kt
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,15 @@ import nebulosa.batch.processing.StepExecution
import nebulosa.batch.processing.StepResult
import nebulosa.common.concurrency.latch.Pauseable
import nebulosa.common.time.Stopwatch
import nebulosa.fits.fits
import nebulosa.imaging.Image
import nebulosa.image.format.ImageRepresentation
import nebulosa.indi.device.camera.Camera
import nebulosa.indi.device.mount.Mount
import nebulosa.log.debug
import nebulosa.log.loggerFor
import nebulosa.math.Angle
import nebulosa.math.deg
import nebulosa.plate.solving.PlateSolver
import java.nio.file.Path

data class TPPAStep(
@JvmField val camera: Camera,
Expand All @@ -30,18 +30,18 @@ data class TPPAStep(
private val longitude: Angle = mount!!.longitude,
private val latitude: Angle = mount!!.latitude,
private val cameraRequest: CameraStartCaptureRequest = request.capture,
) : Step, Pauseable {
) : Step, Pauseable, CameraCaptureListener {

private val cameraExposureStep = CameraExposureStep(camera, cameraRequest)
private val alignment = ThreePointPolarAlignment(solver, longitude, latitude)
private val listeners = LinkedHashSet<TPPAListener>()
private val stopwatch = Stopwatch()
private val stepDistances = DoubleArray(2) { if (request.eastDirection) request.stepDistance else -request.stepDistance }

@Volatile private var image: Image? = null
@Volatile private var mountSlewStep: MountSlewStep? = null
@Volatile private var noSolutionAttempts = 0
@Volatile private var stepExecution: StepExecution? = null
@Volatile private var savedImage: Pair<ImageRepresentation?, Path>? = null

val stepCount
get() = alignment.state
Expand All @@ -65,20 +65,26 @@ data class TPPAStep(
return listeners.remove(listener)
}

override fun onExposureFinished(step: CameraExposureStep, stepExecution: StepExecution, image: ImageRepresentation?, savedPath: Path) {
savedImage = image to savedPath
}

override fun beforeJob(jobExecution: JobExecution) {
cameraExposureStep.registerCameraCaptureListener(this)
cameraExposureStep.beforeJob(jobExecution)
mount?.tracking(true)
}

override fun afterJob(jobExecution: JobExecution) {
cameraExposureStep.afterJob(jobExecution)
cameraExposureStep.unregisterCameraCaptureListener(this)

if (mount != null && request.stopTrackingWhenDone) {
mount.tracking(false)
}

savedImage = null
stopwatch.stop()

listeners.forEach { it.polarAlignmentFinished(this, jobExecution.cancellationToken.isCancelled) }
}

Expand Down Expand Up @@ -119,14 +125,13 @@ data class TPPAStep(
cameraExposureStep.execute(stepExecution)

if (!cancellationToken.isCancelled) {
val savedPath = cameraExposureStep.savedPath ?: return StepResult.FINISHED
image = savedPath.fits().use { image?.load(it, false) ?: Image.open(it, false) }
val saved = savedImage ?: return StepResult.FINISHED

val radius = if (mount == null) 0.0 else ThreePointPolarAlignment.DEFAULT_RADIUS

// Polar alignment step.
val result = alignment.align(
savedPath, image!!, mount?.rightAscension ?: 0.0, mount?.declination ?: 0.0, radius,
saved.second, mount?.rightAscension ?: 0.0, mount?.declination ?: 0.0, radius,
request.compensateRefraction, cancellationToken
)

Expand Down
47 changes: 47 additions & 0 deletions api/src/main/kotlin/nebulosa/api/atlas/CloseApproach.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package nebulosa.api.atlas

import nebulosa.constants.AU_KM
import nebulosa.sbd.SmallBodyIdentified
import java.time.LocalDateTime
import java.time.ZoneOffset
import java.time.format.DateTimeFormatter
import java.util.*

data class CloseApproach(
val name: String = "",
val designation: String = "",
val dateTime: Long = 0,
val distance: Double = 0.0,
val absoluteMagnitude: Double = 0.0,
) {

companion object {

@JvmStatic val EMPTY = CloseApproach()

@JvmStatic private val DATE_TIME_FORMAT = DateTimeFormatter.ofPattern("yyyy-LLL-dd HH:mm", Locale.ENGLISH)

@JvmStatic
fun of(body: SmallBodyIdentified): List<CloseApproach> {
val data = ArrayList<CloseApproach>(body.count)

val nameIdx = body.fields.indexOf("fullname")
val desIdx = body.fields.indexOf("des")
val cdIdx = body.fields.indexOf("cd")
val distIdx = body.fields.indexOf("dist")
val hIdx = body.fields.indexOf("h")

for (entry in body.data) {
val name = entry[nameIdx].trim()
val designation = entry[desIdx].trim()
val dateTime = LocalDateTime.parse(entry[cdIdx].trim(), DATE_TIME_FORMAT).toEpochSecond(ZoneOffset.UTC) * 1000L
val distance = entry[distIdx].trim().toDouble() * AU_KM / 384400.0
val absoluteMagnitude = entry[hIdx].trim().toDouble()

data.add(CloseApproach(name, designation, dateTime, distance, absoluteMagnitude))
}

return data
}
}
}
10 changes: 10 additions & 0 deletions api/src/main/kotlin/nebulosa/api/atlas/SkyAtlasController.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,20 @@ import jakarta.servlet.http.HttpServletResponse
import jakarta.validation.Valid
import jakarta.validation.constraints.Min
import jakarta.validation.constraints.NotBlank
import jakarta.validation.constraints.Positive
import nebulosa.api.beans.converters.device.DeviceOrEntityParam
import nebulosa.api.beans.converters.location.LocationParam
import nebulosa.api.beans.converters.time.DateAndTimeParam
import nebulosa.math.deg
import nebulosa.math.hours
import nebulosa.nova.astrometry.Constellation
import nebulosa.skycatalog.SkyObjectType
import org.springframework.validation.annotation.Validated
import org.springframework.web.bind.annotation.*
import java.time.LocalDate
import java.time.LocalDateTime

@Validated
@RestController
@RequestMapping("sky-atlas")
class SkyAtlasController(
Expand Down Expand Up @@ -70,6 +73,13 @@ class SkyAtlasController(
@GetMapping("minor-planets")
fun searchMinorPlanet(@RequestParam @Valid @NotBlank text: String) = skyAtlasService.searchMinorPlanet(text)

@GetMapping("minor-planets/close-approaches")
fun closeApproachesForMinorPlanets(
@RequestParam(required = false, defaultValue = "7") @Valid @Positive days: Long,
@RequestParam(required = false, defaultValue = "10") @Valid @Positive distance: Double,
@DateAndTimeParam(nullable = true) dateTime: LocalDate?,
) = skyAtlasService.closeApproachesForMinorPlanets(days, distance, dateTime)

@GetMapping("sky-objects/{id}/position")
fun positionOfSkyObject(
@PathVariable id: Long,
Expand Down
5 changes: 5 additions & 0 deletions api/src/main/kotlin/nebulosa/api/atlas/SkyAtlasService.kt
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,11 @@ class SkyAtlasService(
?.let(MinorPlanet::of)
?: MinorPlanet.EMPTY

fun closeApproachesForMinorPlanets(days: Long, distance: Double, date: LocalDate?) = smallBodyDatabaseService
.closeApproaches(days, distance, date).execute().body()
?.let(CloseApproach::of)
?: emptyList()

fun searchSkyObject(
text: String? = null,
rightAscension: Angle = 0.0, declination: Angle = 0.0, radius: Angle = 0.0,
Expand Down
10 changes: 6 additions & 4 deletions api/src/main/kotlin/nebulosa/api/atlas/SkyAtlasUpdateTask.kt
Original file line number Diff line number Diff line change
Expand Up @@ -74,10 +74,12 @@ class SkyAtlasUpdateTask(

httpClient.newCall(request).execute().use {
if (it.isSuccessful) {
val reader = SimbadDatabaseReader(it.body!!.byteStream().source())

for (entity in reader) {
simbadEntityRepository.save(entity)
it.body!!.byteStream().source().use { source ->
SimbadDatabaseReader(source).use { reader ->
for (entity in reader) {
simbadEntityRepository.save(entity)
}
}
}
} else if (it.code == 404) {
finished = true
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import nebulosa.guiding.Guider
import nebulosa.guiding.phd2.PHD2Guider
import nebulosa.hips2fits.Hips2FitsService
import nebulosa.horizons.HorizonsService
import nebulosa.imaging.Image
import nebulosa.image.Image
import nebulosa.log.loggerFor
import nebulosa.phd2.client.PHD2Client
import nebulosa.sbd.SmallBodyDatabaseService
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,5 @@ annotation class DateAndTimeParam(
val datePattern: String = "yyyy-MM-dd",
val timePattern: String = "HH:mm",
val noSeconds: Boolean = true,
val nullable: Boolean = false,
)
Original file line number Diff line number Diff line change
Expand Up @@ -31,22 +31,22 @@ class DateAndTimeParamMethodArgumentResolver : HandlerMethodArgumentResolver {
val dateAndTimeParam = parameter.annotation<DateAndTimeParam>()!!
val type = parameter.parameterType

val dateValue = webRequest.parameter("date")
val timeValue = webRequest.parameter("time")
val dateValue = webRequest.parameter("date")?.ifBlank { null }
val timeValue = webRequest.parameter("time")?.ifBlank { null }

val date = dateValue?.ifBlank { null }
val date = dateValue
?.let { LocalDate.parse(it, DateTimeFormatter.ofPattern(dateAndTimeParam.datePattern)) }
?: LocalDate.now()
?: if (dateAndTimeParam.nullable) null else LocalDate.now()

if (type === LocalDate::class.java) return date

val time = timeValue?.ifBlank { null }
val time = timeValue
?.let { LocalTime.parse(it, DateTimeFormatter.ofPattern(dateAndTimeParam.timePattern)) }
?: LocalTime.now()
?: if (dateAndTimeParam.nullable) null else LocalTime.now()

if (type === LocalTime::class.java) return time

return LocalDateTime.of(date, time)
return LocalDateTime.of(date ?: LocalDate.now(), time ?: LocalTime.now())
.let { if (dateAndTimeParam.noSeconds) it.withSecond(0).withNano(0) else it }
}
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
package nebulosa.api.calibration

import nebulosa.fits.*
import nebulosa.imaging.Image
import nebulosa.imaging.algorithms.transformation.correction.BiasSubtraction
import nebulosa.imaging.algorithms.transformation.correction.DarkSubtraction
import nebulosa.imaging.algorithms.transformation.correction.FlatCorrection
import nebulosa.image.Image
import nebulosa.image.algorithms.transformation.correction.BiasSubtraction
import nebulosa.image.algorithms.transformation.correction.DarkSubtraction
import nebulosa.image.algorithms.transformation.correction.FlatCorrection
import nebulosa.image.format.Header
import nebulosa.image.format.ImageHdu
import nebulosa.image.format.ReadableHeader
import nebulosa.indi.device.camera.FrameType
import nebulosa.log.loggerFor
import org.springframework.stereotype.Service
Expand All @@ -31,7 +34,7 @@ class CalibrationFrameService(

return if (darkFrame != null || biasFrame != null || flatFrame != null) {
var transformedImage = if (createNew) image.clone() else image
var calibrationImage = Image(transformedImage.width, transformedImage.height, Header.EMPTY, transformedImage.mono)
var calibrationImage = Image(transformedImage.width, transformedImage.height, Header.Empty, transformedImage.mono)

if (biasFrame != null) {
calibrationImage = biasFrame.path!!.fits().use(calibrationImage::load)!!
Expand Down Expand Up @@ -98,7 +101,8 @@ class CalibrationFrameService(

try {
file.fits().use { fits ->
val (header) = fits.filterIsInstance<ImageHdu>().firstOrNull() ?: return@use
val hdu = fits.filterIsInstance<ImageHdu>().firstOrNull() ?: return@use
val header = hdu.header
val frameType = header.frameType?.takeIf { it != FrameType.LIGHT } ?: return@use

val exposureTime = if (frameType == FrameType.DARK) header.exposureTimeInMicroseconds else 0L
Expand Down Expand Up @@ -174,7 +178,7 @@ class CalibrationFrameService(

@JvmStatic private val LOG = loggerFor<CalibrationFrameService>()

@JvmStatic val Header.frameType
@JvmStatic val ReadableHeader.frameType
get() = frame?.uppercase()?.let {
if ("LIGHT" in it) FrameType.LIGHT
else if ("DARK" in it) FrameType.DARK
Expand Down
Loading

0 comments on commit 3666fe4

Please sign in to comment.