Editing layer via Python script startEditing, do we have to "close" editing? - qgis

I'm working on a vector layer where I have to merge all n+i [id] attributes into entity(n)[id] where entities(n+i)[id] equals the entity(n)[id], then delete all n+i entities.
All works fine but I call several times startEditing functions before commiting changes, and my question is: does calling commitChanges closes startEditing, or does it let it opened, like if it was a file descriptor or a pointer which we needed to free after the job's done?
The code is:
olayer.startEditing()
olayer.changeAttributeValue(n,id_obj,id_obj_sum,NULL,True)
olayer.commitChanges()
olayer.startEditing()
i= i-1
while i >=1:
olayer.deleteFeature(n+i)
i=i-1
olayer.commitChanges()
As you can see, we call several times olayer.startEditing, even more because all that code is in while body...
So will that spawn hordes of startEditing "pointers" or will it just continuously set the olayer editable status as "open to edition" ?
Actually the code works, but it's painfully slow, is this the reason why ?

By and large, you should not start the edit mode more than once in your layer.
You can commit at the end of all your changes to the layer, so that your modifications stay in an edit buffer in the meantime.
QgsVectorLayer.commitChanges() can let the edit mode open if you pass a False as parameter (the parameter is called stopEditing, see the docs). Like this:
# If the commit is sucessful, let the edit mode open
layer.commitChanges(False)
Also, have a look at the with edit(layer): syntax in the QGIS docs. Using such syntax you avoid starting/committing/closing the edit mode, QGIS does it for you.
with edit(layer):
# All my layer modifications here
# When this line is reached, my layer modifications are already committed.

Related

how to edit simulink plutosdr qpsk example

I am working with this example from MathWorks: https://www.mathworks.com/help/supportpkg/plutoradio/examples/qpsk-transmitter-with-adalm-pluto-radio-1.html
When i run the example it creates an sdrqpsktx variable in the matlab workspace
I want to change sdrqpsktx.MessageBits to something smaller.
When i run the following code in matlab:
a = sdrqpsktx.MessageBits(1:448);
sdrqpsktx.MessageBits = a;
I successfully change sdrqpsktx.MessageBits to a.
However when i run this in simulink sdrqpsktx.MessageBits changes back to its original size.
How do i permanently change sdrqpsktx.MessageBits and run the example with my changes?
Thank you.
There is a model callback, probably a StartFcn, that is overwriting your changes to the variable every time you start the simulation. You either need to delete or modify that code.
To see the code go to:
File->Model Properties->Model Properties, and select the Callback tab.
Any callback that is followed by a * has code in it. Click on that callback to see the code.
See Callbacks for Customized Models for more detailed information.

MIT-Scratch : Sequential cloning without delay

I am just starting to play with this as an educational tool for a youngster and encounter strange behavior whilst attempting to clone sprites.
I setup a global variable for position x,y in sprite_1 and clone a sprite_2 object. This object immediately copies the global x,y to local x,y and exits. Later sprite_2 renders using the stored local x,y.
sprite_1:
sprite_2:
I expect the four sprites to clone diagonally up/right on the screen according to this small reproduce-able example. Instead I appear to get four sprite_2 objects all on top of each other:
If I add a delay of 1 second onto the end of the clone(x,y) function however all is well:
As all four sprite_2 objects appear to be where the last clone was placed, I have a suspicion that the clones are not created immediately but instead created as a batch all at once, at some time and therefore are all taking the last coordinates from the globals _clone_enemy_x/y.
Is this the case? is there are way to circumvent this behavior or what is the solution?
I have 2 possible solutions to this problem:
Go to the "define clone()()" block, right click it, open up the advanced dropdown, and tick "run without screen refresh".
Get rid of the custom block all together, but use the original source for that block in the actual code.
I hope this helps!

unexpected frame appears onto another frame after an event

I'm using a character application. In the first page, there is a frame f-selection where the search fields are entered. When I search for something and open some other frames in that search, then I press F10 which is for opening another frame, the new frame opens but f-selection also appears on it. I'm suspecting this code makes it pop up again:
else assign ll-lgst-key1:SENSITIVE in frame f-selection = TRUE
ll-lgst-key2:SENSITIVE in frame f-selection = FALSE
because when I comment these lines, the frame doesn't pop up. But then I can't use these fields at the first frame where I should, too. I don't know why this code is called again; but is there anything else I can do to fix this issue? I tried to write hide frame f-selection everywhere possible but it doesn't work.
That snippet of code is making "key1" of your frame sensitive. In order to be sensitive it needs to pop up...
So the issue is why is that block of code executing? You say "I don't know why this code is called again". Neither will anyone else because you have shared such a tiny little bit of the overall code. Apparently the flow of control is taking you through that block so you should work on understanding why that is. You might try using the debugger to step through the code execution or you could insert some old fashioned MESSAGE statements to get to the bottom of it.
If you want to kludge around the problem you could wrap that bit of code in conditional logic. Define and set a variable that determines the desired state of the f-selection frame and use that to control the sensitivity logic:
define variable f-shouldBeVisible as logical no-undo.
if .... then
f-shouldBeVisible = yes.
else
f-shouldBeVisible = no.
...
else
do:
if f-shouldBeVisible then
assign ll-lgst-key1:SENSITIVE in frame f-selection = TRUE
ll-lgst-key2:SENSITIVE in frame f-selection = FALSE
.
end.
Of course that looks kind of silly -- but it is just an example with grossly over-simplified logic.
OTOH if you know enough to set the variable you ought to be able to figure out why the ELSE branch is executing. But maybe it is a useful first step.

Moving from file-based tracing session to real time session

I need to log trace events during boot so I configure an AutoLogger with all the required providers. But when my service/process starts I want to switch to real-time mode so that the file doesn't explode.
I'm using TraceEvent and I can't figure out how to do this move correctly and atomically.
The first thing I tried:
const int timeToWait = 5000;
using (var tes = new TraceEventSession("TEMPSESSIONNAME", #"c:\temp\TEMPSESSIONNAME.etl") { StopOnDispose = false })
{
tes.EnableProvider(ProviderExtensions.ProviderName<MicrosoftWindowsKernelProcess>());
Thread.Sleep(timeToWait);
}
using (var tes = new TraceEventSession("TEMPSESSIONNAME", TraceEventSessionOptions.Attach))
{
Thread.Sleep(timeToWait);
tes.SetFileName(null);
Thread.Sleep(timeToWait);
Console.WriteLine("Done");
}
Here I wanted to make that I can transfer the session to real-time mode. But instead, the file I got contained events from a 15s period instead of just 10s.
The same happens if I use new TraceEventSession("TEMPSESSIONNAME", #"c:\temp\TEMPSESSIONNAME.etl", TraceEventSessionOptions.Create) instead.
It seems that the following will cause the file to stop being written to:
using (var tes = new TraceEventSession("TEMPSESSIONNAME"))
{
tes.EnableProvider(ProviderExtensions.ProviderName<MicrosoftWindowsKernelProcess>());
Thread.Sleep(timeToWait);
}
But here I must reenable all the providers and according to the documentation "if the session already existed it is closed and reopened (thus orphans are cleaned up on next use)". I don't understand the last part about orphans. Obviously some events might occur in the time between closing, opening and subscribing on the events. Does this mean I will lose these events or will I get the later?
I also found the following in the documentation of the library:
In real time mode, events are buffered and there is at least a second or so delay (typically 3 sec) between the firing of the event and the reception by the session (to allow events to be delivered in efficient clumps of many events)
Does this make the above code alright (well, unless the improbable happens and for some reason my thread is delayed for more than a second between creating the real-time session and starting processing the events)?
I could close the session and create a new different one but then I think I'd miss some events. Or I could open a new session and then close the file-based one but then I might get duplicate events.
I couldn't find online any examples of moving from a file-based trace to a real-time trace.
I managed to contact the author of TraceEvent and this is the answer I got:
Re the exception of the 'auto-closing and restarting' feature, it is really questions about the OS (TraceEvent simply calls the underlying OS API). Just FYI, the deal about orphans is that it is EASY for your process to exit but leave a session going. This MAY be what you want, but often it is not, and so to make the common case 'just work' if you do Create (which is the default), it will close a session if it already existed (since you asked for a new one).
Experimentation of course is the touchstone of 'truth' but I would frankly expecting unusual combinations to just work is generally NOT true.
My recommendation is to keep it simple. You need to open a new session and close the original one. Yes, you will end up with duplicates, but you CAN filter them out (after all they are IDENTICAL timestamps).
The other possibility is use SetFileName in its intended way (from one file to another). This certainly solves your problem of file size growth, and often is a good way to deal with other scenarios (after all you can start up you processing and start deleting files even as new files are being generated).

How can I save output from Simulink?

I'm a student learning to use MATLAB. For an assignment, I have to create a simple state machine and collect some results. I'm used to using Verilog/Modelsim, and I'd like to collect data only when the state machine's output changes, which is not necessarily every time/sample period.
Right now I have a model that looks like this:
RequestChart ----> ResponseChart ----> Unit Delay Block --> (Back to RequestChart)
| |
------------------------> Mux --> "To Workspace" Sink Block
I've tried setting the sink block to save as "Array" format, but it only saves 51 values. I've tried setting it to "Timeseries", but it saves tons of zero values.
Can someone give me some suggestions? Like I said, MATLAB is new to me, please let me know if I need to clarify my question or provide more information.
Edit: Here's a screen capture of my model:
Generally Simulink will output a sample at every integration step. If you want to only output data when a particular event occurs -- in this case only when some data changes -- then do the following,
run the output of the state machine into a Detect Change block (from the Logic and Bit Operations library)
run that signal into the trigger port of a Triggered Subsystem.
run the output of the state machine into the data port of the Triggered Subsystem.
inside the triggered subsystem, run the data signal into a To Workspace block.
Data will only be saved at time point that the trigger occurs, i.e. when your data changes.
In your Simulink window, make sure the Relative Tolerance is small so that you can generate many more points in between your start and ending time. Click on the Simulation option at the top of the window, then click on Model Configuration Parameters.
From there, change the Relative Tolerance to something small... like 1e-10. After that, try running your simulation again. You should have a lot more points in your output array that you can now save.