Skip to content

[FEATURE]: Support input_path in generated make() functions from mcstas-pygen #2554

Closed

Description

@MilanKlausz

Is your feature request related to a problem? Please describe.
I use mcstas-pygen to turn an .instr file into a .py script so it can be wrapped in a python package to add a complex detector geometry. The generated script creates a make() function that instantiates McStas_instr with only hardcoded parameters.

The problem is that my package expects custom local components, so McStasScript needs to know where they are (input_path) right at instantiation time. Because make() takes no arguments, I'm forced to manually edit the generated python file to add input_path to the function signature and constructor call each time the base instrument file is edited and the python file is regenerated.

Describe the solution you'd like
It would be great if mcstas-pygen generated the make function with a default parameter: def make(input_path=None):.

This would pass input_path directly to McStas_instr(..., input_path=input_path). Since the constructor signature defaults to input_path=None (resolving to "." internally (see: here)), I expet this change to be completely backward-compatible and won't break any existing scripts calling make() with no arguments.

Describe alternatives you've considered
My alternative is to continue manually editing or to automate overriding :)

Additional context
Looking at the source code, I hope this would be a very quick change in mccode/src/pygen.c:

    #if MCCODE_PROJECT == 1     /* neutron */
      cout("# Python McStas instrument description");
      cout("def make(input_path=None):");
      coutf("    instr = ms.McStas_instr(\"%s_generated\", author = \"McCode Py-Generator\", origin = \"ESS DMSC\", input_path=input_path)",instr->name);
    #elif MCCODE_PROJECT == 2   /* xray */
      cout("# Python McXtrace instrument description");
      cout("def make(input_path=None):");
      coutf("    instr = ms.McXtrace_instr(\"%s_generated\", author = \"McCode Py-Generator\", origin = \"ESS DMSC\", input_path=input_path)",instr->name);
    #endif

Note:
I wouldn't mind having other McStas_instr arguments as well (I manually add output_path and NeXus, but these can be modified through .settings() after the initialisation, so they are not really important)

Activity

  1. willend commented on Jul 6, 2026

    @willend
    Contributor

    @MilanKlausz this can absolutely be done. https://github.com/mccode-dev/McCode/tree/test-pygenmod-2554 is under way.

    For (even minor cogen-) implementing suggestions / changes we always welcome a PR? :-) (Use https://github.com/mccode-dev/McCode/wiki/Build-your-own-McStas-or-McXtrace-via-conda%E2%80%90forge to easily ‘roll your own’ locally in a conda-env.)

    BTW as an alteratvie, I would think that once you are in Python / notebook you would always be able to use the mcrun -I some_path_with_comps via the McStasScript setting custom_flags=‘-I some_path_with_comps’

  2. MilanKlausz commented on Jul 6, 2026

    @MilanKlausz
    ContributorAuthor

    Thank you!

    I'll do PR the next time I see a small enough change ;)

    The -I suggestion made me realise that input_path is rather a working directory change then an include path... and I have runtime data files that are being copied to that "instrument_code" directory, so my notebook sitting in another directory would need more than just -I to make it run, not just compile.

  3. added a commit that references this issue on Jul 6, 2026
  4. willend commented on Jul 6, 2026

    @willend
    Contributor

    I’ve merged #2555 to main - can you try building from that to check that the adaptation does what you want?

  5. mads-bertelsen commented on Jul 7, 2026

    @mads-bertelsen
    Contributor

    Doing exactly this was on my todo list! Agree with doing this only for input_path, as it's the only setting that can not just be updated later.

    As you say input_path only changes where mcrun is executed, not your work directory for the notebook, but typically data files for the simulation can just be in the input_path as mcrun then finds them.
    One exception is if you are using the add_ncrystal_union_material tool in mcstasscript with some custom ncmat files, then they are needed both when creating the instrument file (in python work directory) and when executing mcrun (in input_path). I may update that tool so it looks in the input_path as well!

  6. willend commented on Jul 7, 2026

    @willend
    Contributor

    As I remember, -I for mcrun (and mcstas itself) at least historically added to the “data load path” also… - Or could be made to do so...

  7. MilanKlausz commented on Jul 7, 2026

    @MilanKlausz
    ContributorAuthor

    I've built from main (it WAS super easy to ‘roll my own’ mcstas, nice!), used the resulting mcstas-pygen, and I got exactly what I wanted:

    def make(input_path=None):
        instr = ms.McStas_instr("SKADI_Vexperiment_full_Mantid_generated", author = "McCode Py-Generator", origin = "ESS DMSC", input_path=input_path)

    Thank you!

  8. willend commented on Jul 7, 2026

    @willend
    Contributor

    Great, I think that is worth an incremental release, https://github.com/mccode-dev/McCode/releases/tag/v3.7.12 is slowly but surely on the way to conda-forge now.

  9. willend commented on Jul 7, 2026

    @willend
    Contributor

    And good you liked the new procedure for ‘rolling your own’ @MilanKlausz. 👍 Any feedback welcome if you find issues/annoyances later.

    FYI the ‘main’ McCode CI stuff is now based on the same approach.

  10. willend commented on Oct 20, 2026

    @willend
    Contributor

    Implemented by PR #2555 (daa92c59f, merged 2026-07-06; released in v3.7.12), confirmed above by @MilanKlausz. mccode/src/pygen.c.in now generates def make(input_path=None):, defaulting to the script's own directory. For other setups, the alternatives discussed above also apply, e.g. McStasScript custom_flags='-I <path>'. Closing.

    (Issue triage done by Claude on behalf of @willend.)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions