• topas
  • Stephens Peakshapes for TOF NPD

Hi Both,

Thanks for your help here. I have modified the original stephens macro to replace tan Th with D_spacing as suggested:

macro TOF_Stephens_monoclinic(s400, s040, s004, s220, s202, s022, s301, s121, s103, eta)
{
prm mhkl = H4 s400 + K4 s040 + L4 s004 +
H2 K2 s220 + H2 L2 s202 + K2 L2 s022 +
H K2 L s121 +
H L3 s103 + H3 L s301;

prm pp = D_spacing2 * Sqrt(Max(mhkl,0)) / 1000;

gauss_fwhm = 1.8/3.1415927 pp (1-eta) D_spacing + 0.0001;
lor_fwhm = 1.8/3.1415927 pp eta D_spacing + 0.0001;
}

Which I am calling as such in the refinement (note for the XRD I call "Stephens_monoclinic" in this same way, with no issues):

TOF_Stephens_monoclinic
(
eta, 0.5,
s400, 200,
s040, 200,
s004, 200,
s220, 200,
s202, 200,
s022, 200,
s121, 200,
s103, 200,
s301, 200
)

However, I'm still receiving the same error message:

"Cannot find match for macro TOF_Stephens_monoclinic
Number of arguements 20"

As suggested above, it is saying that it cannot find this macro, which takes 20 arguments (corresponding to the 10 parameter names and 10 parameter values in the called macro).

I'm defining this, as I would any temporary macro, at the top of the file (as opposed to in the .inc). This works just fine for the other macros I have defined this way, such as the below:

macro Out_Tick_XRD_Q(file)
{
phase_out file load out_record out_fmt out_eqn
{
" %11.5f 200\n" = 2 *Pi / D_spacing;
}
}


Is there any reason why TOPAS would not be recognising this user defined macro? I have tried changing the name in case there is anything special about it, but I receive the same error, only with the new name. Functionally, the only differences between the macro I am trying to use (unsuccessfully), and the default stephens_monoclinic, is the new name, and the replacement of tan Th with D_spacing.

Checking the stephens_monoclinic macro in our topas.inc (V7) actually shows it is a bit different to that on the topas website:

macro Stephens_monoclinic
(
etac, etav,
s400c,s400v,
s040c,s040v,
s004c,s004v,
s220c,s220v,
s202c,s202v,
s022c,s022v,
s121c,s121v,
s103c,s103v,
s301c,s301v
)
{
#m_argu s400c If_Prm_Eqn_Rpt(s400c, s400v,)
#m_argu s040c If_Prm_Eqn_Rpt(s040c, s040v,)
#m_argu s004c If_Prm_Eqn_Rpt(s004c, s004v,)
#m_argu s220c If_Prm_Eqn_Rpt(s220c, s220v,)
#m_argu s202c If_Prm_Eqn_Rpt(s202c, s202v,)
#m_argu s022c If_Prm_Eqn_Rpt(s022c, s022v,)
#m_argu s121c If_Prm_Eqn_Rpt(s121c, s121v,)
#m_argu s103c If_Prm_Eqn_Rpt(s103c, s103v,)
#m_argu s301c If_Prm_Eqn_Rpt(s301c, s301v,)
Stephens_lor_gauss(
etac, etav,
CeV(s400c,s400v) H4 +
CeV(s040c,s040v) K4 +
CeV(s004c,s004v) L4 +
CeV(s220c,s220v) H2 K2 +
CeV(s202c,s202v) H2 L2 +
CeV(s022c,s022v) K2 L2 +
CeV(s121c,s121v) H K2 L +
CeV(s103c,s103v) H L3 +
CeV(s301c,s301v) H3 L
)
}

I am a little confused, as this seems to entirely remove reference to the tan Th, which we thought was causing the TOF incompatibility to begin with. Apologies for the wall of text, if you have any suggestions for why this might still not be working, any advice greatly appreciated!

