Hello,
some of our beamline scientists have requested the possibility of
asking/introducing interactively parameters from/to the macros from the
spock command line. As an example, if we have a macro called setPosMono, the
user would run it in spock typing:
spock[1]: setPosMono
Spock would answer with:
pos_a (21):
where 21 would be the current pos_a value, if the user press Enter the
value 21 would be used as parameter in the macro, but if the user
type any other value this new one would be taken, and so successively until
all parameters are asked/introduced.
I would like to open with this request the discussion about if and how
the implementation could be done. I can of course contribute in implementing it,
once the details are decided.
Regards, Teresa
Hello,
sorry for the question, but some of our scientists ask continuously about it ... is somebody planning to work on this subject soon?, or could you
give me some tips how this should be done?, so I could try to implement it
in the way you want.
Many thanks.
Hi Teresa,
To fulfill the requirement of your users I see at least the following 2 options:
Below are my ideas about both options..
The first option would require the client (e.g. spock) to handle this process,
and for the server the macro execution would be the same as until now -
all the macro parameters would be already known at the moment of execution.
There is small thing to kepp in mind.. now, the default parameter values are filled by the server (ParamDecoder) based on the macro definition.
We should clarify how to define if a macro parameters should be introduced interactively:
In the second option, we would need to cheat a little bit. The macro would be already in execution on the server,
but at the beginning it could ask for the required values. Yes, it sounds more like a workaround:)
AFAIK, in the current state, the interactive macros works only with the Qt dialogs (and there are some bugs already reported about it:
#149, #153). I've taken a brief look into this implementation, and I think that it should not be too difficult to implement it as a CLI feature (I think this work was even started). The interactive macros are implemented via Door's Input attribute. Which emits events whenever a macro expects user intputs.
The client (spock) in the event callback despatch the work of collecting the user response to the InputHandler.
I think that instead of using a Qt InputHandler we would need to substitute it by the CLI input handler (this is implemented in sardana.spock.inputhandler). Of course this should be properly configurable, if someone wants a GUI or CLI input handlers, etc.
I see work on both options interesting for Sardana. The first option, because it looks more like the proper way to fulfill your users' requrierements.
The second one as well, because the interactive macro is a relatively new feature, which could still be improved. Also interactive (via CLI) macros could be interesting to the users.
From the complexity point of view, I have a feeling that the first option would be more difficult to implement, and would requrie taking some new decisions on the macro definition, and clients configuration.
Of course there could be other options on how to implement this feature-request. Maybe some kind of mixture of option 1 and 2 - interaction between server and client before execution of the macro prepare and run?
Regarding my dedication to this, of course I'm willing to help, but in the following two weeks I could not fully dedicate to that.
Cheers!
Teresa's reply via mailing list:
Hi all,
We have advance with this topic, however there are still some doubts. Below I explain you the current state of this development...
In our opinion the Spock CLI, should handle the interactive macros in the command line (CL) input mode by default.
The present behavior (Qt dialogs) is also fine but its selection should be parametrizable by the user (either sardanacustomsettings.py or the spock profile), what is your opinion about it?
In order to implement the CL mode, the input handler could use the raw_input python built-in function.
Since the current interactive macro mechanism is based on Tango events and writes of the Input attribute, the client (spock) is notified about a request for the user interaction via Tango event. This make the raw_input being called in a separate thread.
There are some particular ipython versions (seems like the newest one - we are sure about 0.13.0, 1.0.0) where the TerminalIPythonApp.gui = 'qt' and/or TerminalIPythonApp.pylab = 'qt' configuration causes problems with calling raw_input from outside of the main thread. Spock uses these particular configurations, which enables the qt4 input hook (I understand that this input hook is responsible for giving times to the Qt EventLoop to process the Qt events and signals while the user input is blocking the current thread execution). Some ipython versions and their input hook implementations gives problems since they manipulate the system signal handlers - this is not allowed out of the main thread and raises exceptions. There could be several options to overpass this limitation, below I list some examples:
With our current knowledge, we propose option 3. The only drawback of this option is that the spock GUI elements become unusable during the user input.
We know the following spock GUI elements:
The expconf and showscan online_raw seems to be not affected by option 3, since they run in a separate process.
We are not sure for the moment about the spsplot - lack of experience with that.
The interactive macro dialogs in GUI mode, would not be affected since we explicitly don't want to use them in the CL mode
The only affected could be plots and showscan.
For the moment, plots they seem to do not work as expected anyway (see bug #297).
One regression would be showscan becoming unusable during the user input.
Of course in the future we could think about improving this solution, but for the moment it seems to add new feature and not loosing any relevant of the existing ones.
I will send a patch, which could serve as a proof of concept. Any comments are more than welcome.
Hi Zibi,
many thanks for your work and the information.
I agree with the decisions you took. At least I do not
see any conflict for our users with that implementation.
I will test your patch as soon as possible.
Hi Zibi,
I have tested your patch and it looks really
nice. I will give it today or on Monday to the users
that have requested it, so they can test in a real
case if this is what they want, but I really think so.
Many many thanks, and also from the users.
Hi,
one comment from our beamline scientists:
the line with 'Input possibilities are' is nice to have,
but should be optional and only appear when 'data_type'
is given. Just now it appears always, with 'String' if
'data_type' is not used.
Could this be changed?.
Hi Teresa,
Regarding the 'input possibilities', we had a look to it between cfalcon and me. Currently there is a default value for data_type which is String.
This is coded in function 'input(self, msg, args, *kwargs)' from sardana/macroserver/macro.py
We have tried to use 'None' as default data_type, but doing so, it becomes mandatory to define the data_type in each macro definition; otherwise no input is accepted by the macro, because the macro is asking for an input with 'None type'. From our point of view it is better to use the default type (which is String currently), and in this case implementing an 'if' condition, in order to do not print the 'input possibilities' when the type is String, does not seem really useful for us; because in some certain imacros maybe the information that a String input data_type is required could be important.
However this can be discussed, between the following three possible solutions:
1- Current solution: default data_type is 'String' and imacros are working even if data_type is not defined in the imacro. The 'input possibilities' in this case are always printed.
2- default data_type is 'String' and imacros are working even if data_type is not defined in the imacro. Use an 'if' in order to do not print the 'input possibilities' in case that data_type is 'String'
3- Use 'None' as default data_type, and define in a mandatory way the data_type in each imacro. In this case the data_type will always be printed, because a 'None' data_type makes the macro unusable.
What do you think?
Cheers,
marc
Hi Marc,
for me the best solution is the 1, that means, the one
it is already implemented ... but I have to ask the users about
it. I tell you then.
Hi Marc,
the beamline people prefer the solution 2, and one have
to know that if nothing is shown the value has to be an string,
selected or by default. They say that it is annoying to have the print
out for each input, that the macro ask for. Could be done like this?.
This feature has been implemented in the develop branch after integrating 5 patches sent to the devel list by mrosanes, cfalcon and zreszela
Sorry, I was requested to open this request again.
The users complain for having always the printed output
Accepted input: String
They want that the default 'Accepted input' do not appears
as printout.
Would this be possible?.
Sorry, could you have a look to this last request from me
(about taking out the 'Accepted input:String' printout)?.
Some of our users do not accepted like this and they make
pressure to change it urgently, sorry.
Hi Teresa,
From ALBA point of view it is OK if the 'Accepted input' is removed. Please, submit a patch to the list with the implementation that DESY users wish.
Many thanks,
marc
Hi Marc,
thanks, I have just sent the patch.
The patch has been reviewed and tested and it applies without problems.
From my point of view it can already be integrated by the integration managers.
I've applied the patch of Teresa to the develop branch.
I'm closing this ticket.