spacetelescope / webbpsf

James Webb Space Telescope PSF simulation tool
https://webbpsf.readthedocs.io
BSD 3-Clause "New" or "Revised" License
119 stars 63 forks source link

Expression has forbidden control characters #919

Closed strampelligiovanni closed 1 month ago

strampelligiovanni commented 1 month ago

I'm following the basic usage example as shown here: https://webbpsf.readthedocs.io/en/latest/usage.html

import matplotlib, matplotlib.pyplot as plt
import webbpsf
nrc = webbpsf.NIRCam()
nrc.filter =  'F200W'
psf = nrc.calc_psf(oversample=4)

but at the nrc.calc_psf I get this error:

---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
Cell In[3], line 5
      3 nrc = webbpsf.NIRCam()
      4 nrc.filter =  'F200W'
----> 5 psf = nrc.calc_psf(oversample=4)

File /opt/miniconda3/envs/spaceklip/lib/python3.11/site-packages/webbpsf/webbpsf_core.py:1213, in JWInstrument.calc_psf(self, outfile, source, nlambda, monochromatic, fov_arcsec, fov_pixels, oversample, detector_oversample, fft_oversample, overwrite, display, save_intermediates, return_intermediates, normalize, add_distortion, crop_psf)
   1210         self.pupil.update_opd()
   1212 # Run poppy calc_psf
-> 1213 psf = SpaceTelescopeInstrument.calc_psf(
   1214     self,
   1215     outfile=outfile,
   1216     source=source,
   1217     nlambda=nlambda,
   1218     monochromatic=monochromatic,
   1219     fov_arcsec=fov_arcsec,
   1220     fov_pixels=fov_pixels,
   1221     oversample=oversample,
   1222     detector_oversample=detector_oversample,
   1223     fft_oversample=fft_oversample,
   1224     overwrite=overwrite,
   1225     display=display,
   1226     save_intermediates=save_intermediates,
   1227     return_intermediates=return_intermediates,
   1228     normalize=normalize,
   1229 )
   1231 return psf

File /opt/miniconda3/envs/spaceklip/lib/python3.11/site-packages/poppy/instrument.py:265, in Instrument.calc_psf(self, outfile, source, nlambda, monochromatic, fov_arcsec, fov_pixels, oversample, detector_oversample, fft_oversample, overwrite, display, save_intermediates, return_intermediates, normalize)
    263 self._check_for_aliasing(wavelens)
    264 # and use it to compute the PSF (the real work happens here, in code in poppy.py)
--> 265 result = self.optsys.calc_psf(wavelens, weights, display_intermediates=display, display=display,
    266                               save_intermediates=save_intermediates, return_intermediates=return_intermediates,
    267                               normalize=normalize)
    269 if return_intermediates:  # this implies we got handed back a tuple, so split it apart
    270     result, intermediates = result

File /opt/miniconda3/envs/spaceklip/lib/python3.11/site-packages/poppy/utils.py:1436, in BackCompatibleQuantityInput.__call__.<locals>.unit_check_wrapper(*func_args, **func_kwargs)
   1432 # Call the original function with any equivalencies in force.
   1433 with add_enabled_equivalencies(self.equivalencies):
   1434     # print("Args:   {}".format(bound_args.args))
   1435     # print("KWArgs: {}".format(bound_args.kwargs))
-> 1436     return wrapped_function(*bound_args.args, **bound_args.kwargs)

File /opt/miniconda3/envs/spaceklip/lib/python3.11/site-packages/poppy/poppy_core.py:1714, in BaseOpticalSystem.calc_psf(self, wavelength, weight, save_intermediates, save_intermediates_what, display, return_intermediates, return_final, source, normalize, display_intermediates, inwave)
   1712     plt.clf()
   1713 for wlen, wave_weight in zip(wavelength, normwts):
-> 1714     mono_psf, mono_intermediate_wfs = self.propagate_mono(
   1715         wlen,
   1716         retain_intermediates=retain_intermediates,
   1717         retain_final=return_final,
   1718         display_intermediates=display_intermediates,
   1719         normalize=normalize,
   1720         inwave=inwave
   1721     )
   1723     if outfits is None:
   1724         # for the first wavelength processed, set up the arrays where we accumulate the output
   1725         outfits = mono_psf

