BiodataMiningGroup / quimbi

Quick exploration tool for multivariate bioimages
GNU General Public License v3.0
1 stars 0 forks source link

Reimplement the UI #2

Open mzur opened 6 years ago

mzur commented 6 years ago

The UI did not age very well with Angular 1. Some parts of the UI do not work correctly any more (the spectrum viewer) and the code is hard to maintain. We decided to do a rewrite of the UI in Vue. This can be done incrementally:

mzur commented 6 years ago

Quick recap 2018-10-12:

mzur commented 5 years ago

Recap 2018-10-24:

mzur commented 5 years ago

Recap 2018-11-07:

Smoothing for the zoom in OpenLayers can be disabled like this.

On chaining multiple shaders: Instead of rendering to the null framebuffer, the AngleDist shader renders to a texture. This texture is picked up by the ColorMap shader to apply the color map.

Before the shader can render to a texture, the texture has to be created. This happens here through the setUpDistanceTexture function. The function makes use of the glmvilib assets object and the helpers to create a new framebuffer and texture, and bind the two together. Whenever a shader uses the new framebuffer as target, it will render to the texture. The pointer to the framebuffer is stored in assets.framebuffers.distances, which is used here to define the render target of the AngleDist shader.

The color map is applied in the ColorMap shader. Originally, this shader used the output of the ColorLens shader as input source but right now this should be changed to use assets.textures.distanceTexture of AngleDist, instead.

The color map itself is loaded as Uint8Array by the colorMap service from the CSV file. In our case it can be hard-coded somewhere. The texture that holds the color map is created here. There is no need to dynamically update the color map with the updateColorMaps function, it can be set directly in the setUp function (replace null with the Uint8Array).

Edit: The this object should now be usable as intended in setUp, callback and postCallback functions of shaders. Here is the latest release of glmvilib.

fabian-ep commented 5 years ago

Edit: The this object should now be usable as intended in setUp, callback and postCallback functions of shaders. Here is the latest release of glmvilib.

Klappt, danke!

Die ColorMap auch schon (fast). ;)

bildschirmfoto 2018-11-09 um 12 21 25
mzur commented 5 years ago

Recap 2018-11-12:

Die RGB fire.csv gibt es hier.

Infos zum "dynamic stretching" der Color Map (2. oben):

Für das Stretching werden die Werte der aktuell minimalen und maximalen Distanz benötigt. Diese müssen nach jedem Rendern mit AngleDist aus dem WebGL Framebuffer ausgelesen werden. In der alten Version läuft das über die postCallback Funktion nach jedem Rendern von RGBSelection. In der neuen Version kann dies einfach nach AngleDist passieren.

Die Werte werden mit glmvilib.getPixels aus dem aktuell aktiven Framebuffer ausgelesen und in ein Uint8Array geschrieben. Aus den ausgelesenen Distanzwerten wird dann ein Histogramm erstellt, in dem für jede mögliche Distanz (0 bis 255) die Zahl der mit dieser Distanz vorkommenden Pixel enthalten ist. Aus diesem Histogramm werden wiederum die Werte der aktuell minimalen und maximalen Distanz ermittelt. Der alte Code ist für mehrere gleichzeitige Marker/Farbkanäle ausgelegt. Wir brauchen aber nur einen.

Die aktuelle Color Map, das ermittelte Histogramm und die minimale/maximale Distanz werden für die Darstellung des "Color Map Indicator" im UI verwendet (colorScale, colorScaleCanvas, colorScaleHistogram). Das colorScaleCanvas ist mit WebGL implementiert. Für einen einzigen Marker kann man es aber ganz einfach wie das Histogramm mit dem Canvas 2D Context implementieren.

Die minimale/maximale Distanz wird außerdem in dem ColorLens Shader verwendet. Dieser kümmert sich dann darum, dass die von AngleDist ermittelten Distanzen auf [0, 1] gestreckt werden. Zum Verständnis, eine Streckung würde Formal so aussehen: f(x) = x - x_min / (x_max - x_min). Das ist hier etwas umständlich implementiert, um eine Division zu vermeiden, die angeblich langsamer in WebGL ist. Die Performance spielt aber an dieser Stelle gar keine so große Rolle. Trotzdem muss aber eine Division durch 0 vermieden werden.

mzur commented 5 years ago

Recap 2018-11-26:

Sonstige Features über die wir gesprochen haben:

Die Werte für den Spectrum Viewer werden mit dem SelectionInfo Shader ermittelt. Dieser wird in dem Marker ausgeführt, wenn immer ein Mausklick passiert. Damit erhält man einen Intensitätswert (0 - 255) für jeden Kanal des Spektrums, wobei 0 einer Intensität von 0 % und 255 einer Intensität von 100 % entspricht. Die Label der x-Achse (d.h. die Namen der Kanäle) werden aus den Dateinamen der Input-PNGs ermittelt.

Folgende Features sollte der Spectrum Viewer haben:

Folgendes sollte leicht zu implementieren sein (oder schon funktionieren):

fabian-ep commented 5 years ago

Mir ist beim implementieren der ColorScale aufgefallen, dass eine Handvoll Pixel schwarz erscheinen, wenn man mit der Maus darüber fährt. Ist da vlt. noch ein Fehler in der ColorLens (Division durch 0 oder so)?

mzur commented 5 years ago

Ja, das habe ich auch schon bemerkt. Das ist allerdings in der alten Version auch schon so, also musst du dich da nicht drum kümmern (es sei denn du möchtest :wink:).

mzur commented 5 years ago

Wobei so ein schwarzes Pixel den interessanten Effekt hat, dass das schwarze div unter der Color Map die Höhe 0 hat (und bei 0 auch auch ein Balken im Histrogramm sichtbar ist), die Color Map aber trotzdem gestaucht ist:

screen shot 2018-11-27 at 08 29 58

Dieser Fall sollte zwar nicht auftreten, aber vielleicht ist hier ausnahmsweise nicht 1 der höchste Wert. Funktioniert dann vielleicht das Verschieben der Color Map nach unten (mit dem weißen div) noch nicht richtig?

mzur commented 5 years ago

Recap 2018-12-04:

Folgende Features haben wir besprochen: