Skip to content

Add optional raw spec parameter for x13_arima_analysis() - #9550

Merged
ChadFulton merged 5 commits into
statsmodels:mainfrom
ropeladder:x13_raw_spec2
Jun 14, 2025
Merged

Add optional raw spec parameter for x13_arima_analysis()#9550
ChadFulton merged 5 commits into
statsmodels:mainfrom
ropeladder:x13_raw_spec2

Conversation

@ropeladder

Copy link
Copy Markdown
Contributor
  • tests added / passed.
  • code/documentation is well formatted.
  • properly formatted commit message.

This commit adds an option to pass in a raw .spec file to the x13_arima_analysis() function, either as a path or as a string.

We needed a way to use more advanced configuration options for x13, but adding all the specifications to the statsmodels function itself seemed like an exercise in futility. (the manual for x13 is nearly 300 pages) The string substitution is hopefully not too brittle.

Comment thread statsmodels/tsa/x13.py Outdated
Comment thread statsmodels/tsa/x13.py Outdated
Comment thread statsmodels/tsa/x13.py
spec += _make_forecast_options(forecast_periods)
spec += "x11{ save=(d11 d12 d13) }"
spec += "x11{ save=(d11 d12 d13) \n savelog=(fd8 m7 q)}"

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It happens below, but if the user passes a raw spec you should trap that error seperatrly and let them know there is a problem with their spec.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not clear what you mean here. Are you saying it should parse or otherwise validate the raw spec file before sending it to x13? Or that there should be a separate path for spec file errors?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lower in the file there is an exception handelign block that raises if somethign bad happens. You shoudl seperate the cases where statsmodels wrote the spec file from where the user directly passed the spec, so that you can tell the user that something is wrong with their spec.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for clarifying. Rather than adding separate handling logic, I added in an extra warning when the x13 error occurs with a user-provided spec file. The error returned by the existing _check_errors() function does a good job of showing where the errors are line-by-line already, so it didn't seem worth it to add a separate error check.

Comment thread statsmodels/tsa/x13.py
freq : str
Must be givein if ``endog`` does not have date information in its
index. Anything accepted by pandas.DatetimeIndex for the freq value.
rawspec : str or Path

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking at this, why not allow the user to pass additional options beyone what is known. It looks like this can be of type dict[str, Union[dict[str, ??], str]]. This would just add these to the statsmodels generated spec.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That could definitely be useful for adding miscellaneous parameters. Since rawspec expects something that will essentially replace the spec file it might make more sense to add a second parameter called "addspec" or something, to make it clearer that it's not replacing the spec file outright.

@ChadFulton ChadFulton left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks pretty good to me, thanks @ropeladder! I have a few questions / comments.

Comment thread statsmodels/tsa/x13.py Outdated
# if specfile string (or path) is passed
else:

if ((not None) in [diff, exog, start, freq]): # or (not outlier) or trading:

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the intention here is to raise an error if any of those arguments are set, but doesn't this just test if the value True is in that list?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oops! Should work now.

Comment thread statsmodels/tsa/x13.py Outdated

rawspec_text = None

if os.path.exists(rawspec):

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Technically it might be more idiomatic here to do a try/except block like:

try:
    with open(rawspec) as f:
        rawspec_text = f.read()
except FileNotFoundError:
    if "{" in rawspec:
         rawspec_text = rawspec
    else:
         raise ValueError("rawspec argument provided but not valid path"
                                      " or spec string")

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

open() doesn't like super long filenames, so I used except (OSError, FileNotFoundError):.

Comment thread statsmodels/tsa/x13.py
Comment thread statsmodels/tsa/x13.py
# (d11=final seasonally adjusted series)
# (d12=final trend cycle)
# (d13=final irregular component)
if spec_outputs:

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What happens in the case that the user doesn't have any outputs already defined?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added more splicing to deal with other scenarios.

Comment thread statsmodels/tsa/x13.py Outdated
be treated as a valid spec file. Other parameters for the spec file
will be IGNORED.
Series data and required output formats are spliced into spec file
before it is passed to x12/x13.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this probably needs a little more explanation for how the user is expected to set up their spec file. e.g.:

  • You must have a series{} block that does not contain data or file arguments.
  • You must have a save{} block.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added some details.

@ChadFulton

Copy link
Copy Markdown
Member

LGTM. Do you have anything else planned, or are you happy with it now? @bashtage is there anything else you'd like to see here before it is merged?

Thanks again, great addition!

@ropeladder

Copy link
Copy Markdown
Contributor Author

LGTM. Do you have anything else planned, or are you happy with it now? @bashtage is there anything else you'd like to see here before it is merged?

Thanks again, great addition!

That should be it, thanks!

@ChadFulton
ChadFulton merged commit cee5801 into statsmodels:main Jun 14, 2025
@ChadFulton

Copy link
Copy Markdown
Member

Thanks @ropeladder!

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants