Skip to content

Commit 05716ce

Browse files
committed
add LOPORA colormap
1 parent 9db6c1d commit 05716ce

File tree

7 files changed

+227
-0
lines changed

7 files changed

+227
-0
lines changed

.vscode/.ropeproject/config.py

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
# The default ``config.py``
2+
# flake8: noqa
3+
4+
5+
def set_prefs(prefs):
6+
"""This function is called before opening the project"""
7+
8+
# Specify which files and folders to ignore in the project.
9+
# Changes to ignored resources are not added to the history and
10+
# VCSs. Also they are not returned in `Project.get_files()`.
11+
# Note that ``?`` and ``*`` match all characters but slashes.
12+
# '*.pyc': matches 'test.pyc' and 'pkg/test.pyc'
13+
# 'mod*.pyc': matches 'test/mod1.pyc' but not 'mod/1.pyc'
14+
# '.svn': matches 'pkg/.svn' and all of its children
15+
# 'build/*.o': matches 'build/lib.o' but not 'build/sub/lib.o'
16+
# 'build//*.o': matches 'build/lib.o' and 'build/sub/lib.o'
17+
prefs['ignored_resources'] = ['*.pyc', '*~', '.ropeproject',
18+
'.hg', '.svn', '_svn', '.git', '.tox']
19+
20+
# Specifies which files should be considered python files. It is
21+
# useful when you have scripts inside your project. Only files
22+
# ending with ``.py`` are considered to be python files by
23+
# default.
24+
# prefs['python_files'] = ['*.py']
25+
26+
# Custom source folders: By default rope searches the project
27+
# for finding source folders (folders that should be searched
28+
# for finding modules). You can add paths to that list. Note
29+
# that rope guesses project source folders correctly most of the
30+
# time; use this if you have any problems.
31+
# The folders should be relative to project root and use '/' for
32+
# separating folders regardless of the platform rope is running on.
33+
# 'src/my_source_folder' for instance.
34+
# prefs.add('source_folders', 'src')
35+
36+
# You can extend python path for looking up modules
37+
# prefs.add('python_path', '~/python/')
38+
39+
# Should rope save object information or not.
40+
prefs['save_objectdb'] = True
41+
prefs['compress_objectdb'] = False
42+
43+
# If `True`, rope analyzes each module when it is being saved.
44+
prefs['automatic_soa'] = True
45+
# The depth of calls to follow in static object analysis
46+
prefs['soa_followed_calls'] = 0
47+
48+
# If `False` when running modules or unit tests "dynamic object
49+
# analysis" is turned off. This makes them much faster.
50+
prefs['perform_doa'] = True
51+
52+
# Rope can check the validity of its object DB when running.
53+
prefs['validate_objectdb'] = True
54+
55+
# How many undos to hold?
56+
prefs['max_history_items'] = 32
57+
58+
# Shows whether to save history across sessions.
59+
prefs['save_history'] = True
60+
prefs['compress_history'] = False
61+
62+
# Set the number spaces used for indenting. According to
63+
# :PEP:`8`, it is best to use 4 spaces. Since most of rope's
64+
# unit-tests use 4 spaces it is more reliable, too.
65+
prefs['indent_size'] = 4
66+
67+
# Builtin and c-extension modules that are allowed to be imported
68+
# and inspected by rope.
69+
prefs['extension_modules'] = []
70+
71+
# Add all standard c-extensions to extension_modules list.
72+
prefs['import_dynload_stdmods'] = True
73+
74+
# If `True` modules with syntax errors are considered to be empty.
75+
# The default value is `False`; When `False` syntax errors raise
76+
# `rope.base.exceptions.ModuleSyntaxError` exception.
77+
prefs['ignore_syntax_errors'] = False
78+
79+
# If `True`, rope ignores unresolvable imports. Otherwise, they
80+
# appear in the importing namespace.
81+
prefs['ignore_bad_imports'] = False
82+
83+
# If `True`, rope will insert new module imports as
84+
# `from <package> import <module>` by default.
85+
prefs['prefer_module_from_imports'] = False
86+
87+
# If `True`, rope will transform a comma list of imports into
88+
# multiple separate import statements when organizing
89+
# imports.
90+
prefs['split_imports'] = False
91+
92+
# If `True`, rope will remove all top-level import statements and
93+
# reinsert them at the top of the module when making changes.
94+
prefs['pull_imports_to_top'] = True
95+
96+
# If `True`, rope will sort imports alphabetically by module name instead
97+
# of alphabetically by import statement, with from imports after normal
98+
# imports.
99+
prefs['sort_imports_alphabetically'] = False
100+
101+
# Location of implementation of
102+
# rope.base.oi.type_hinting.interfaces.ITypeHintingFactory In general
103+
# case, you don't have to change this value, unless you're an rope expert.
104+
# Change this value to inject you own implementations of interfaces
105+
# listed in module rope.base.oi.type_hinting.providers.interfaces
106+
# For example, you can add you own providers for Django Models, or disable
107+
# the search type-hinting in a class hierarchy, etc.
108+
prefs['type_hinting_factory'] = (
109+
'rope.base.oi.type_hinting.factory.default_type_hinting_factory')
110+
111+
112+
def project_opened(project):
113+
"""This function is called after opening the project"""
114+
# Do whatever you like here!

