Skip to content

Commit

Permalink
Adding supoprt for linear/circular polarization (#56)
Browse files Browse the repository at this point in the history
* Release scripts

* Fixed version string

* Run RFS in any case

* Better settings parsing

* Using different jobs

* Reviewing retractor behavior

* Different method for computing positions

* Modified build scripts

* Keeping debug_image

* Informing user & logging with DI

* Using injected entities

* removed unused setting

* Fixed message formatting

* Changed default settins

* Simplifying camera usage

* Improved shutter handling

* Fixed Shutter Action

* Trimming debug code

* Refactoring

* Renaming cycle types

* Backwards-compatibility for target deserialization

* Refactored model

* Injecting logger and user notifier

* Modifying enum displayed text in job settings window

* More flexible conversion

* Extension methods for CycleType

* Rearranging job settings

* Changed wording

* Adding circular polarimetry

* Marked problematic code paths

* Updating gitignore

* Enum representations

* Implementing Enum -> String conversion

* Migrating codebase

* Storing additional field in EnumNameRep

* Implementing enum parsing

* Refactoring Helpers & Converters

* Refactoring

* Refactoring

* Fixed Debug camera

* Drawing polarization symbol

* Recording instrument regime in  FITS

* Fixed errors

* Improving layout

* Fixed Debug Camera image area

* Notifying if the cycle type has changed

* Fixed typo
  • Loading branch information
Ilia-Kosenkov authored Jun 6, 2021
1 parent 54effe5 commit 6e8a71e
Show file tree
Hide file tree
Showing 41 changed files with 1,400 additions and 715 deletions.
8 changes: 7 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,13 @@ Releases/*
!src/DIPOL-UF/ui-config.json
!src/DIPOL-UF/config.json
!src/DIPOL-UF/user-allowed-setts.json
!src/ANDOR-CS/debug_image.fits
!**/FodyWeavers.xml
!src/DIPOL-UF/sample_star.json
!src/DIPOL-UF/App.config
!src/ANDOR-CS/DebugData/*
!src/ANDOR-CS/DebugData/*

scripts/*
!scripts/*ps1
*.xsd
src/DIPOL-UF/FodyWeavers.xsd
28 changes: 28 additions & 0 deletions scripts/build-gui.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
param (
[string]$PathToSrc,
[string]$OutputDir = "./Releases",
[string]$Arch = "x64",
[string]$Configuration = "Release"
)

$csprojPath = "$PathToSrc/DIPOL-UF/DIPOL-UF.csproj"

# Restore and build project
MSBuild.exe $csprojPath -t:restore -verbosity:minimal
MSBuild.exe $csprojPath -p:Configuration=$Configuration -p:Platform=$Arch -verbosity:minimal

$regex = [System.Text.RegularExpressions.Regex]::new("^\s*\[assembly:\s*AssemblyVersion\s*\(\s*`"(\d+\.\d+.\d+)`"\s*\)\s*\]");

# Finds version string in the AssemblyInfo.cs
$version = Get-Content "$PathToSrc/DIPOL-UF/Properties/AssemblyInfo.cs" | `
ForEach-Object {$regex.Matches($_)} | `
Where-Object {$_.Success} | `
ForEach-Object {$_.Groups[1].Value}

# Creates output directory if it is missing
$dir = "$OutputDir/DIPOL-UF_$($Configuration)_$($Arch)_v$version"
New-Item $dir -Force -ItemType Directory -ErrorAction SilentlyContinue

# Copies items one by one
Get-ChildItem "$PathToSrc/DIPOL-UF/bin/$Arch/$Configuration/" | `
ForEach-Object {Copy-Item -Path $($_.FullName) -Destination "$dir\"}
28 changes: 28 additions & 0 deletions scripts/build-host.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
param (
[string]$PathToSrc,
[string]$OutputDir = "./Hosts",
[string]$Arch = "x64",
[string]$Configuration = "Release"
)

$csprojPath = "$PathToSrc/Host/Host.csproj"

# Restore and build project
MSBuild.exe $csprojPath -t:restore -verbosity:minimal
MSBuild.exe $csprojPath -p:Configuration=$Configuration -p:Platform=$Arch -verbosity:minimal

$regex = [System.Text.RegularExpressions.Regex]::new("^\s*\[assembly:\s*AssemblyVersion\s*\(\s*`"(\d+\.\d+.\d+)`"\s*\)\s*\]");

# Finds version string in the AssemblyInfo.cs
$version = Get-Content "$PathToSrc/Host/Properties/AssemblyInfo.cs" | `
ForEach-Object {$regex.Matches($_)} | `
Where-Object {$_.Success} | `
ForEach-Object {$_.Groups[1].Value}

# Creates output directory if it is missing
$dir = "$OutputDir/Host_$($Configuration)_$($Arch)_v$version"
New-Item $dir -Force -ItemType Directory -ErrorAction SilentlyContinue

# Copies items one by one
Get-ChildItem "$PathToSrc/Host/bin/$Arch/$Configuration/" | `
ForEach-Object {Copy-Item -Path $($_.FullName) -Destination "$dir\"}
32 changes: 4 additions & 28 deletions src/ANDOR-CS/Classes/DebugCamera.cs
Original file line number Diff line number Diff line change
@@ -1,29 +1,4 @@
// This file is part of Dipol-3 Camera Manager.

// MIT License
//
// Copyright(c) 2018-2019 Ilia Kosenkov
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.


#if DEBUG
#if DEBUG
using System;
using System.IO;
using System.Threading.Tasks;
Expand All @@ -42,6 +17,7 @@ public sealed partial class DebugCamera : Camera
{
private const string DebugImagePath = @"debug_image.fits";

private static volatile int Counter = -1;
private static readonly Random R = new Random();
private static readonly object Locker = new object();
private const ConsoleColor Green = ConsoleColor.DarkGreen;
Expand Down Expand Up @@ -107,7 +83,7 @@ public DebugCamera(int camIndex)

Task.Delay(TimeSpan.FromSeconds(1.5)).GetAwaiter().GetResult();

CameraIndex = camIndex;
CameraIndex = Interlocked.Increment(ref Counter);
SerialNumber = $"XYZ-{R.Next(9999):0000}";
Capabilities = new DeviceCapabilities()
{
Expand All @@ -117,7 +93,7 @@ public DebugCamera(int camIndex)
| AcquisitionMode.Accumulation
| AcquisitionMode.FastKinetics
| AcquisitionMode.Kinetic,
GetFunctions = GetFunction.Temperature | GetFunction.TemperatureRange,
GetFunctions = GetFunction.Temperature | GetFunction.TemperatureRange | GetFunction.DetectorSize,
SetFunctions = SetFunction.Temperature
| SetFunction.VerticalReadoutSpeed
| SetFunction.VerticalClockVoltage
Expand Down
Binary file added src/ANDOR-CS/debug_image.fits
Binary file not shown.
7 changes: 7 additions & 0 deletions src/DIPOL-UF/Controls/CameraTab.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<!--Cooler slider/bar-->
<Grid Grid.Column="0" Grid.Row="0" Margin="2">
Expand Down Expand Up @@ -483,6 +484,12 @@
Text="{Binding ExposureTime,
Mode=OneWay,
StringFormat={extensions:Text Key=General_ExposureFloatFormat}}"/>
<Image
Grid.Column="0" Grid.Row="7" Grid.ColumnSpan="2"
Margin="10"
Width="120" Height="120"
Source="{Binding PolarizationSymbolImage}"
/>
</Grid>
<StackPanel Grid.Row="2" Grid.Column="0">
<ProgressBar
Expand Down
141 changes: 56 additions & 85 deletions src/DIPOL-UF/Converters/ConverterImplementations.cs
Original file line number Diff line number Diff line change
Expand Up @@ -118,84 +118,62 @@ public static int CameraToIndexConversion(string cam)
public static string CameraKeyToHostConversion(string input)
=> Helper.GetCameraHostName(input);

public static Brush TemperatureToBrushConversion(float temp, Brush[] brushes)
{
if (brushes is null || brushes.Length < 4)
return Brushes.Black;

if (temp > 20)
return brushes[0];
if (temp > 5)
return brushes[1] ;
if (temp > -15)
return brushes[2];
return brushes[3];
}
public static Brush TemperatureToBrushConversion(float temp, Brush[]? brushes) =>
brushes is {Length: >= 4}
? temp switch
{
> 20 => brushes[0],
> 5 => brushes[1],
> -15 => brushes[2],
_ => brushes[3]
}
: Brushes.Black;

public static string EnumToDescriptionConversion(Enum @enum)
=> @enum.GetEnumStringEx().EnumerableToString();
=> @enum.GetEnumNameRep().Full;

public static List<string> EnumToDescriptionConversion(IEnumerable<Enum> enums)
=> enums.Select(x => x.GetEnumStringEx().EnumerableToString())
.ToList();
=> enums.GetEnumNamesRep().Select(x => x.Full).ToList();

public static Enum DescriptionToEnumConversion(string desc, Type type)
public static Enum? DescriptionToEnumConversion(string desc, Type type)
{
if (type.BaseType == typeof(Enum))
return (Enum)Helper.GetEnumFromDescription(desc, type);

if(Nullable.GetUnderlyingType(type) is Type innerType &&
innerType.BaseType == typeof(Enum))
return (Enum)Helper.GetEnumFromDescription(desc, innerType);
if (type is {IsEnum: true})
{
return EnumHelper.FromDescription(desc, type);
}

if (Nullable.GetUnderlyingType(type) is {IsEnum: true} innerType)
{
return EnumHelper.FromDescription(desc, innerType);
}

return null;
}

public static Brush TemperatureStatusToBrushConversion(TemperatureStatus status, Brush[] brushes)
{
if (brushes.Length >= 5)

switch (status)
public static Brush TemperatureStatusToBrushConversion(TemperatureStatus status, Brush[] brushes) =>
brushes.Length >= 5
? status switch
{
case TemperatureStatus.Off:
return brushes[0];
case TemperatureStatus.Stabilized:
return brushes[1];
case TemperatureStatus.NotReached:
return brushes[2];
case TemperatureStatus.Drift:
return brushes[3];
case TemperatureStatus.NotStabilized:
return brushes[4];
default:
return Brushes.Black;
TemperatureStatus.Off => brushes[0],
TemperatureStatus.Stabilized => brushes[1],
TemperatureStatus.NotReached => brushes[2],
TemperatureStatus.Drift => brushes[3],
TemperatureStatus.NotStabilized => brushes[4],
_ => Brushes.Black
}
else
return Brushes.Black;
}
: Brushes.Black;

public static bool BoolToBoolConversion(List<bool> values, string parameter = null)
{
if (parameter is string strPar)
public static bool BoolToBoolConversion(List<bool> values, string? parameter = null) =>
parameter?.Trim().ToLowerInvariant() switch
{
var key = strPar.Trim().ToLowerInvariant();
switch (key)
{
case "all":
return values.All(x => x);
case "any":
return values.Any();
case "notall":
return !values.All(x => x);
case "notany":
return !values.Any();
}
}

return values.All(x => x);
}

public static bool CompareToConversion(object src, object parameter)
"any" => values.Any(x => x),
"notall" => values.Any(x => !x),
"notany" => !values.Any(x => x),
// Default, also "all" branch
_ => values.All(x => x),
};

public static bool CompareToConversion(object src, object? parameter)
{
if(!src.GetType().IsPrimitive)
throw new TypeAccessException(nameof(src));
Expand All @@ -220,37 +198,30 @@ public static bool CompareToConversion(object src, object parameter)
as IComparable)
?.CompareTo(src);

switch (operation)
return operation switch
{
case "=":
case "==":
return diff == 0;
case ">":
return diff < 0;
case ">=":
return diff <= 0;
case "<":
return diff > 0;
case "<=":
return diff >= 0;
case "!=":
return diff != 0;
default:
throw new ArgumentException(string.Format(Localization.General_InvalidArgument, nameof(parameter)));
}

"=" or "==" => diff == 0,
">" => diff < 0,
">=" => diff <= 0,
"<" => diff > 0,
"<=" => diff >= 0,
"!=" => diff != 0,
_ => throw new ArgumentException(
string.Format(Localization.General_InvalidArgument, nameof(parameter))
)
};
}
throw new ArgumentException(string.Format(Localization.General_InvalidArgument, nameof(parameter)));
}

public static object FieldAccessConversion(object src, string fieldName)
public static object? FieldAccessConversion(object? src, string fieldName)
=> src?.GetType()
.GetField(fieldName, BindingFlags.Public | BindingFlags.Instance)
?.GetValue(src);

public static string ValidationErrorsToStringConversion(object value)
public static string? ValidationErrorsToStringConversion(object value)
=> value is IReadOnlyCollection<ValidationError> collection
? collection.Select(x => x.ErrorContent).EnumerableToString(";\r\n") + "."
? $"{collection.Select(x => x.ErrorContent).EnumerableToString(";\r\n")}."
: null;
}
}
27 changes: 15 additions & 12 deletions src/DIPOL-UF/Converters/EnumToDescriptionValueConverter.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Windows.Data;
using System.Globalization;
using System.Linq;
Expand All @@ -9,18 +8,22 @@ namespace DIPOL_UF.Converters
{
internal class EnumToDescriptionValueConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
switch (value)
public object Convert(object value, Type targetType, object parameter, CultureInfo culture) =>
value switch
{
case Enum enumVal:
return ConverterImplementations.EnumToDescriptionConversion(enumVal);
case IEnumerable enumVals:
return ConverterImplementations.EnumToDescriptionConversion(enumVals.Cast<Enum>());
default:
return null;
}
}
Enum enumVal => ConverterImplementations.EnumToDescriptionConversion(enumVal),
IEnumerable enumVals =>
(
// This checks if target type implements IEnumerable
targetType.FindInterfaces((t, o) => o is Type compType && t == compType, typeof(IEnumerable)).Any(),
ConverterImplementations.EnumToDescriptionConversion(enumVals.Cast<Enum>())
) switch
{
(true, var values) => values,
var (_, values) => values?.EnumerableToString()
},
_ => null
};

public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
//=> value is string desc
Expand Down
Loading

0 comments on commit 6e8a71e

Please sign in to comment.