File /opt/miniconda3/envs/spaceklip/lib/python3.11/site-packages/poppy/utils.py:1436, in BackCompatibleQuantityInput.__call__.<locals>.unit_check_wrapper(*func_args, **func_kwargs)
   1432 # Call the original function with any equivalencies in force.
   1433 with add_enabled_equivalencies(self.equivalencies):
   1434     # print("Args:   {}".format(bound_args.args))
   1435     # print("KWArgs: {}".format(bound_args.kwargs))
-> 1436     return wrapped_function(*bound_args.args, **bound_args.kwargs)

File /opt/miniconda3/envs/spaceklip/lib/python3.11/site-packages/poppy/poppy_core.py:1852, in BaseOpticalSystem.propagate_mono(self, wavelength, normalize, retain_intermediates, retain_final, display_intermediates, inwave)
   1850     wavefront, intermediate_wfs = self.propagate(wavefront, **kwargs)
   1851 else:
-> 1852     wavefront = self.propagate(wavefront, **kwargs)
   1853     intermediate_wfs = []
   1855 if (not retain_intermediates) & retain_final:  # return the full complex wavefront of the last plane.

File /opt/miniconda3/envs/spaceklip/lib/python3.11/site-packages/poppy/poppy_core.py:2200, in OpticalSystem.propagate(self, wavefront, normalize, return_intermediates, display_intermediates)
   2198 # The actual propagation:
   2199 wavefront.propagate_to(optic)
-> 2200 wavefront *= optic
   2202 # Normalize if appropriate:
   2203 if normalize.lower() == 'first' and wavefront.current_plane_index == 1:  # set entrance plane to 1.

File /opt/miniconda3/envs/spaceklip/lib/python3.11/site-packages/poppy/poppy_core.py:177, in BaseWavefront.__imul__(self, optic)
    174     self.location = 'at ' + optic.name
    175     return self
--> 177 phasor = optic.get_phasor(self)
    179 if not np.isscalar(phasor) and phasor.size > 1:
    180     assert self.wavefront.shape == phasor.shape, "Phasor shape {} does not match wavefront shape {}".format(
    181         phasor.shape, self.wavefront.shape)

File /opt/miniconda3/envs/spaceklip/lib/python3.11/site-packages/poppy/poppy_core.py:2553, in OpticalElement.get_phasor(self, wave)
   2551     trans = self.get_transmission(wave)
   2552     opd = self.get_opd(wave)
-> 2553     self.phasor = ne.evaluate("trans * exp(1.j * opd * scale)")
   2554 else:
   2555     self.phasor = self.get_transmission(wave) * xp.exp(1.j * self.get_opd(wave) * scale)

File /opt/miniconda3/envs/spaceklip/lib/python3.11/site-packages/numexpr/necompiler.py:975, in evaluate(ex, local_dict, global_dict, out, order, casting, sanitize, _frame_depth, **kwargs)
    973     return re_evaluate(local_dict=local_dict, _frame_depth=_frame_depth)
    974 else:
--> 975     raise e

File /opt/miniconda3/envs/spaceklip/lib/python3.11/site-packages/numexpr/necompiler.py:872, in validate(ex, local_dict, global_dict, out, order, casting, _frame_depth, sanitize, **kwargs)
    870 expr_key = (ex, tuple(sorted(context.items())))
    871 if expr_key not in _names_cache:
--> 872     _names_cache[expr_key] = getExprNames(ex, context, sanitize=sanitize)
    873 names, ex_uses_vml = _names_cache[expr_key]
    874 arguments = getArguments(names, local_dict, global_dict, _frame_depth=_frame_depth)

File /opt/miniconda3/envs/spaceklip/lib/python3.11/site-packages/numexpr/necompiler.py:721, in getExprNames(text, context, sanitize)
    720 def getExprNames(text, context, sanitize: bool=True):
--> 721     ex = stringToExpression(text, {}, context, sanitize)
    722     ast = expressionToAST(ex)
    723     input_order = getInputOrder(ast, None)

File /opt/miniconda3/envs/spaceklip/lib/python3.11/site-packages/numexpr/necompiler.py:281, in stringToExpression(s, types, context, sanitize)
    279     no_whitespace = re.sub(r'\s+', '', s)
    280     if _blacklist_re.search(no_whitespace) is not None:
--> 281         raise ValueError(f'Expression {s} has forbidden control characters.')
    283 old_ctx = expressions._context.get_current_context()
    284 try:

ValueError: Expression trans * exp(1.j * opd * scale) has forbidden control characters.

any idea what may cause it?