Hi Bas & list,
let me go through your questions:
1) in the current implementation, the batch job itself is a struct/cell array but not an object. Dependencies are objects, but currently each of them lives its own life in a matlabbatch variable. Their actual purpose (linking outputs to inputs) only gets into action when a job is loaded into cfg_util/spm_jobman. You can hand spm_jobman or cfg_util a cell array of jobs (as filenames, matlabbatch variables or a mixture of both). This will correctly concatenate them and update dependencies in much the same way as it happens when you load multiple job files at once into the GUI. Note that you can only create dependencies within each job file/variable, but not across different parts of the concatenated job. If you were to concatenate jobs outside the batch system, you will break dependencies in a bad way.
2) You would want to interface to cfg_util in this case (after starting up SPM properly, of course). There is an easy and a more difficult part of this exercise, though. The easy thing is to initialise your job and get all virtual outputs:
[job_id modids] = cfg_util('initjob', ...); ill in your (cell array of) jobs
The first output argument is your jobid. You will need this every time you want to refer to your job (for e.g. running it, getting virtual outputs or real outputs). The second output argument is a cell list of module ids, one for each module in your job. This is valuable if you want to reference just a certain module in your job.
Then, you would do
voutputs = cfg_util('getAllVOutputs', job_id);
This returns a cell list of virtual outputs, one cell item per module. These are dependency objects, that can be used as inputs later on. Note, that modules will only return virtual outputs if their input structure is completely specified. E.g. if you had a "Realign: Estimate" module, it would only return a dependency if it has at least one session specified.
Using the dependencies as inputs can become more difficult than getting them out of the job. It will be easiest, when your batch has "<-X"/"<UNDEFINED>" marks wherever you want to put in any input programmatically. You can then use
sts = cfg_util('filljob', job_id, ...);
In the input list that follows job_id, you can mix real inputs and appropriate dependencies from voutputs. Note that usually this does not change the input structure of your job. You could add e.g. sessions this way, but 1) the required inputs are quite cumbersome and 2) it would break existing dependencies. You should use the GUI to design job templates that only require entry/file/menu values to be filled.
If everything went ok, sts should be true, and you are ready to run your job
cfg_util('run', job_id)
Afterwards, you can run
outputs = cfg_util('getAllOutputs', job_id);
to get a list of real outputs of each module or
[tag, val] = cfg_util('harvestrun', job_id)
to get a matlabbatch job val where all dependencies are replaced by real inputs.
3. No, there isn't (yet). Housekeeping of virtual file names was the performance bottleneck in SPM5 spm_jobman. This was one of the reasons to replace it by dependencies. Therefore, filenames are now computed at run-time. There are plans to implement a 'dryrun' feature, but it requires quite a lot of changes to existing code in both SPM and matlabbatch.
|