.vscode/.ropeproject/objectdb

6 Bytes
Binary file not shown.

dev/colormap/lopora-brightness.png

57.3 KB
Loading

dev/colormap/lopora-display.png

57.2 KB
Loading

dev/colormap/lopora.py

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
"""
2+
Attempt to mimic LOPORA colormap from
3+
https://github.com/swharden/Lopora/blob/20afe72416579f8b7d3c8861532c71a95b904066/src/LOPORA-v5a.py#L828-L872
4+
"""
5+
import numpy
6+
import matplotlib.pyplot as plt
7+
8+
9+
def doit(intensityCompression=2, pointCount=256):
10+
11+
Rs = numpy.ones(pointCount)
12+
Gs = numpy.ones(pointCount)
13+
Bs = numpy.ones(pointCount)
14+
15+
for n in range(pointCount):
16+
17+
frac = n / len(Rs)
18+
v = frac ** (1.0 / (1.0 + float(intensityCompression) / 2.0))
19+
20+
R = int(v * v * 255 + 0.5)
21+
Rs[n] = int(min(max(R, 0), 255))
22+
23+
G = int(v * 255 + 0.5)
24+
Gs[n] = int(min(max(G, 0), 255))
25+
26+
B = int(255 * numpy.sqrt(v) + 0.5)
27+
Bs[n] = int(min(max(B, 0), 255))
28+
29+
return [Rs, Gs, Bs]
30+
31+
32+
def rgbToInt32(r, g, b):
33+
return int(r * 2**16 + g * 2**8 + b)
34+
35+
36+
if __name__ == "__main__":
37+
38+
[r, g, b] = doit()
39+
40+
for i in range(256):
41+
int32 = rgbToInt32(r[i], g[i], b[i])
42+
print(f"{int32:010d}, ", end='')
43+
if i % 8 == 7:
44+
print()
45+
46+
# plt.plot(r, 'r-', alpha=.5)
47+
# plt.plot(g, 'g-', alpha=.5)
48+
# plt.plot(b, 'b-', alpha=.5)
49+
50+
# plt.grid(alpha=.2, ls='--')
51+
# plt.title("Lopora Style Colormap")
52+
# plt.xlabel("input value")
53+
# plt.ylabel("color intensity")
54+
# plt.tight_layout()
55+
# plt.show()
56+
57+
print("DONE")

src/Spectrogram/Colormap.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ public class Colormap
1414
public static Colormap GrayscaleReversed => new Colormap(new Colormaps.Grayscale());
1515
public static Colormap Greens => new Colormap(new Colormaps.Greens());
1616
public static Colormap Inferno => new Colormap(new Colormaps.Inferno());
17+
public static Colormap Lopora => new Colormap(new Colormaps.Lopora());
1718
public static Colormap Magma => new Colormap(new Colormaps.Magma());
1819
public static Colormap Plasma => new Colormap(new Colormaps.Plasma());
1920
public static Colormap Turbo => new Colormap(new Colormaps.Turbo());

