Yes, my work laptop is much faster, ryzen 4500, the home laptop has a i5 from 2016. The problem can also be reproduced on an even older desktop PC.
Started looking into events today, RFH: Instrumenting to determine when an image analysis/processing action is complete · Issue #13745 · darktable-org/darktable · GitHub. Made some discoveries. Still testing to make sure I understand what’s happening and how to best proceed forward.
Okay, I set the sleep timers in:
local function ProcessWorkflowSteps()
– process current image
LogInfo(“==============================”)
LogInfo(“process workflow steps”)
dt.control.sleep(500)
– execute all workflow steps
– the order is from bottom to top, along the pixel pipeline.
for i = 1, #WorkflowSteps do
step = WorkflowSteps[#WorkflowSteps + 1 - i]
step:Run()
end
dt.control.sleep(500)
LogScreen(“initial workflow - done”)
LogInfo(“initial workflow - done”)
LogInfo(“==============================”)
end
from 500 to 2000, and this 100% fixed the problem on my slow PC. So, this clearly is a timing problem. I wonder if other steps in the script are also not completed, because the script moves on before the action is fully executed.
Anyway, thanks so much to Uli and Bill for working on this. I love this community and how much volunteer work goes into it. It’s highly appreciated.
@dterrahe figured out a new home for the pixelpipe-processing-complete
event trigger that seems to accurately tell when the pixelpipe processing is truly complete. I tested it against all the routines that I used sleeps in and got them all running without any sleeps. Then I selected 10 images in lighttable and looped through loading each image and adding 0.5 ev of exposure without any problems. The PR is submitted.
That’s very good! Did you consider “darkroom-image-loaded”? Do we still need it?
How do I get this script
It’s linked in this thread just scroll up
darkroom-image-loaded
is needed if you want to run a script from lighttable view and have it cycle through a set of images and apply edits.
The sequence works like this:
- request an image to be loaded
- the image is loaded and the
darkroom-image-loaded
event is fired along with a flag that tells whether the image was cleanly loaded or not. If it’s not cleanly loaded, then you need to ask for it to be reloaded. - once the image is loaded it has to be processed through the pixelpipe to generate the center display and the navigation preview, so you need to catch
pixelpipe-processing-complete
to make sure the image is ready to have edits applied to it. - apply edits catching
pixelpipe-processing-complete
between each action call
The problem with setting spot exposure in measurement mode is that it only uses the preview pixelpipe, so until the new PR is merged there isn’t a way to catch that event.
When you are running/testing scripts if you run darktable in a terminal with the -d lua -d perf
flags you can click in the GUI and see what’s happening from the messages, which is how I figured out the spot exposure measurement problem.
Here comes a new version with some changes:
-
it should support dt 4.2.1 and dt 4.3+801 now
-
with DT 4.2 there is a timing problem, if you run it with older hardware you might run into errors. To avoid this, there are some sleeping times included. You can find some dt.control.sleep(1000) within the code. You could increase the waiting time to your needs. This will be fixed with later dt versions.
You can find the script file in the attachment:
InitialWorkflowModule.zip (10.5 KB)
or you can download it from github (as of today):
- Todd Prior via discuss.pixls.us noreply@discuss.pixls.us [02-26-23 11:04]:
It’s linked in this thread just scroll up
tks, got it.
I understand that we have to wait for both events.
How can I read the flag to detect the image was cleanly loaded or not? The callback gets two parameters, event and image. Where can I find the flag?
How can I reload it if the image didn’t load cleanly?
Here’s a script that uses it
display_in_darkroom.zip (1.2 KB)
thanks! The callback function now has 3 parameters? Is it new for dt 4.3?
No, actually it’s in 4.2. It was merged 10/14/22. To better understand what “clean” is, here’s the commit message
Added triggers for the darkroom-image-loaded lua event. Researching
_dev_change_image I found that it’s possible to load an image without
having locks on the pixel pipes, which means that if you immediately
do any processing it gets applied to the previous image. So I added
a status (boolean) to the event that lets the caller know if the load
was clean (got pixel pipe locks) or not.
This got added when I started playing with darktable.gui.action() and started having edits show up on the wrong images
seems like that’s a good thing for the next script version , I will integrate it.
In my lua script I try to set “global chroma” in color balance rgb module. The script sets the value and waits for “pixelpipe-processing-complete”. That works fine, but if I set an already set value again, the event is not sent. I’m now trying to read the current value beforehand to avoid the set command, but I don’t get the exact value from the GUI:
example: value in user interface = 1.23%
luaValue = dt.gui.action(“iop/colorbalancergb/global chroma”,0,“value”,“”,0/0)
luaValue is returned as 2.5123000144958
I tried other values:
1.23% => 2.5123000144958
2.34% => 2.5234000682831
There seems to be an offset of 2.5 and a small rounding error?
How can I get the current value of this slider? Is it the same for other modules?
EDIT: I could round the value and subtract out the offset and %, but maybe there’s a more direct way?
EDIT: Contrast Equalizer Mix needs offset and factor
Color Balance RGB chroma:
value = Round((dt.gui.action(…) - 2.5) * 1)
Contrast Equalizer Mix:
value = Round((dt.gui.action(…) - 2.5) * 4)
value = dt.gui.action(“iop/atrous/mix”,0,“value”,“”,0/0)
converted = value - 2.5
converted = converted * 4
converted = math.floor(converted * 10000 + 0.5) / 10000
The normal return from dt.gui.action
is an encoded value of the location on the 0-1 range and includes an indication on whether this is a percentage or a ± value. This is used to correctly set rotor lights on midi encoders.
The only exception is the “set” effect, which takes and returns an actual parameter value (which might be different from what is shown on the screen, because that sometimes contains further scaling/offset).
So for your case the following should work (though I haven’t tested)
luaValue = dt.gui.action(“iop/colorbalancergb/global chroma”,“value”,“set”)
that works, thank you!
one more thing:
I use the following command to configure channel mixer rgb:
dt.gui.action(“iop/channelmixerrgb/illuminant”,0,“selection”,“item:D (daylight)”,1,000)
If the same value is already configured, no pixelpipe-processing-complete event is sent.
How can I detect the current value?
dt.gui.action(“iop/channelmixerrgb/illuminant”, 0, “selection”, 0/0)
returns decimal values, but I would prefer a string like “item:D (daylight)”.
Sorry, you can’t; dt.gui.action
can only return values as in c return types are fixed. This would require somebody to write a completely separate function. Or you would have to copy and maintain the list of names in lua.