On Thu, 2006-10-12 at 00:31 +1000, Edward d'Auvergne wrote:
One thought that occured to me is that sometimes its useful to execute a command on several runs (or pipes) at once. One way of doing this would be to retain a 'run' argument for user commands, but to have it optional. If it is passed, then the command executes in each of the specified runs, but returns to the current run after execution. Implimentation of this could employ a generic internal 'run loop' function which loops through the runs and calls the fuction. So we might have, at the prompt code level: def user_command(args, runs=None): sanity_check(args) if runs: run_loop(runs, do_command, args) else: do_command(args) with: def run_loop(runs, do_command, args): current_run = run.current() for run_name in runs: run.switch(run_name) do_command(args) run.switch(current_run) The alternative would be to have the run_loop visible to the user (called something more usefull, I guess), and leave the user to deal with it.This idea, although it is good, unfortunately still suffers from the problem I described in the second paragraph of section 1.1 (https://mail.gna.org/public/relax-devel/2006-10/msg00054.html, Message-id: <1160551172.9523.60.camel@xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx>). The dense branching of the 'run' argument would simply be replaced by the 'runs'. This is a consequence of all the times 'self.relax.data' needs to be accessed. The unnecessary complexity and branching is still there - the 1645 occurrences of the text 'self.run' would remain, they would just be renamed to 'self.runs'.
Either I don't understand the problem, or you don't understand my solution (or both? - either way probably my fault). Importantly, if it is not already clear, what I am suggesting is a simple extension of your proposal, not a replacement for it. As I see it, the proposal above doesn't involve branching of the 'runs' argument - it is caught at the earliest possible opportunity (ie. in the prompt code) and passed into a simple and general run_loop function. My suggestion is precisely analagous to your spin selection loop in both design and motivation (or if it is not, that is because I'm not understanding something - it is my intention that it should be). The 1645 occurrences of self.run would not remain in my suggestion, as I understand it. There are no references to self.run in the psuedocode above, so I see no reason why there should be any more under my proposal that there is under yours. If 'runs' is passed by the user (and I envision this as a relatively rare occurence) it simply has the effect of passing flow control to run_loop so that the desired command is executed in all the required runs in turn. Note that run_loop uses your proposed run.switch() function, it does not pass 'runs' any deeper into the relax code.
If the idea is implemented, the concept should be radically changed so that arguments don't need to be passed into the user functions. The complex branching needs to be eliminated. Is it worth removing the need of 'for' loops from the user? No matter what happens, you need a 'for' loop somewhere if you have a set of pipes and want to apply the same functions to it. I'm not too worried that the user controls that 'for' loop - then the user can decide whether to apply the user function to a single pipe or loop over a set of pipes.
You are right here: all I am suggesting is to put all of the for loops that would otherwise appear in user scripts into a generic function in the highest level of the relax code. I feel that simplicity and readability of users scripts is a fundamentally important goal, and ultimately that is the motivation of the proposal.
I can see how the idea would be implemented in the GUI though! If you have the user function represented as a long rectangular block with the multiple pipes (e.g. all the model-free models) passing through it, that one block could control all the pipes. Edward
Am I being any clearer now, or am I missunderstanding the problem entirely?? Chris