How to wrap Executable line into a loop

Hey :wave:

I have a small tool that handles cube files. Among other parameters, the tool expects the input name and output name of the file:

cubehandler shrink [options] input_file output_file

I am preparing a plugin for it to post-process the cube files created in a previous QE/CP2K/… calculation.

To be able to analyse multiple cube files in one go, I would like to wrap the execution in a bash loop:

for file in <files>; do
    cubehandler shrink [options] ${file} out_${file}
done

My only option now is to put for file in <files>; do into mpirun_extra_params and done in the cmdline parameters of the code, but this is ugly. Are there any better options?

Thank you very much.

Best,
Sasha

Hi Sasha, with the CalcJob options available in AiiDA there is not much better you can do than the hack you sketched out. One alternative I see is to instead of calling cubehandler as the “code” directly, to write bash script that contains the loop itself and call that as the code:

#!/bin/bash

options="$@"
for file in input*.cube; do
    cubehandler shrink "$options" ${file} out_${file}
done

Now to easily run this, I would recommend using aiida-shell.
Simply store that bash script on the remote computer, put it in the PATH and make it executable. Then you can run it with something like:

from aiida_shell import launch_shell_job
results, node = launch_shell_job(
    'cube_shrinker.sh',
    arguments='-s some-flag --quick -O option',
    nodes={
        'cube_1': SinglefileData(..., filename='input_1.cube'),
        'cube_2': SinglefileData(..., filename='input_2.cube'),
    },
    output=['out_*.cube'],
    metadata={
        'options': {
            'computer': load_computer('target-computer'),
        }
    }
)

I haven’t tried this, but I think it should be close to working. No dedicated plugin even necessary.

In addition to @sphuber’s comment: since you are writing the cubehandler script, you can just have the option to specify more than one input filename in the cmdline (or maybe a folder, where you process all .cube files), and just a folder for all the outputs. So you can just do a single call of the code, and then retrieve all files with some wildcard, e.g. outputs/.cube.
Also in this case of course you could still use aiida-shell directly (possibly combined with a custom parser if needed to convert .cube into some AiiDA-specific format?0