Skip to content

AB's proposal for refactoring file operations

Duc Le edited this page May 29, 2019 · 4 revisions

Go back: Horace framework redesign ideas


Refactoring the Framework

AB also presented a proposal to rewrite (refactor) parts of the core Matlab Horace code:

This section will deal with a new proposed iSQW class to help with file handling.

Another section deals with his ideas for sqw.

Refactoring inheritance structure of Horace data classes

This mainly involves rewriting the current object-oriented code to be better standards conforming. In particular the refactored classes will have a clearer inheritance structure which follows syntax introduced by Matlab since Horace was originally written.

As a concrete example, take the cut_sqw function which is used to rebin the data including integration over some specified axes. This function branches depending on the type (class) of the first argument, which can be one of:

  • A dnd object
  • An sqw object
  • A filename (the file could contain either a dnd or sqw object)

cut_sqw uses functions in the horace_function_utils folder to parse the argument and construct a structure which determines whether the input is a file or in-memory object and which type (sqw or dnd) it is.

  • If the input is a dnd object or dnd file, cut_sqw calls the cut method of the relevant dnd class.
    • However, this method is just a wrapper around the cut method of the sqw class.
  • If the input is a sqw object or sqw file, cut_sqw calls the cut method of the sqw class directly.

sqw.cut then calls the parsing function to parse its input again, in order to catch the case where it is called directly on a sqw in-memory object rather than from cut_sqw.

sqw.cut then branches again depending on the type of the input:

  • It calls cut_sqw_main if the object is an sqw.
    • This in turn wraps either:
      • cut_data_from_file (if the input is a file)
      • cut_data_from_array (if the input is an in-memory object)
  • It calls cut_dnd_main if the object is a dnd.
    • If the input is a file, cut_dnd_main loads the entire file into memory.
    • It then calls cut_dnd_calc_ubins to do the rebin.

This is an extreme example, but several other functions (e.g. head, refine_crystal/change_crystal, set_sample/set_instrument) have similar indirections to branch depending on class and whether the input is a file or in-memory object. This makes the code convoluted, hard to read/understand, and hence hard to maintain.

The proposed change is to introduce an "abstract base class" called iSQW, which will have virtual methods for the usual sqw/dnd methods (e.g. plot, cut, plus, minus etc), in addition to two extra methods:

  • load will load data from a file, including a file-backed version (loads only headers not pixel information).
  • save

This will formalise the current "dummy" structure generated by the routines in horace_function_utils when something like cut_sqw is called. The new design, however, will have the sqw and dnd classes being derived from iSQW which means that these classes will be able to call load and save transparently. sqw and dnd will still define their own methods separately, and calling cut on such an in-memory object will work the same as it does now. However, calling these methods on files will folow a much simpler workflow:

  • cut_sqw checks whether the input is a file or object.
    • If it is a file, it calls the load method of iSQW.
      • If the file has pixel information, this load will create an sqw object, if not it creates a dnd object.
    • cut_sqw then calls the cut method of iSQW.
      • Because sqw and dnd are derived from iSQW and the objects are polymorphic, the correct concrete cut methods (of either sqw or dnd) are automatically called (since iSQW.cut is virtual).

It is planned that iSQW.load could also create a file-backed sqw object if the input file is sqw-type. This means that it would not load the pixel information (only the headers and pre-calculated binned ["image"] data). Implementation details is not clear, but it might be a new derived class, e.g. file_sqw


Go back: Horace framework redesign ideas

Clone this wiki locally