Skip to content

Commit

Permalink
[api][desktop]: Add calibrationGroup option on Live Stacking
Browse files Browse the repository at this point in the history
  • Loading branch information
tiagohm committed Aug 17, 2024
1 parent 0ae9aef commit 02eec09
Show file tree
Hide file tree
Showing 8 changed files with 70 additions and 26 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import java.nio.file.Path
import java.util.EnumMap
import kotlin.io.path.deleteRecursively
import kotlin.io.path.exists
import kotlin.io.path.isRegularFile

data class CameraLiveStackingManager(
private val calibrationFrameProvider: CalibrationFrameProvider? = null,
Expand Down Expand Up @@ -132,20 +133,17 @@ data class CameraLiveStackingManager(
calibrationGroup, temperature, binX, binY, width, height, exposureTime, gain, filter
)

val newDarkPath = darkPath?.takeIf { it.exists() } ?: calibrationFrameProvider
val newDarkPath = (if (useCalibrationGroup) calibrationFrameProvider
.findBestDarkFrames(calibrationGroup, temperature, width, height, binX, binY, exposureTime, gain)
.firstOrNull()
?.path
.firstOrNull()?.path else darkPath)?.takeIf { it.isCalibrationFrame }

val newFlatPath = flatPath?.takeIf { it.exists() } ?: calibrationFrameProvider
val newFlatPath = (if (useCalibrationGroup) calibrationFrameProvider
.findBestFlatFrames(calibrationGroup, width, height, binX, binY, filter)
.firstOrNull()
?.path
.firstOrNull()?.path else flatPath)?.takeIf { it.isCalibrationFrame }

val newBiasPath = if (newDarkPath != null) null else biasPath?.takeIf { it.exists() } ?: calibrationFrameProvider
val newBiasPath = (if (newDarkPath != null) null else if (useCalibrationGroup) calibrationFrameProvider
.findBestBiasFrames(calibrationGroup, width, height, binX, binY)
.firstOrNull()
?.path
.firstOrNull()?.path else biasPath)?.takeIf { it.isCalibrationFrame }

LOG.info(
"live stacking will use calibration frames. group={}, dark={}, flat={}, bias={}",
Expand All @@ -161,5 +159,8 @@ data class CameraLiveStackingManager(
companion object {

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

private inline val Path?.isCalibrationFrame
get() = this != null && exists() && isRegularFile() && (isFits() || isXisf())
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ data class LiveStackingRequest(
@JvmField val biasPath: Path? = null,
@JvmField val use32Bits: Boolean = false,
@JvmField val slot: Int = 1,
@JvmField val useCalibrationGroup: Boolean = false,
) {

fun get(workingDirectory: Path): LiveStacker {
Expand Down
14 changes: 11 additions & 3 deletions desktop/src/app/camera/camera.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -641,8 +641,16 @@
(ngModelChange)="savePreference()" />
</div>
<div class="col-12 align-items-center">
<neb-path-chooser
<p-checkbox
[binary]="true"
[disabled]="!liveStacking.request.enabled"
label="Use Camera's calibration group"
[(ngModel)]="liveStacking.request.useCalibrationGroup"
(ngModelChange)="savePreference()" />
</div>
<div class="col-12 align-items-center">
<neb-path-chooser
[disabled]="!liveStacking.request.enabled || liveStacking.request.useCalibrationGroup"
[directory]="false"
label="Dark File"
key="liveStackerDarkFile"
Expand All @@ -652,7 +660,7 @@
</div>
<div class="col-12 align-items-center">
<neb-path-chooser
[disabled]="!liveStacking.request.enabled"
[disabled]="!liveStacking.request.enabled || liveStacking.request.useCalibrationGroup"
[directory]="false"
label="Flat File"
key="liveStackerFlatFile"
Expand All @@ -662,7 +670,7 @@
</div>
<div class="col-12 align-items-center">
<neb-path-chooser
[disabled]="!liveStacking.request.enabled || liveStacking.request.type !== 'PIXINSIGHT'"
[disabled]="!liveStacking.request.enabled || liveStacking.request.type !== 'PIXINSIGHT' || liveStacking.request.useCalibrationGroup"
[directory]="false"
label="Bias File"
key="liveStackerDarkFile"
Expand Down
39 changes: 31 additions & 8 deletions desktop/src/app/sequencer/sequencer.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,17 @@
[autoDisplayFirst]="false"
(ngModelChange)="savePreference()"
appendTo="body" />
<p-dropdown
*ngIf="plan.liveStacking.enabled && plan.liveStacking.useCalibrationGroup"
[disabled]="sequence.stackerGroupType === 'NONE' || running"
[options]="calibrationGroups"
optionLabel="label"
optionValue="value"
[(ngModel)]="sequence.calibrationGroup"
styleClass="border-0 p-inputtext-sm"
[autoDisplayFirst]="false"
(ngModelChange)="savePreference()"
appendTo="body" />
</div>
<div class="col pb-1 pr-4 align-items-center justify-content-end gap-2">
<p-button
Expand Down Expand Up @@ -495,8 +506,8 @@
<div class="align-content-start justify-content-center align-items-center flex flex-row flex-wrap gap-3 justify-content-start pt-3 px-4">
<p-floatLabel class="min-w-12rem">
<p-dropdown
[disabled]="!plan.liveStacking.enabled"
[options]="'LIVE_STACKER' | dropdownOptions | enumDropdown"
[disabled]="!plan.liveStacking.enabled || running"
[options]="['PIXINSIGHT'] | enumDropdown"
[(ngModel)]="plan.liveStacking.type"
optionsLabel="label"
optionsValue="value"
Expand All @@ -509,28 +520,34 @@
<div class="col-2 flex flex-column align-items-center justify-content-center text-center gap-2">
<span class="text-sm text-gray-100">32-bit (slower)</span>
<p-inputSwitch
[disabled]="!plan.liveStacking.enabled"
[disabled]="!plan.liveStacking.enabled || running"
[(ngModel)]="plan.liveStacking.use32Bits"
(ngModelChange)="savePreference()" />
</div>
<p-checkbox
[binary]="true"
[disabled]="!plan.liveStacking.enabled || running"
label="Use calibration group"
[(ngModel)]="plan.liveStacking.useCalibrationGroup"
(ngModelChange)="savePreference()" />
<neb-path-chooser
[disabled]="!plan.liveStacking.enabled"
[disabled]="!plan.liveStacking.enabled || plan.liveStacking.useCalibrationGroup || running"
[directory]="false"
label="Dark File"
key="liveStackerDarkFile"
[(path)]="plan.liveStacking.darkPath"
class="min-w-22rem"
(pathChange)="savePreference()" />
<neb-path-chooser
[disabled]="!plan.liveStacking.enabled"
[disabled]="!plan.liveStacking.enabled || plan.liveStacking.useCalibrationGroup || running"
[directory]="false"
label="Flat File"
key="liveStackerFlatFile"
[(path)]="plan.liveStacking.flatPath"
class="min-w-22rem"
(pathChange)="savePreference()" />
<neb-path-chooser
[disabled]="!plan.liveStacking.enabled || plan.liveStacking.type !== 'PIXINSIGHT'"
[disabled]="!plan.liveStacking.enabled || plan.liveStacking.type !== 'PIXINSIGHT' || plan.liveStacking.useCalibrationGroup || running"
[directory]="false"
label="Bias File"
key="liveStackerDarkFile"
Expand Down Expand Up @@ -680,13 +697,19 @@
label="Offset"
[(ngModel)]="property.properties.OFFSET" />
</div>
<div class="col-6">
<p-checkbox
[binary]="true"
label="Calibration Group"
[(ngModel)]="property.properties.CALIBRATION_GROUP" />
</div>
<div
*ngIf="plan.liveStacking.enabled"
class="col-6">
<p-checkbox
[binary]="true"
label="Live Stacking Group"
[(ngModel)]="property.properties.STACKER_GROUP_TYPE" />
label="Stacking Group"
[(ngModel)]="property.properties.STACKING_GROUP" />
</div>
</div>
<ng-template pTemplate="footer">
Expand Down
11 changes: 9 additions & 2 deletions desktop/src/app/sequencer/sequencer.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { BrowserWindowService } from '../../shared/services/browser-window.servi
import { ElectronService } from '../../shared/services/electron.service'
import { PreferenceService } from '../../shared/services/preference.service'
import { Tickable, Ticker } from '../../shared/services/ticker.service'
import { DropdownItem } from '../../shared/types/angular.types'
import { JsonFile } from '../../shared/types/app.types'
import { Camera, cameraCaptureNamingFormatWithDefault, FrameType, updateCameraStartCaptureFromCamera } from '../../shared/types/camera.types'
import { Focuser } from '../../shared/types/focuser.types'
Expand All @@ -19,7 +20,7 @@ import { Rotator } from '../../shared/types/rotator.types'
import { DEFAULT_SEQUENCE, DEFAULT_SEQUENCE_PROPERTY_DIALOG, DEFAULT_SEQUENCER_PLAN, DEFAULT_SEQUENCER_PREFERENCE, Sequence, SequenceProperty, SequencerEvent, SequencerPlan, sequencerPlanWithDefault } from '../../shared/types/sequencer.types'
import { resetCameraCaptureNamingFormat } from '../../shared/types/settings.types'
import { Wheel } from '../../shared/types/wheel.types'
import { deviceComparator } from '../../shared/utils/comparators'
import { deviceComparator, textComparator } from '../../shared/utils/comparators'
import { AppComponent } from '../app.component'
import { CameraComponent } from '../camera/camera.component'
import { FilterWheelComponent } from '../filterwheel/filterwheel.component'
Expand All @@ -39,6 +40,7 @@ export class SequencerComponent implements AfterContentInit, OnDestroy, Tickable

protected readonly property = structuredClone(DEFAULT_SEQUENCE_PROPERTY_DIALOG)
protected readonly preference = structuredClone(DEFAULT_SEQUENCER_PREFERENCE)
protected readonly calibrationGroups: DropdownItem<string | undefined>[] = []
protected plan = this.preference.plan
protected event?: SequencerEvent
protected running = false
Expand Down Expand Up @@ -267,6 +269,10 @@ export class SequencerComponent implements AfterContentInit, OnDestroy, Tickable
this.focusers = (await this.api.focusers()).sort(deviceComparator)
this.rotators = (await this.api.rotators()).sort(deviceComparator)

const calibrationGroups = (await this.api.calibrationGroups()).sort(textComparator)
this.calibrationGroups.push({ label: 'None', value: undefined })
calibrationGroups.forEach((e) => this.calibrationGroups.push({ label: e, value: e }))

this.loadPreference()

await this.loadPlanFromPath()
Expand Down Expand Up @@ -541,7 +547,8 @@ export class SequencerComponent implements AfterContentInit, OnDestroy, Tickable
if (this.property.properties.FRAME_FORMAT) dest.frameFormat = source.frameFormat
if (this.property.properties.GAIN) dest.gain = source.gain
if (this.property.properties.OFFSET) dest.offset = source.offset
if (this.plan.liveStacking.enabled && this.property.properties.STACKER_GROUP_TYPE) dest.stackerGroupType = source.stackerGroupType
if (this.plan.liveStacking.enabled && this.property.properties.STACKING_GROUP) dest.stackerGroupType = source.stackerGroupType
if (this.plan.liveStacking.useCalibrationGroup && this.property.properties.CALIBRATION_GROUP) dest.calibrationGroup = source.calibrationGroup
} else {
break
}
Expand Down
2 changes: 1 addition & 1 deletion desktop/src/shared/services/browser-window.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ export class BrowserWindowService {
}

openSequencer(preference: WindowPreference = {}) {
Object.assign(preference, { icon: 'workflow', width: 628, height: 570, resizable: true, minWidth: 628, minHeight: 328 })
Object.assign(preference, { icon: 'workflow', width: 628, height: 467, resizable: true, minWidth: 628, minHeight: 328 })
return this.openWindow({ preference, id: 'sequencer', path: 'sequencer' })
}

Expand Down
5 changes: 4 additions & 1 deletion desktop/src/shared/types/camera.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,7 @@ export interface LiveStackingRequest extends LiveStackerSettings {
flatPath?: string
biasPath?: string
use32Bits: boolean
useCalibrationGroup: boolean
}

export interface CameraDitherDialog {
Expand Down Expand Up @@ -270,8 +271,9 @@ export const DEFAULT_LIVE_STACKER_SETTINGS: LiveStackerSettings = {
export const DEFAULT_LIVE_STACKING_REQUEST: LiveStackingRequest = {
...DEFAULT_LIVE_STACKER_SETTINGS,
enabled: false,
type: 'SIRIL',
type: 'PIXINSIGHT',
use32Bits: false,
useCalibrationGroup: false,
}

export const CAMERA_CAPTURE_NAMING_FORMAT_LIGHT = '[camera]_[type]_[year:2][month][day][hour][min][sec][ms]_[filter]_[width]_[height]_[exp]_[bin]_[gain]'
Expand Down Expand Up @@ -404,6 +406,7 @@ export function liveStackingRequestWithDefault(request?: Partial<LiveStackingReq
request.enabled ??= source.enabled
request.type ||= source.type
request.use32Bits ??= source.use32Bits
request.useCalibrationGroup ??= source.useCalibrationGroup
return request as LiveStackingRequest
}

Expand Down
5 changes: 3 additions & 2 deletions desktop/src/shared/types/sequencer.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ export type SequencerCaptureMode = 'FULLY' | 'INTERLEAVED'

export type SequencerState = 'IDLE' | 'PAUSING' | 'PAUSED' | 'RUNNING'

export type SequenceProperty = 'EXPOSURE_TIME' | 'EXPOSURE_AMOUNT' | 'EXPOSURE_DELAY' | 'FRAME_TYPE' | 'X' | 'Y' | 'WIDTH' | 'HEIGHT' | 'BIN' | 'FRAME_FORMAT' | 'GAIN' | 'OFFSET' | 'STACKER_GROUP_TYPE'
export type SequenceProperty = 'EXPOSURE_TIME' | 'EXPOSURE_AMOUNT' | 'EXPOSURE_DELAY' | 'FRAME_TYPE' | 'X' | 'Y' | 'WIDTH' | 'HEIGHT' | 'BIN' | 'FRAME_FORMAT' | 'GAIN' | 'OFFSET' | 'STACKING_GROUP' | 'CALIBRATION_GROUP'

export type SequenceProperties = Record<SequenceProperty, boolean>

Expand Down Expand Up @@ -130,7 +130,8 @@ export const DEFAULT_SEQUENCE_PROPERTIES: SequenceProperties = {
FRAME_FORMAT: true,
GAIN: true,
OFFSET: true,
STACKER_GROUP_TYPE: false,
STACKING_GROUP: false,
CALIBRATION_GROUP: false,
}

export const DEFAULT_SEQUENCE_PROPERTY_DIALOG: SequencePropertyDialog = {
Expand Down

0 comments on commit 02eec09

Please sign in to comment.