Thanks again for your time and help!

    I think you're just missing a #m_argu for (eta,etav) which is in your macro call.

      So you have defined a macro

      macro TOF_Stephens_monoclinic(s400, s040, s004, s220, s202, s022, s301, s121, s103, eta)
      {
      prm mhkl = H4 s400 + K4 s040 + L4 s004 +
      H2 K2 s220 + H2 L2 s202 + K2 L2 s022 +
      H K2 L s121 +
      H L3 s103 + H3 L s301;
      
      prm pp = D_spacing2 * Sqrt(Max(mhkl,0)) / 1000;
      
      gauss_fwhm = 1.8/3.1415927 pp (1-eta) D_spacing + 0.0001;
      lor_fwhm = 1.8/3.1415927 pp eta D_spacing + 0.0001;
      }

      which you are then calling in your input file as

      TOF_Stephens_monoclinic(eta, 0.5, s400, 200, s040, 200, s004, 200, s220, 200, s202, 200, s022, 200, s121, 200, s103, 200, s301, 200)

      Is that correct?

      Well, there's your problem. You've defined a macro with 10 arguments and are calling it with 20. TOPAS then complains that it can't find a macro definition with 20 arguments because you haven't provided one.

      You need to call it with 10 arguments.

      prm eta 0.5
      prm s400 200
      prm s040 200
      prm s004 200
      prm s220 200
      prm s202 200
      prm s022 200
      prm s121 200
      prm s103 200
      prm s301 200
      TOF_Stephens_monoclinic(eta, s400, s040, s004, s220, s202, s022, s121, s103, s301)

        jmas5 Checking the stephens_monoclinic macro in our topas.inc (V7) actually shows it is a bit different to that on the topas website:

        macro Stephens_monoclinic
        ...
        }

        I am a little confused, as this seems to entirely remove reference to the tan Th, which we thought was causing the TOF incompatibility to begin with.

        It just abstracts away the Tan(Th) to the Stephens_lor_gauss macro, which is

        macro Stephens_lor_gauss(etac, etav, mhkl)
        {
           #m_argu etac  If_Prm_Eqn_Rpt(etac, etav, min 0 max 1)   
                       local #m_unique pp_ = D_spacing^2 * Sqrt(Max(mhkl,0)) Tan(Th) 0.0018/3.1415927;
                       gauss_fwhm =  pp_ (1-CeV(etac, etav));
                       lor_fwhm   =  pp_ CeV(etac, etav);
        }

        Hi Both, thanks again for your help and patience with me on this!

        johnsoevans For John's comment, I think that's correct, but for some reason that macro works just fine for the xray xdds and has never had an issue. I think possibly because it is defined in the "Stephens_lor_gauss" macro that it calls? For consistency, I have tried making the below macro, where I have replaced references to tan Th with D_spacing:

        Macro:

        macro TOF_Stephens_lor_gauss(etac, etav, mhkl)
        {
        #m_argu etac If_Prm_Eqn_Rpt(etac, etav, min 0 max 1)
        local #m_unique pp_ = D_spacing2 * Sqrt(Max(mhkl,0)) D_spacing 0.0018/3.1415927;
        gauss_fwhm = pp_ (1-CeV(etac, etav));
        lor_fwhm = pp_ CeV(etac, etav);
        }

        macro TOF_Stephens_monoclinic
        (
        etac, etav,
        s400c,s400v,
        s040c,s040v,
        s004c,s004v,
        s220c,s220v,
        s202c,s202v,
        s022c,s022v,
        s121c,s121v,
        s103c,s103v,
        s301c,s301v
        )
        {
        #m_argu s400c If_Prm_Eqn_Rpt(s400c, s400v,)
        #m_argu s040c If_Prm_Eqn_Rpt(s040c, s040v,)
        #m_argu s004c If_Prm_Eqn_Rpt(s004c, s004v,)
        #m_argu s220c If_Prm_Eqn_Rpt(s220c, s220v,)
        #m_argu s202c If_Prm_Eqn_Rpt(s202c, s202v,)
        #m_argu s022c If_Prm_Eqn_Rpt(s022c, s022v,)
        #m_argu s121c If_Prm_Eqn_Rpt(s121c, s121v,)
        #m_argu s103c If_Prm_Eqn_Rpt(s103c, s103v,)
        #m_argu s301c If_Prm_Eqn_Rpt(s301c, s301v,)
        TOF_Stephens_lor_gauss(
        etac, etav,
        CeV(s400c,s400v) H4 +
        CeV(s040c,s040v) K4 +
        CeV(s004c,s004v) L4 +
        CeV(s220c,s220v) H2 K2 +
        CeV(s202c,s202v) H2 L2 +
        CeV(s022c,s022v) K2 L2 +
        CeV(s121c,s121v) H K2 L +
        CeV(s103c,s103v) H L3 +
        CeV(s301c,s301v) H3 L
        )
        }

        This yields the below error, when called like this (with the 20 arguments):

        Call:

        TOF_Stephens_monoclinic
        (
        etac, 0.5,
        s400c, 200,
        s040c, 200,
        s004c, 200,
        s220c, 200,
        s202c, 200,
        s022c, 200,
        s121c, 200,
        s103c, 200,
        s301c, 200
        )

        Error:

        " Uninitialized_Variable in equation: m672c9d7a_1b"

        rowlesmr Taking Matt's approach for the below macro, is also resulting in a different error currently:

        Macro:

        macro TOF_Stephens_monoclinic(s400, s040, s004, s220, s202, s022, s301, s121, s103, eta)
        {
        prm mhkl = H4 s400 + K4 s040 + L4 s004 +
        H2 K2 s220 + H2 L2 s202 + K2 L2 s022 +
        H K2 L s121 +
        H L3 s103 + H3 L s301;

        prm pp = D_spacing2 * Sqrt(Max(mhkl,0)) / 1000;

        gauss_fwhm = 1.8/3.1415927 pp (1-eta) D_spacing + 0.0001;
        lor_fwhm = 1.8/3.1415927 pp eta D_spacing + 0.0001;
        }

        Call:

        prm eta 0.5
        prm s400 200
        prm s040 200
        prm s004 200
        prm s220 200
        prm s202 200
        prm s022 200
        prm s121 200
        prm s103 200
        prm s301 200
        TOF_Stephens_monoclinic(eta, s400, s040, s004, s220, s202, s022, s121, s103, s301)

        Error:
        "Uninitialized_Variable in equation: K2"

        I wonder if the error is the same between them both, just that it is named in the second macro and not in the first? Thanks again for your help!

        (Edit: re-posting with correct formatting)

        Hi Both, thanks again for your help and patience with me on this!

        johnsoevans For John's comment, I think that's correct, but for some reason that macro works just fine for the xray xdds and has never had an issue. I think possibly because it is defined in the "Stephens_lor_gauss" macro that it calls? For consistency, I have tried making the below macro, where I have replaced references to tan Th with D_spacing:

        Macro:

        macro TOF_Stephens_lor_gauss(etac, etav, mhkl)
        {
        #m_argu etac If_Prm_Eqn_Rpt(etac, etav, min 0 max 1)
        local #m_unique pp_ = D_spacing2 * Sqrt(Max(mhkl,0)) D_spacing 0.0018/3.1415927;
        gauss_fwhm = pp_ (1-CeV(etac, etav));
        lor_fwhm = pp_ CeV(etac, etav);
        }
        macro TOF_Stephens_monoclinic
        (
        etac, etav,
        s400c,s400v,
        s040c,s040v,
        s004c,s004v,
        s220c,s220v,
        s202c,s202v,
        s022c,s022v,
        s121c,s121v,
        s103c,s103v,
        s301c,s301v
        )
        {
        #m_argu s400c If_Prm_Eqn_Rpt(s400c, s400v,)
        #m_argu s040c If_Prm_Eqn_Rpt(s040c, s040v,)
        #m_argu s004c If_Prm_Eqn_Rpt(s004c, s004v,)
        #m_argu s220c If_Prm_Eqn_Rpt(s220c, s220v,)
        #m_argu s202c If_Prm_Eqn_Rpt(s202c, s202v,)
        #m_argu s022c If_Prm_Eqn_Rpt(s022c, s022v,)
        #m_argu s121c If_Prm_Eqn_Rpt(s121c, s121v,)
        #m_argu s103c If_Prm_Eqn_Rpt(s103c, s103v,)
        #m_argu s301c If_Prm_Eqn_Rpt(s301c, s301v,)
        TOF_Stephens_lor_gauss(
        etac, etav,
        CeV(s400c,s400v) H4 +
        CeV(s040c,s040v) K4 +
        CeV(s004c,s004v) L4 +
        CeV(s220c,s220v) H2 K2 +
        CeV(s202c,s202v) H2 L2 +
        CeV(s022c,s022v) K2 L2 +
        CeV(s121c,s121v) H K2 L +
        CeV(s103c,s103v) H L3 +
        CeV(s301c,s301v) H3 L
        )
        }

        This yields the below error, when called like this (with the 20 arguments):

        Call:

        TOF_Stephens_monoclinic
        (
        etac, 0.5,
        s400c, 200,
        s040c, 200,
        s004c, 200,
        s220c, 200,
        s202c, 200,
        s022c, 200,
        s121c, 200,
        s103c, 200,
        s301c, 200
        )

        Error:

        " Uninitialized_Variable in equation: m672c9d7a_1b"

        rowlesmr Taking Matt's approach for the below macro, is also resulting in a different error currently:

        Macro:

        macro TOF_Stephens_monoclinic(s400, s040, s004, s220, s202, s022, s301, s121, s103, eta)
        {
        prm mhkl = H4 s400 + K4 s040 + L4 s004 +
        H2 K2 s220 + H2 L2 s202 + K2 L2 s022 +
        H K2 L s121 +
        H L3 s103 + H3 L s301;
        
        prm pp = D_spacing2 * Sqrt(Max(mhkl,0)) / 1000;
        
        gauss_fwhm = 1.8/3.1415927 pp (1-eta) D_spacing + 0.0001;
        lor_fwhm = 1.8/3.1415927 pp eta D_spacing + 0.0001;
        }

        Call:

        prm eta 0.5
        prm s400 200
        prm s040 200
        prm s004 200
        prm s220 200
        prm s202 200
        prm s022 200
        prm s121 200
        prm s103 200
        prm s301 200
        TOF_Stephens_monoclinic(eta, s400, s040, s004, s220, s202, s022, s121, s103, s301)

        Error:
        "Uninitialized_Variable in equation: K2"

        I wonder if the error is the same between them both, just that it is named in the second macro and not in the first? Thanks again for your help!

        Its a copy/paste forum-formatting issue (at least for the error in my macro)

        macro TOF_Stephens_monoclinic(s400, s040, s004, s220, s202, s022, s301, s121, s103, eta)
        {
        prm mhkl = H^4 s400 + K^4 s040 + L^4 s004 +
        H^2 K^2 s220 + H^2 L^2 s202 + K^2 L^2 s022 +
        H K^2 L s121 +
        H L^3 s103 + H^3 L s301;
        
        prm pp = D_spacing^2 * Sqrt(Max(mhkl,0)) / 1000;
        
        gauss_fwhm = 1.8/3.1415927 pp (1-eta) D_spacing + 0.0001;
        lor_fwhm = 1.8/3.1415927 pp eta D_spacing + 0.0001;
        }

        You need the sysmbol in there to make a power.

        Thanks for this! That does seem to have been the issue with that macro. However, I'm now getting a different error (though I think this now means that the macro itself is working). The new fun error is "Negative FWHM encountered", which I have seen before when I accidentally leave these parameters refining with simulated annealing on. I'm wondering if perhaps the starting parameters that the macro for XRD uses will now need to be different for NPD? To confirm, I'm currently using:

        Macro:

        `macro TOF_Stephens_monoclinic(s400, s040, s004, s220, s202, s022, s301, s121, s103, eta)
        {
        prm mhkl = H4 s400 + K4 s040 + L4 s004 +
        H2 K2 s220 + H2 L2 s202 + K2 L2 s022 +
        H K2 L s121 +
        H L3 s103 + H3 L s301;

        prm pp = D_spacing2 * Sqrt(Max(mhkl,0)) / 1000;

        gauss_fwhm = 1.8/3.1415927 pp (1-eta) D_spacing + 0.0001;
        lor_fwhm = 1.8/3.1415927 pp eta D_spacing + 0.0001;
        }
        `

        Input file:
        prm eta 0.5
        prm s400 200
        prm s040 200
        prm s004 200
        prm s220 200
        prm s202 200
        prm s022 200
        prm s121 200
        prm s103 200
        prm s301 200
        TOF_Stephens_monoclinic(eta, s400, s040, s004, s220, s202, s022, s121, s103, s301)

        Setting all the parameters to 1 (instead of 200) allowed the refinement to initialise, but after one run I encountered the negative FWHM error again. I was able to get around this with the below restrictions, however all the parameters do minimise. Is this physically meaningful?

        prm eta_b5 0.5 min 0 max 1
        prm s400_b5 0.01 min 0 max 1
        prm s040_b5 0.01 min 0 max 1
        prm s004_b5 0.01 min 0 max 1
        prm s220_b5 0.01 min 0 max 1
        prm s202_b5 0.01 min 0 max 1
        prm s022_b5 0.01 min 0 max 1
        prm s121_b5 0.01 min 0 max 1
        prm s103_b5 0.01 min 0 max 1
        prm s301_b5 0.01 min 0 max 1
        TOF_Stephens_monoclinic(eta_b5, s400_b5, s040_b5, s004_b5, s220_b5, s202_b5, s022_b5, s121_b5, s103_b5, s301_b5)

        Thanks again for your continued help!

        Apologies, macro was not formatted as code. Re-posted below:

        `macro TOF_Matt_Stephens_monoclinic(s400, s040, s004, s220, s202, s022, s301, s121, s103, eta)
        {
        prm mhkl = H4 s400 + K4 s040 + L4 s004 +
        H2 K2 s220 + H2 L2 s202 + K2 L2 s022 +
        H K2 L s121 +
        H L3 s103 + H3 L s301;

        prm pp = D_spacing2 * Sqrt(Max(mhkl,0)) / 1000;

        gauss_fwhm = 1.8/3.1415927 pp (1-eta) D_spacing + 0.0001;
        lor_fwhm = 1.8/3.1415927 pp eta D_spacing + 0.0001;
        } `

        Also for reference, below are the refined values:

        prm eta_b5 0.0625563.501034_LIMIT_MIN_0 min 0 max 1
        prm s400_b5 0.87625_4709.88862_LIMIT_MIN_0 min 0 max 1
        prm s040_b5 0.87625
        4764.84687_LIMIT_MIN_0 min 0 max 1
        prm s004_b5 0.12625_875.637423_LIMIT_MIN_0 min 0 max 1
        prm s220_b5 0.62625
        4261.83885_LIMIT_MIN_0 min 0 max 1
        prm s202_b5 0.87625_4728.59797_LIMIT_MIN_0 min 0 max 1
        prm s022_b5 0.87625
        5195.35536_LIMIT_MIN_0 min 0 max 1
        prm s121_b5 0.87625_4906.25752_LIMIT_MIN_0 min 0 max 1
        prm s103_b5 0.37625
        _2631.16776_LIMIT_MIN_0 min 0 max 1
        prm s301_b5 0.87625_2375.1912_LIMIT_MIN_0 min 0 max 1

        I do not know why it is not formatting correctly, but the "^" signs are in the macro as below

        The Max(mhkl, 0) should stop pp from going negative. Have you tried just putting the min/max on the eta Gaussian/Lorentzian broadening term? That should be the only term left that would allow a negative fwhm (unless you are also refining other peak shape parameters).

        [The code formatting on the wiki isn't topas-specific. It's just something built in that "almost works". Sorry for hassle.]

          johnsoevans

          Hi John,

          Thanks for your message. Trying to use the standard values of 200 (Also happens for 20, 2) for the sx terms, with only min 0 max 1 (start 0.5) on eta, still results in the negative FWHM error. I can get it start the refinement by setting them all to 1 (or 0.5/0.05...), but I quickly encounter negative FHWM error on the first step. It seems the only way I can make the refinement happy is to give it min 0 max 1 for all parameters, below are my starting point and the refined values. If this seems physically reasonable I am happy to use this, but would like to avoid adding extra terms otherwise. Thanks again for your help!

          Macro:

          `macro TOF_Stephens_monoclinic(s400, s040, s004, s220, s202, s022, s301, s121, s103, eta)
          {
          prm mhkl = H4 s400 + K4 s040 + L4 s004 +
          H2 K2 s220 + H2 L2 s202 + K2 L2 s022 +
          H K2 L s121 +
          H L3 s103 + H3 L s301;

          prm pp = D_spacing2 * Sqrt(Max(mhkl,0)) / 1000;

          gauss_fwhm = 1.8/3.1415927 pp (1-eta) D_spacing + 0.0001;
          lor_fwhm = 1.8/3.1415927 pp eta D_spacing + 0.0001;
          } `

          Call:

          prm eta_b5 0.5 min 0 max 1
          prm s400_b5 0.05 min 0 max 1
          prm s040_b5 0.05 min 0 max 1
          prm s004_b5 0.05 min 0 max 1
          prm s220_b5 0.05 min 0 max 1
          prm s202_b5 0.05 min 0 max 1
          prm s022_b5 0.05 min 0 max 1
          prm s121_b5 0.05 min 0 max 1
          prm s103_b5 0.05 min 0 max 1
          prm s301_b5 0.05 min 0 max 1
          TOF_Stephens_monoclinic(eta_b5, s400_b5, s040_b5, s004_b5, s220_b5, s202_b5, s022_b5, s121_b5, s103_b5, s301_b5)

          Refined values:

          prm eta_b5 0.0625561.686111_LIMIT_MIN_0 min 0 max 1
          prm s400_b5 0.88125_4732.37809_LIMIT_MIN_0 min 0 max 1
          prm s040_b5 0.88125
          4789.89379_LIMIT_MIN_0 min 0 max 1
          prm s004_b5 0.00625_562.368449_LIMIT_MIN_0 min 0 max 1
          prm s220_b5 0.25625
          3034.88555_LIMIT_MIN_0 min 0 max 1
          prm s202_b5 0.88125_4752.97901_LIMIT_MIN_0 min 0 max 1
          prm s022_b5 0.88125
          5428.61298_LIMIT_MIN_0 min 0 max 1
          prm s121_b5 0.88125_4917.87234_LIMIT_MIN_0 min 0 max 1
          prm s103_b5 0.63125
          _3928.17146_LIMIT_MIN_0 min 0 max 1
          prm s301_b5 0.88125_2386.28893_LIMIT_MIN_0 min 0 max 1

          Those large errors on the coefficients are concerning. They show that something not quite right is going on.

          Other things to try are wrapping the gauss and lor equations in Abs(...) or 'Max(..., 0)`, but I can't really grep how those equations can be negative given all of the other constraints.

            rowlesmr
            Updated macro:

            Input 1:

            Resultant output1 :

            Result: Very large errors as before

            Input 2:

            Output 2:

            Result: Quite large values (?), no large errors except for eta which is the only param with the min 0 max 1 left

            Input 3:

            Output 3:

            Result: No large errors, I guess because they are now allowed to go to huge values which they seem to want to do. I don't know if this is physically meaningful.

            I think, overall, the Abs(x) has eliminated the prior issues of negative FWHM, so that I don't need the min x max y restraints on the values. My question now then is, are the values it is refining to sensible? I have included the XRD stephens monoclinic parameters below for comparison, as they are quite different. My main concern is Eta, which I believed should be between 0 and 1? I don't know if this is different when working with TOF data?

            Thanks again for your help!

            7 days later

            Caveat: Never used TOF, never seriously used Stephen's peak shape.

            I have no intuition as to sensible magnitudes for the parameters.

            eta really only makes sense in the range [0,1], as it is a mixing parameter between lorentzian and gaussian peakshapes.

            I would posit that output 3 still shows large errors; 5000 +- 100000 is a large error.

            .

            As a final thought, do you have the correct functional form? I've worked through the paper and have derived eqn 4 by differentiating Bragg's Law. I assume that I could then follow through the separation into Lorentzian and Gaussian widths. The paper does say "A similar result for the peak-width as a function of s2(M_hkl) may be derived for TOF neutron diffraction.". Have you done this? It might be worth the trouble.

            Unfortunately, my brain isn't good enough to think of where/how to start...

            Hiya all
            Matthew emailed me to see if I could add anything useful so here are my tuppences….

            I don’t do much with TOF data these days but my comments come in two parts – one is more instrument specific and other is more general.

            From my recollection WISH is the only other TOF instrument that uses a POWGEN-style geometry for the detector geometry giving a smooth deltaD/D – allowing all the data to be combined into a single as done at POWGEN if desired. I’ve never played with WISH data, but I know POWGEN data rather well 😉
            In TOF-speak POWGEN’s banks are actually more accurately different frames with differing centre wavelengths – I’ve no idea if WISH is doing the same or if the detectors are ‘banked’ during data reduction by two theta into separate datasets replicating a more conventional instrument such as POLARIS. In a full, combined dataset any component with a d-dependence is very challenging to model as the range is much wider than normal. In GSAS-II Bob Von Dreele added a couple of extra terms into the usual TOF equations to improve the fit to POWGEN data specifically, DIFB with a 1/d dependence is added to the TOF-to-d conversion:
            macro mod_TOF_d {
            pk_xo = zero + dif_c D_spacing + dif_a D_spacing2 + dif_b/D_spacing;
            }

            and the term BETAQ, also with a 1/d dependence to the back-to-back
            macro GSAS_btb_mod
            {
            push_peak 'GSAS-II TOF back-to-back peak shape
            exp_conv_const = alpha0 + alpha1 / D_spacing;
            bring_2nd_peak_to_top
            exp_conv_const = beta0 + (beta1 / D_spacing4) + (betaq/D_spacing);
            add_pop_1st_2nd_peak
            }
            It’s possible that WISH data might also benefit from the more sophisticated calibration.

            Now for the profile…..
            I never used the Stephen’s model with TOF in TOPAS but the foundation is the same as any other TOF correction.
            One of the first places to look for many TOF-related equations is the old GSAS-I manual as the program was primarily written for TOF neutron data with constant wavelength and X-rays added later – other programs have done it in reverse. The Stephens model is TOF Profile 4 in the GSAS-I manual (page 149).
            Assuming Tan(Th) is a microstrain term simply switching for D-spacing alone won’t work as the d-spacing dependence of peak broadening is more complex for TOF data. For instance the TCH profile in TOF looks like the following in terms in GSAS-style Gaussian sigmas and Lorentzian gammas.

            'TCH profiles for TOF
            macro TCH_TOF
            {
            local G_FWHM = (Sqrt(8 Ln(2) * (sig02 + (sig12 * D_spacing2) + (sig22 * D_spacing4))));
            local gam_L = gam0 + (gam1 * D_spacing) + (gam2 * D_spacing2);
            local tch_p_l = gam_L;
            local tch_p_g = G_FWHM;
            local tch_p '0.5
            = (
            tch_p_g5 +
            2.69269 tch_p_g4 tch_p_l +
            2.42843 tch_p_g3 tch_p_l2 +
            4.47163 tch_p_g2 tch_p_l3 +
            0.07842 tch_p_g tch_p_l4 +
            tch_p_l5
            )0.2;
            local tch_q = tch_p_l / tch_p;
            }

            The base TOF pseudo-Voigt is what you need to modify to get the Stephens broadening model with the modifications below from a screen-grab from the GSAS-I manual. Sigma(s)2 and Gamma(s) are the Gaussian and Lorentzian contributions to the microstrain that would appear to have a d3 dependence. Phi is described under TOF profile 1.

            Finally a few suggestions with regard to multi-dataset refinements if you’re using the for_xdds construction.
            Take care not to use any ‘@’ inside the loops. Macros can sometimes misbehave when called inside for_xdds and need to be switched under the individual datasets. Beware of ‘scope’ in TOPAS. Parameter scope is very powerful if you leverage it correctly passing ‘local’ parameters to a common macro but beware that Alan has on occasion changed the scope of some parameters so files aren’t always compatible across TOPAS versions.

            Have fun!
            Pam

            4 months later

            Apologies for the long lapse in response here, it's been a busy few months! Giulio Lampronti and I spend a bit of time looking at this back in December, and managed to get it working well in the input file itself. However, I'm finding a little difficulty in converting to the form of a macro. The code that works (at least for monoclinic, it shouldn't be difficult to change for the rest) is as follows: (note, the forums may format this slightly dodgy, so have also attached screenshots)

            prm s400 1e+161.05335787 min 0.000000000000001 max 1e+20
            prm s040 4.02030236e+10_1.05335787_LIMIT_MIN_1e-15 min 0.000000000000001 max 1e+20
            prm s004 8.03640459e+10
            2.78826643e+20_LIMIT_MIN_1e-15 min 0.000000000000001 max 1e+20
            prm s220 8.28938399e+12_1.05335787 max 1e+20
            prm s202 -1.23829058e+12
            1.05335787 max 1e+20
            prm s022 1.60728092e+11_1.05335787 max 1e+20
            prm s301 3.48795127e+09
            1.05335787 max 1e+20
            prm s121 2.40541613e+11_1.05335787 max 1e+20
            prm s103 -9.14581569e+11
            1.05335787 max 1e+20
            prm eta_TOF 0.999999871`
            0.210782633_LIMIT_MIN_1e-10 min 0.0000000001 max 0.9999999999
            prm mhkl = H4 s400 + K4 s040 + L4 s004
            + H2 K2 s220 + H2 L2 s202 + K2 L2 s022
            + H3 L1 s301 + H1 L3 s103 + H1 K2 L1 s121;


                        'lor_fwhm = eta * (D_spacing^2 * Sqrt(Max(mhkl,0)) Tan(Th) 0.0018/3.1415927;  
                        'gauss_fwhm = (1 - eta) * (D_spacing^2 * Sqrt(Max(mhkl,0)) Tan(Th) 0.0018/3.1415927;  `

            To adapt this into a macro, I attempted to use the XRD macro from our topas.inc as inspiration:

            `macro Stephens_lor_gauss(etac, etav, mhkl)
            {
            #m_argu etac If_Prm_Eqn_Rpt(etac, etav, min 0 max 1)
            local #m_unique pp_ = D_spacing2 * Sqrt(Max(mhkl,0)) Tan(Th) 0.0018/3.1415927;
            gauss_fwhm = pp_ (1-CeV(etac, etav));
            lor_fwhm = pp_ CeV(etac, etav);
            }


            macro Stephens_monoclinic
            (
            etac, etav,
            s400c,s400v,
            s040c,s040v,
            s004c,s004v,
            s220c,s220v,
            s202c,s202v,
            s022c,s022v,
            s121c,s121v,
            s103c,s103v,
            s301c,s301v
            )
            {
            #m_argu s400c If_Prm_Eqn_Rpt(s400c, s400v,)
            #m_argu s040c If_Prm_Eqn_Rpt(s040c, s040v,)
            #m_argu s004c If_Prm_Eqn_Rpt(s004c, s004v,)
            #m_argu s220c If_Prm_Eqn_Rpt(s220c, s220v,)
            #m_argu s202c If_Prm_Eqn_Rpt(s202c, s202v,)
            #m_argu s022c If_Prm_Eqn_Rpt(s022c, s022v,)
            #m_argu s121c If_Prm_Eqn_Rpt(s121c, s121v,)
            #m_argu s103c If_Prm_Eqn_Rpt(s103c, s103v,)
            #m_argu s301c If_Prm_Eqn_Rpt(s301c, s301v,)
            Stephens_lor_gauss(
            etac, etav,
            CeV(s400c,s400v) H4 +
            CeV(s040c,s040v) K4 +
            CeV(s004c,s004v) L4 +
            CeV(s220c,s220v) H2 K2 +
            CeV(s202c,s202v) H2 L2 +
            CeV(s022c,s022v) K2 L2 +
            CeV(s121c,s121v) H K2 L +
            CeV(s103c,s103v) H L3 +
            CeV(s301c,s301v) H3 L
            )
            }
            `

            Below is as far as I've gotten with the TOF macro. I think the main issue is that I need to incorporate the flightpath variable which is now present in the stephens_lor_gauss function, which I'm not quite sure how to do:

            `macro TOF_Stephens_lor_gauss(etac, etav, mhkl, flight_path)
            {
            #m_argu eta_TOF If_Prm_Eqn_Rpt(etac, etav, min 0 max 1)
            local #m_unique pp_ = (D_spacing2 * Sqrt(Max(mhkl,0))) Tan(ArcSin((1.977 * 0.001) / (flight_path * D_spacing))) 0.0018/3.1415927;
            gauss_fwhm = pp_ (1-CeV(etac, etav));
            lor_fwhm = pp_ CeV(etac, etav);
            }

            macro TOF_Stephens_monoclinic
            (
            etac, etav,
            s400c,s400v,
            s040c,s040v,
            s004c,s004v,
            s220c,s220v,
            s202c,s202v,
            s022c,s022v,
            s121c,s121v,
            s103c,s103v,
            s301c,s301v
            )
            {
            #m_argu s400c If_Prm_Eqn_Rpt(s400c, s400v,)
            #m_argu s040c If_Prm_Eqn_Rpt(s040c, s040v,)
            #m_argu s004c If_Prm_Eqn_Rpt(s004c, s004v,)
            #m_argu s220c If_Prm_Eqn_Rpt(s220c, s220v,)
            #m_argu s202c If_Prm_Eqn_Rpt(s202c, s202v,)
            #m_argu s022c If_Prm_Eqn_Rpt(s022c, s022v,)
            #m_argu s121c If_Prm_Eqn_Rpt(s121c, s121v,)
            #m_argu s103c If_Prm_Eqn_Rpt(s103c, s103v,)
            #m_argu s301c If_Prm_Eqn_Rpt(s301c, s301v,)
            TOF_Stephens_lor_gauss(
            etac, etav,
            CeV(s400c,s400v) H4 +
            CeV(s040c,s040v) K4 +
            CeV(s004c,s004v) L4 +
            CeV(s220c,s220v) H2 K2 +
            CeV(s202c,s202v) H2 L2 +
            CeV(s022c,s022v) K2 L2 +
            CeV(s121c,s121v) H K2 L +
            CeV(s103c,s103v) H L3 +
            CeV(s301c,s301v) H3 L
            )
            } `

            In the input file itself, flight_path is defined locally for each bank, is it possible to tell the macro just to take the local flightpath macro? If so, how do I direct it to do this?

            Thanks again all for your continued help here! Hopefully we'll have a set of TOF_Stephens strain macros to share with the TOPAS community soon!

            Huzzah! Ignore the above, I've not gotten it working with the below code. I will email a set of complete TOF_Stephens to John to share asap. Thanks again all!

            macro TOF_Stephens_lor_gauss(etac, etav, mhkl)
            {
            #m_argu etac If_Prm_Eqn_Rpt(etac, etav, min 0 max 1)
            local #m_unique pp_ = (D_spacing2 * Sqrt(Max(mhkl,0))) Tan(ArcSin((1.977 * 0.001) / (flight_path * D_spacing))) 0.0018/3.1415927;
            gauss_fwhm = pp_ (1-CeV(etac, etav));
            lor_fwhm = pp_ CeV(etac, etav);

              }

            macro TOF_Stephens_monoclinic
            (
            etac, etav,
            s400c,s400v,
            s040c,s040v,
            s004c,s004v,
            s220c,s220v,
            s202c,s202v,
            s022c,s022v,
            s121c,s121v,
            s103c,s103v,
            s301c,s301v
            )
            {
            #m_argu s400c If_Prm_Eqn_Rpt(s400c, s400v,)
            #m_argu s040c If_Prm_Eqn_Rpt(s040c, s040v,)
            #m_argu s004c If_Prm_Eqn_Rpt(s004c, s004v,)
            #m_argu s220c If_Prm_Eqn_Rpt(s220c, s220v,)
            #m_argu s202c If_Prm_Eqn_Rpt(s202c, s202v,)
            #m_argu s022c If_Prm_Eqn_Rpt(s022c, s022v,)
            #m_argu s121c If_Prm_Eqn_Rpt(s121c, s121v,)
            #m_argu s103c If_Prm_Eqn_Rpt(s103c, s103v,)
            #m_argu s301c If_Prm_Eqn_Rpt(s301c, s301v,)
            TOF_Stephens_lor_gauss(
            etac, etav,
            CeV(s400c,s400v) H4 +
            CeV(s040c,s040v) K4 +
            CeV(s004c,s004v) L4 +
            CeV(s220c,s220v) H2 K2 +
            CeV(s202c,s202v) H2 L2 +
            CeV(s022c,s022v) K2 L2 +
            CeV(s121c,s121v) H K2 L +
            CeV(s103c,s103v) H L3 +
            CeV(s301c,s301v) H3 L
            )
            }

            Hi again all, I've attached my .inc with the adapted macros and copy-pasteable templates for calling the macros within your .inp. I've only explicitly tested monoclinic, but they're all formatted the same. My one remaining concern is the enormous values that are output. Eta is between 0-1 as per the limit, but as you can see we used much larger limit on the s variables. I'm not sure if this is just the nature of the values involved with TOF (since the raw data is 10's of thousands of micro seconds, as opposed to 10's of 2theta degrees), or if there is possibly still an error. @johnsoevans If these are suitable I'm happy for them to be posted on the topas wiki to share with the community who might find them useful (assuming they are working as intended)!

            Thanks again, any and all advice appreciated 🙂

            tof-stephens-peak-types-template.txt
            1kB
            tof-stephens-peakshapes.txt
            14kB

            P.S. The file upload seems to have converted them to .txts and, whilst they are text files, I'd recommend changing them back to .inp and .inc files respectively.