Code Monkey home page Code Monkey logo

pdrtpy's People

Contributors

dependabot[bot] avatar github-actions[bot] avatar markusroellig avatar mpound avatar nanoexplorer avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

pdrtpy's Issues

Measurement.read fails if WCS project has 3 dimensions

reported by Lorenzo Evangelista [email protected]

Dear Mark Pound,

I am Pierre Guillard's PhD student working on JWST H2 maps of the CenA galaxy. We’re contacting you via Emilie Habart.

We are trying to generate a pixel-by-pixel gas excitation map by superposing a set of multiple moment maps, however we have an issue with the Measurement.read function.

It looks like the function doesn’t accept our moment maps because they are generated from sliced-cubes with a WCS having 3 dimensions, while 2 are expected.
We have tried to modify the Header to make it acceptable but all attempts failed.

Is there a way to allow the function to accept 3 dimension headers?

Thank you very much for your help,

Best wishes,

Lorenzo EVANGELISTA

Here attached you’ll find the map which gives the error.
Following you’ll find part of the code and the error.


q = []
nu = []
i=1
for j in intensity:
    infile=f"Moment_maps/Conv_maps/ConvP_S{i}.fits"
    m = Measurement.read(infile,identifier=j).    ######################## Line of error
    q.append(m)
    nu.append(h.upper_colden(m,'cm-2'))
    i+=1
# pick a single scale for all the plots
vmin=q[1].data.min()
vmax=q[1].data.max()

fig,ax = plt.subplots(2,3,subplot_kw={'projection':q[0].wcs},figsize=(9,6))
i = 0
for a in ax:
    for b in a:
        b.imshow(q[i],origin="lower",vmin=vmin,vmax=vmax,cmap='plasma')
        b.set_title(q[i].id)
        i = i+1
plt.rcParams['font.size'] = 8
plt.subplots_adjust(wspace=0.5)


fitted 1 of 1 pixels
got 0 exceptions and 0 bad fits
WARNING: FITSFixedWarning: The WCS transformation has more axes (3) than the image it is associated with (2) [astropy.wcs.wcs]
WARNING: FITSFixedWarning: 'obsfix' made the change 'Set OBSGEO-L to 169.637084 from OBSGEO-[XYZ].
Set OBSGEO-B to 18.461327 from OBSGEO-[XYZ].
Set OBSGEO-H to 1255350594.775 from OBSGEO-[XYZ]'. [astropy.wcs.wcs]
Traceback (most recent call last):

File ~/anaconda3/lib/python3.11/site-packages/pdrtpy/measurement.py:650 in fits_measurement_reader
z=Measurement(z,unit=z._unit,title=_title)

File ~/anaconda3/lib/python3.11/site-packages/pdrtpy/measurement.py:147 in init
self._set_up_for_interp()

File ~/anaconda3/lib/python3.11/site-packages/pdrtpy/measurement.py:338 in _set_up_for_interp
self._world_axis = utils.get_xy_from_wcs(self,quantity=False,linear=False)

File ~/anaconda3/lib/python3.11/site-packages/pdrtpy/pdrutils.py:711 in get_xy_from_wcs
x=w.array_index_to_world_values(xind,xind)[0]

File ~/anaconda3/lib/python3.11/site-packages/astropy/wcs/wcsapi/low_level_api.py:90 in array_index_to_world_values
return self.pixel_to_world_values(*index_arrays[::-1])

File ~/anaconda3/lib/python3.11/site-packages/astropy/wcs/wcsapi/fitswcs.py:336 in pixel_to_world_values
world = self.all_pix2world(*pixel_arrays, 0)

File ~/anaconda3/lib/python3.11/site-packages/astropy/wcs/wcs.py:1570 in all_pix2world
return self._array_converter(self._all_pix2world, "output", *args, **kwargs)