src/Spectrogram/Colormaps/Lopora.cs

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
/* Lopora is an open-source weak signal spectrogram by Onno Hoekstra (PA2OHH)
2+
* This colormap was created to mimic the default colors used by Lopora.
3+
* https://www.qsl.net/pa2ohh/11lop.htm
4+
* https://github.com/swharden/Lopora/blob/20afe72416579f8b7d3c8861532c71a95b904066/src/LOPORA-v5a.py#L828-L872
5+
*/
6+
7+
using System;
8+
9+
namespace Spectrogram.Colormaps
10+
{
11+
class Lopora : IColormap
12+
{
13+
public (byte r, byte g, byte b) GetRGB(byte value)
14+
{
15+
byte[] bytes = BitConverter.GetBytes(rgb[value]);
16+
return (bytes[2], bytes[1], bytes[0]);
17+
}
18+
19+
private readonly int[] rgb =
20+
{
21+
0000000000, 0000069696, 0000137036, 0000203860, 0000270426, 0000336991, 0000403300, 0000469608,
22+
0000535915, 0000602222, 0000668273, 0000734580, 0000800631, 0000866681, 0000932987, 0000999037,
23+
0001065088, 0001131137, 0001197187, 0001262981, 0001329031, 0001395080, 0001461130, 0001526924,
24+
0001592973, 0001659023, 0001724816, 0001790865, 0001856659, 0001922708, 0001988501, 0002054550,
25+
0002120344, 0002186393, 0002252186, 0002317979, 0002384028, 0002449821, 0002515614, 0002581663,
26+
0002647456, 0002713249, 0002779042, 0002845091, 0002910884, 0002976677, 0003042470, 0003108263,
27+
0003174056, 0003240105, 0003305898, 0003371690, 0003437483, 0003503276, 0003569069, 0003634862,
28+
0003700654, 0003766447, 0003832240, 0003898033, 0003963825, 0004029618, 0004095411, 0004161204,
29+
0004227252, 0004292789, 0004358582, 0004424374, 0004490167, 0004555960, 0004621752, 0004687545,
30+
0004753338, 0004819130, 0004884923, 0004950716, 0005016508, 0005082301, 0005148093, 0005213886,
31+
0005279679, 0005345215, 0005411008, 0005476800, 0005542593, 0005608386, 0005674178, 0005739971,
32+
0005805763, 0005871300, 0005937092, 0006002885, 0006068677, 0006134470, 0006200263, 0006265799,
33+
0006331592, 0006397384, 0006463177, 0006528969, 0006594506, 0006660298, 0006726091, 0006791883,
34+
0006857676, 0006923212, 0006989005, 0007054797, 0007120590, 0007186126, 0007251918, 0007317711,
35+
0007383503, 0007449040, 0007514832, 0007580625, 0007646417, 0007711954, 0007777746, 0007843539,
36+
0007909331, 0007974867, 0008040660, 0008106452, 0008171989, 0008237781, 0008303574, 0008369366,
37+
0008434902, 0008435159, 0008500951, 0008566488, 0008632280, 0008698072, 0008763609, 0008829401,
38+
0008895194, 0008960986, 0009026522, 0009092315, 0009158107, 0009223644, 0009289436, 0009355228,
39+
0009420765, 0009486557, 0009552350, 0009617886, 0009683678, 0009749471, 0009815007, 0009880799,
40+
0009946336, 0010012128, 0010077921, 0010143457, 0010209249, 0010275042, 0010340578, 0010406370,
41+
0010472163, 0010537699, 0010603491, 0010669028, 0010734820, 0010800612, 0010866149, 0010931941,
42+
0010997734, 0011063270, 0011129062, 0011194599, 0011260391, 0011326183, 0011391720, 0011457512,
43+
0011523048, 0011588841, 0011654633, 0011720169, 0011785962, 0011851498, 0011917290, 0011983082,
44+
0012048619, 0012114411, 0012179947, 0012245740, 0012311532, 0012377068, 0012442861, 0012508397,
45+
0012574189, 0012639726, 0012705518, 0012771310, 0012836847, 0012902639, 0012968175, 0013033967,
46+
0013099504, 0013165296, 0013231088, 0013296625, 0013362417, 0013427953, 0013493746, 0013559282,
47+
0013625074, 0013690610, 0013756403, 0013822195, 0013887731, 0013953524, 0014019060, 0014084852,
48+
0014150388, 0014216181, 0014281717, 0014347509, 0014413046, 0014478838, 0014544374, 0014610166,
49+
0014675959, 0014741495, 0014807287, 0014872823, 0014938616, 0015004152, 0015069944, 0015135481,
50+
0015201273, 0015266809, 0015332601, 0015398138, 0015463930, 0015529466, 0015595258, 0015660795,
51+
0015726587, 0015792123, 0015857915, 0015923452, 0015989244, 0016054780, 0016120572, 0016186109,
52+
0016251901, 0016317437, 0016383229, 0016448766, 0016514558, 0016580350, 0016645887, 0016711679,
53+
};
54+
}
55+
}

0 commit comments

Comments
 (0)