File ~/anaconda3/lib/python3.11/site-packages/astropy/wcs/wcs.py:1562 in _array_converter
raise TypeError(

TypeError: WCS projection has 3 dimensions, so expected 2 (an Nx3 array and the origin argument) or 4 arguments (the position in each dimension, and the origin argument). Instead, 3 arguments were given.

During handling of the above exception, another exception occurred:

Traceback (most recent call last):

File ~/anaconda3/lib/python3.11/site-packages/spyder_kernels/py3compat.py:356 in compat_exec
exec(code, globals, locals)

File ~/Desktop/Work/untitled1.py:108
m = Measurement.read(infile,identifier=j)

File ~/anaconda3/lib/python3.11/site-packages/astropy/nddata/mixins/ndio.py:59 in call
return self.registry.read(self._cls, *args, **kwargs)

File ~/anaconda3/lib/python3.11/site-packages/astropy/io/registry/core.py:218 in read
data = reader(*args, **kwargs)

File ~/anaconda3/lib/python3.11/site-packages/pdrtpy/measurement.py:652 in fits_measurement_reader
raise TypeError('could not convert fits_measurement_reader output to Measurement')

TypeError: could not convert fits_measurement_reader output to Measurement

add crosshair to chisq plot

suggested by Andy Harris, add a crosshair at the minimum chisq value in chisq plots (for single pixel mode).

legend incorrect when adding models

Excerpt from email from Aaron Bryant:

The only remaining issue I see is that, despite setting a title for the new model like ms.add_model("CII_158/CO_1413", ciico1413, title = "[C II] 158 $\mu$m / CO(J=14-13)"), this title is not propagated to plots such as ratios_on_models:

add modetype = temperature

see ModelPlot lines 275++. Add 'temperature' as a modeltype
Also change type="both" to type="any" in the method signature

Add regularization to map solution

In many cases, the conditions can be ill-posed. Meaning small changes in values or errors can lead to large changes in n and/or G0. This can manifest as stripes in the solution map. The fix for this is to implement some kind of regularization term to the cost function (chisq calculation). Probably the best choice for our case is a regularization term based on the spatial derivatives of the observed ratio maps. This may help force n and G0 to be spatially smooth.

add G0 from FIR estimate option

horizontal line perpendicular to G0 axis indicating the estimate from just the FIR data. Ramsey knows how to compute this.

add to() to Measurement

utils.to() is a bit cumbersome to use. adding the functionality to Measurement makes sense.
measurement2 = measurement1.to(unit)
where unit is either astropy Unit or str

allow single temperature fit to H2

h2excitation is fixed to a two temperature model. would be nice to be flexible and allow one temperature (or N temperatures). If lmfit allows arrays as Parameters in models then this could work with the existing modelfunc.

updated ASCL entry

update ASCL.net entry to add pdrtpy.readthedocs.io, remove references to WITS, and add codemeta.json file to this repository.

handling of log labels is klugy

As reported by Nicola, ModelPlot.plot() labels x and y as log(n) log(G0) even when the axes are not log (the default) though the scale is logarithmic. I kluged a fix to this in pdrutils and modeplot.py but it needs a proper fix.

add ne,Ratio, constant temperature plot

For a FITS file that is CTYPE1=n_e, CTYPE_2=T_e, value is line ratio, we would like a plot of n_e on x-axis, ratio on y-axis and lines of constant temperature.

n_e = electron density
T_e = electron temperature

pyplot functions plot to incorrect axes when colorbar = True in functions derived from PlotBase

When doing e.g. lrp.density(colorbar=True) and then calling pyplot functions like lrp._plt.scatter(x,y) to overplot details, these are instead plotted onto the colorbar Axes rather than the image.

This is a result of PlotBase._wcs_colorbar using AxesDivider.append_axes() to generate a colorbar axis. This axis then becomes the active axis when we make any future pyplot calls. The active axis can be reverted to the image axis by using plt.sca(ax)

In PlotBase._plot, this can be achieved by adding the following line to the if statement at line 376, below where _wcs_colorbar is called:

self._plt.sca(self._axis[axidx])

lineratio fit fails if measurements given as dict

As reported by Aaron Dryant

Hi Marc,

using version 2.3.0

if I put measurements into LineRatioFit as a dictionary, with keys as line identifiers, when doing lrf.run() I get an Attribute Error. See below for comparison with measurements as a list, which works fine:

type(meas_list), type(meas_dict)
Out[35]: (list, dict)

lrf_list = LineRatioFit(ms, measurements = meas_list)

lrf_dict = LineRatioFit(ms, measurements = meas_dict)

lrf_list.run()
0%| | 0/8118 [00:00<?, ?it/s]
fitted 6949 of 8118 pixels
got 0 exceptions

lrf_dict.run()
Traceback (most recent call last):

Input In [39] in <cell line: 1>
lrf_dict.run()

File C:\ProgramData\Anaconda3\lib\site-packages\pdrtpy\tool\lineratiofit.py:387 in run
self._reset_masks()

File C:\ProgramData\Anaconda3\lib\site-packages\pdrtpy\tool\lineratiofit.py:417 in _reset_masks
self._measurements[m].mask = deepcopy(self._masks[m])

AttributeError: 'LineRatioFit' object has no attribute '_masks'

lrf_list._masks
Out[40]:
{'OI_63': array([[ True, True, True, ..., True, True, True],
[ True, True, True, ..., True, True, True],
[ True, True, True, ..., True, True, True],
...,
[False, False, False, ..., True, True, True],
[False, False, False, ..., True, True, True],
[False, False, False, ..., True, True, True]]),
'OI_145': array([[ True, True, True, ..., True, True, True],
[ True, True, True, ..., True, True, True],
[ True, True, True, ..., True, True, True],
...,
[False, False, False, ..., True, True, True],
[False, False, False, ..., True, True, True],
[False, False, False, ..., True, True, True]]),
'CII_158': array([[ True, True, True, ..., True, True, True],
[ True, True, True, ..., True, True, True],
[ True, True, True, ..., True, True, True],
...,
[False, False, False, ..., True, True, True],
[False, False, False, ..., True, True, True],
[False, False, False, ..., True, True, True]])}

lrf_dict._masks
Traceback (most recent call last):

Input In [41] in <cell line: 1>
lrf_dict._masks

AttributeError: 'LineRatioFit' object has no attribute '_masks'

I see in line 50 of lineratiofit.py, dict measurements get turned straight into self._measurements, whereas list measurements go to _init_measurements where self gets the _masks attribute. So I think this may be the source of the problem.

thanks,
Aaron

NAXIS not found for added model from Measurement arithmetic

  1. When creating a new ratio that is not supported by default support by the model, as in the following example:

    x = ms.get_model("CI_609")

    y = ms.get_model("CO_43")

    z = y/x

    ms.add_model("CO_43/CI_609",model=z,title="CO(J=4-3)[C I] 609$\mu$m",overwrite=True)

    mylines =["CI_609","CI_370","CO_43"]

    ms.table.show_in_notebook()

    mylines =["CI_609","CI_370","CO_43"]

    check supported combinations of lines and ratios in the selected model

    mods = ms.get_models(mylines,model_type='both')

    mods.keys()

    plotting selected model

    z = ms.get_models(["CI_609","CI_370","CO_43"],model_type="ratio")

    print("Found models: ",z.keys())

    for j in z:

     	pl_name = j
    
     	pl_name = pl_name.replace("/", "_" ) 
    
     	print(pl_name)
    
     	mp.plot(j,legend=False,contours=True,label=True,yaxis_unit="Draine",cmap='rainbow',norm='zscale') # tab20c
    

I get the following error:


Exception Traceback (most recent call last)

Cell In[75], line 13

 11 pl_name = pl_name.replace("/", "_" ) 

 12 print(pl_name)

---> 13 mp.plot(j,legend=False,contours=True,label=True,yaxis_unit="Draine",cmap='rainbow',norm='zscale') # tab20c

 14 plt.savefig('/Users/cassaca-pgarcia/Desktop/'+str(pl_name)+'_latex.pdf', bbox_inches='tight',transparent=False)

File ~/anaconda3/lib/python3.10/site-packages/pdrtpy/plot/modelplot.py:45, in ModelPlot.plot(self, identifier, **kwargs)

 43 kwargs_opts.update(kwargs)

 44 if '/' in identifier:

---> 45 self.ratio(identifier,**kwargs_opts)

 46 else:

 47     self.intensity(identifier,**kwargs_opts)

File ~/anaconda3/lib/python3.10/site-packages/pdrtpy/plot/modelplot.py:76, in ModelPlot.ratio(self, identifier, **kwargs)

 73 if not kwargs_opts['image'] and kwargs_opts['colors'][0] == 'white':

 74     kwargs_opts['colors'][0] = 'black'

---> 76 self._plot_no_wcs(model,**kwargs_opts)

 77 if kwargs_opts['legend']:

 78     lines = list()

File ~/anaconda3/lib/python3.10/site-packages/pdrtpy/plot/modelplot.py:683, in ModelPlot._plot_no_wcs(self, data, header, **kwargs)

678 #if self._tool is not None:

679 #     if self._tool._modelnaxis is None and "NAXIS" not in _header:

680 #         raise Exception("Image header/WCS has no NAXIS keyword")

682 if "NAXIS" not in _header:

--> 683 raise Exception("Image header/WCS has no NAXIS keyword")

684 else:

685     _naxis = _header["NAXIS"]

Exception: Image header/WCS has no NAXIS keyword

ability to add a user-computed model to a ModelSet instance.

Dear Marc,

thank you for the update. I find a lot of improvements. However, I have a new feature request:

The list of intensity and ratio files will never be complete in terms of what the user may want. A simple case that I tried yesterday was pure CII intensities from kt2013. However, this can apply to any ratio or intensity that the user may want to look at, but where no FITS file is there. Numerically, I can easily generate the values or ratios from the existing data. For the kt2013 CII case e.g. by
mods = ms.get_models(["CII_158","OI_145", "FIR"],model_type='both')
cii_field = (mods['FIR'].data)*(mods['OI_145+CII_158/FIR'].data)/((mods['OI_145/CII_158'].data)+1.0)

However, I cannot use the ModelPlot methods to work with this data set. The solution that I think of to implement a ModelSet.register method. This should allow to define new models in the existing ModelSet by defining the dataset in a numerical way, e.g. like above, give it a key and inherit or redefine the other properties from another model in the ModelSet. Then I can even compare the Measurement with those user-defined data when the keys match.

Do you think that this is easily possible? Probably I am overlooking things. There may be another solution, but it would be good to have the full flexibility of the maths combining the FITS files within the ModelSet-ModelPlot combo.

Cheers
Volker

H2 model maps in WK2006 are only 17x17

As reported by @maitraiyee-tiwari :

Hi Marc,

I also tried the _Single_pixel notebook to get the overlay plots using our data. At first I used CO32, CII and OI 63 data to get the overlay plot. This works perfectly fine but when I also use the H2S1 and H2S2 data, I get an error in the p.run() stage. Do you know what mistake am I making here?


ValueError Traceback (most recent call last)
in
----> 1 p.run()

~/anaconda3/lib/python3.8/site-packages/pdrtpy/tool/lineratiofit.py in run(self, mask)
351 # eventually need to check that the maps overlap in real space.
352 self._compute_delta_sq()
--> 353 self._compute_chisq()
354 self.compute_density_radiation_field()
355

~/anaconda3/lib/python3.8/site-packages/pdrtpy/tool/lineratiofit.py in _compute_chisq(self)
538 if self.ratiocount < 2 :
539 raise Exception("Not enough ratios to compute chisq. Need 2, got %d"%self.ratiocount)
--> 540 sumary = sum((self._deltasq[r]._data for r in self._deltasq))
541 self._dof = len(self._deltasq) - 1
542 k = utils.firstkey(self._deltasq)

ValueError: operands could not be broadcast together with shapes (29,25) (17,17)

crosshair on chisq plot is off by one?

the n,G0 values are correct (checked against classic pdrt) but the ax.scatter puts the cross at the bottom left corner of the pixel. both matplotlib and astropy used zero-based pixels (pixel space not wcs) and both claim to use the center of the pixel as the coordinate. Needs more investigation.
chisq

allow custom colorbar label

default colorbar label is header['BUNIT'] in ModelPlot._plot_no_wcs(). add kwarg and make consistent through relevabt plotting tools.

nan's in error map

When computing If some maps have nan's in the observations error plane where other maps do not then one gets funky results in the g0,n maps. Ideally these pixels in the result maps should get set to NaN or if there are enough ratios without it then do the computation and the error will be higher. Either way, a warning should be issued to user.
Example is the NGC1333 data from Els.

add clip to run()

to avoid dividing noise by noise in observed maps and then fitting the result, we want to clip the maps below say 2*rms as determined from the error plane in the Measurement. This can be an argument to run()

construct models.tab on the fly?

Continually modifying models.tab as new models are added may become cumbersome. One idea is to build it on-the-fly based on the file names. Have a master models.tab that contains all possible models and based on filenames in the models directory in question select those rows from the master file.

user-added ModelSet

This should be doable simply by changing the constructor to promote the table name to an initialization parameter.

fix rows and columns.

nrows, ncols is messed up in overlay_ratios and ratios_on_models.
the NX3 and row calculation should be in ratios not overlays

Feature request: asymmetric errors

For a number of observational data we have asymmetric error bars. This cannot be adequately fitted at the moment. Unfortunately, this is not foreseen in the underlying astropy NDUncertainty so that it would require a major code change where basically two NDUncertainty arrays are swept through and separately used in plotting and fitting if both are given.

error in mp.plot concerning meas_color when overlaying >1 measurements

Reported by Aaron Bryant

when using ModelPlot.plot (and by extension mp.intensity or mp.ratio), if specifying more than 1 measurement to overlay in parameter space, then an error arises when specifying colors in meas_color.

For example with 2 overlaid measurements, I specify:
meas_color = ['red', 'orange']

from this when doing the mp.plot, I get:
ValueError: Invalid RGBA argument: 'redred'

This behaviour comes from the "kluge" in ModelPlot._plot_no_wcs at line 850:
colors = kwargs_opts['meas_color'][jj]*mlen

incrementing jj correctly increments through the colors in meas_color, but multiplying by mlen (the kluge for colorcounter), which in this case is 2, would result in:
meas_color = ['red', 'orange']
meas_color[0]*2
Out: 'redred'

Removing the multiplication with mlen fixes this but presumably breaks whatever problem arose with colorcounter.
proof that it works:

Figure 2024-03-06 144928

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.