dfm / python-fsps

Python bindings to Charlie Conroy's Flexible Stellar Population Synthesis (FSPS) Fortran code
https://python-fsps.readthedocs.io
MIT License
65 stars 38 forks source link

IndexError: list index out of range #152

Closed kh-kr closed 3 years ago

kh-kr commented 3 years ago

Hi,

I have added Gaia DR2 and EDR3 filters by updating the below mentioned files as:

1) $FSPS_DIR/data/filter_lambda_eff.dat 144 5048.62 145 6246.77 146 7740.87 147 5109.71 148 6217.59 149 7769.02 2) $FSPS_DIR/data/FILTER_LIST 144 Gaia2r_Gbp Gaia-DR2 Bp 145 Gaia2r_G Gaia-DR2 G 146 Gaia2r_Grp Gaia-DR2 Rp 147 Gaia3_Gbp Gaia-DR3 Bp 148 Gaia3_G Gaia-DR3 G 149 Gaia3_Grp Gaia-DR3 Rp 3) I do not know what to change in the $FSPS_DIR/data/magsun.dat file so I kept it as it is. 4) Modified the nbands parameter in the $FSPS_DIR/src/sps_vars.f90 routine from 143 to 149.

I then uninstalled fsps and reinstalled it by this command: "FFLAGS="-DBASTI=1 -DMIST=0 -DPADOVA=0 -DMILES=1 -DBASEL=0" python -m pip install fsps==0.4.0rc1 --no-binary fsps"

I successfully imported Gaia filters, but when I was trying to get isochrone files using the code:

sps = fsps.StellarPopulation(zcontinuous=1) sps.params['imf_type'] = 0 # Salpeter IMF sps.params['sfh'] = 1 # Tau model SFH iso = sp.isochrones()

Then getting IndexError as: IndexError Traceback (most recent call last) in 12 sps.params['imf_type'] = 0 # Salpeter IMF 13 sps.params['sfh'] = 1 # Tau model SFH ---> 14 iso = sp.isochrones() 15 16

~/anaconda3/lib/python3.7/site-packages/fsps/fsps.py in isochrones(self, outfile) 863 absfile, 864 comments="#", --> 865 dtype=np.dtype([(n, np.float) for n in header]), 866 ) 867 return cmd_data

~/anaconda3/lib/python3.7/site-packages/numpy/lib/npyio.py in loadtxt(fname, dtype, comments, delimiter, converters, skiprows, usecols, unpack, ndmin, encoding, max_rows, like) 1144 # converting the data 1145 X = None -> 1146 for x in read_data(_loadtxt_chunksize): 1147 if X is None: 1148 X = np.array(x, dtype)

~/anaconda3/lib/python3.7/site-packages/numpy/lib/npyio.py in read_data(chunk_size) 998 999 # Then pack it according to the dtype's nesting -> 1000 items = pack_items(items, packing) 1001 X.append(items) 1002 if len(X) > chunk_size:

~/anaconda3/lib/python3.7/site-packages/numpy/core/_internal.py in call(self, *args, kwargs) 870 self.func = func 871 def call(self, *args, *kwargs): --> 872 return self.func(self, args, kwargs) 873

~/anaconda3/lib/python3.7/site-packages/numpy/lib/npyio.py in pack_items(self, items, packing) 955 ret = [] 956 for length, subpacking in packing: --> 957 ret.append(self(items[start:start+length], subpacking)) 958 start += length 959 return tuple(ret)

~/anaconda3/lib/python3.7/site-packages/numpy/core/_internal.py in call(self, *args, kwargs) 870 self.func = func 871 def call(self, *args, *kwargs): --> 872 return self.func(self, args, kwargs) 873

~/anaconda3/lib/python3.7/site-packages/numpy/lib/npyio.py in pack_items(self, items, packing) 946 """Pack items into nested lists based on re-packing info.""" 947 if packing is None: --> 948 return items[0] 949 elif packing is tuple: 950 return tuple(items)

IndexError: list index out of range

I am completely new to fsps, so I don't know how to deal with this. Can anyone help me, please?

bd-j commented 3 years ago

Hi, did you add the transmission curves to data/allfilters.dat, in the same order as the are added to FILTER_LIST?

kh-kr commented 3 years ago

Yes, I did.

bd-j commented 3 years ago

It looks like you are calling sp.isochrones() while StellarPopulation object is called sps. Do you have multiple StellarPopulation instances running?

Also, I note that the 'sfh' parameter is irrelevant for the output of StellarPopulation.isochrones. The isochrone data is always given for SSPs of one solar mass formed at each age, and is only affected by parameters listed in StellarPopulation.params.ssp_params

Otherwise, I'm not sure what the issue is. My guess is that the FSPS write_isochrones is somehow not matching the same number of columns in the file it writes to as the number of bands that it thinks exist. You could try stepping through some of the code in the isochrones method that is raising the error, https://github.com/dfm/python-fsps/blob/main/src/fsps/fsps.py#L823

So, something like the following to check the lengths of various arrays

import fsps
import os
import numpy as np

outfile = "pyfsps_tmp"
absfile = os.path.join(os.environ["SPS_HOME"], "OUTPUTS", outfile + ".cmd")

sp = fsps.StellarPopulation()
sp.params["imf_type"] = 0
sp._compute_csp()
fsps._fsps.driver.write_isoc(outfile)

with open(absfile, "r") as f:
        # drop the comment hash and mags field
        header = f.readline().split()[1:-1]
        line1 = f.readline()
fnames = fsps.list_filters()

print(absfile)
print(len(header), len(fnames), len(line1.split())
dtype=np.dtype([(n, np.float) for n in header+fnames])
cmd_data = np.loadtxt(absfile, comments="#", dtype=dtype)
kh-kr commented 3 years ago

Hi,

I tried running the above code. And the output is:

_/home/khushboo_astro/python-fsps/src/fsps/libfsps/OUTPUTS/pyfspstmp.cmd 11 149 154

This line suggests that I have 149 filters (143 are the default ones, and I added 6 more Gaia-DR2 and Gaia-EDR3 filters) in the FILTER_LIST but getting the magnitudes for 143 filters only. That is why it is again raising the index error.

_IndexError Traceback (most recent call last)

in 16 print(len(header), len(fnames), len(line1.split())) 17 dtype=np.dtype([(n, np.float) for n in header+fnames]) ---> 18 cmd_data = np.loadtxt(absfile, comments="#", dtype=dtype) ~/anaconda3/lib/python3.7/site-packages/numpy/lib/npyio.py in loadtxt(fname, dtype, comments, delimiter, converters, skiprows, usecols, unpack, ndmin, encoding, max_rows, like) 1144 # converting the data 1145 X = None -> 1146 for x in read_data(_loadtxt_chunksize): 1147 if X is None: 1148 X = np.array(x, dtype) ~/anaconda3/lib/python3.7/site-packages/numpy/lib/npyio.py in read_data(chunk_size) 998 999 # Then pack it according to the dtype's nesting -> 1000 items = pack_items(items, packing) 1001 X.append(items) 1002 if len(X) > chunk_size: ~/anaconda3/lib/python3.7/site-packages/numpy/core/_internal.py in __call__(self, *args, **kwargs) 870 self.func = func 871 def __call__(self, *args, **kwargs): --> 872 return self.func(self, *args, **kwargs) 873 ~/anaconda3/lib/python3.7/site-packages/numpy/lib/npyio.py in pack_items(self, items, packing) 955 ret = [] 956 for length, subpacking in packing: --> 957 ret.append(self(items[start:start+length], subpacking)) 958 start += length 959 return tuple(ret) ~/anaconda3/lib/python3.7/site-packages/numpy/core/_internal.py in __call__(self, *args, **kwargs) 870 self.func = func 871 def __call__(self, *args, **kwargs): --> 872 return self.func(self, *args, **kwargs) 873 ~/anaconda3/lib/python3.7/site-packages/numpy/lib/npyio.py in pack_items(self, items, packing) 946 """Pack items into nested lists based on re-packing info.""" 947 if packing is None: --> 948 return items[0] 949 elif packing is tuple: 950 return tuple(items) IndexError: list index out of range_
bd-j commented 3 years ago

so I think maybe the issue is that the changes to the FSPS fortran are not being incorporated when you pip install. Try modifying nbands in python-fsps/src/fsps/libfsps/src/sps_vars.f90 instead of $FSPS_DIR/src. (the data files, e.g. allfilters.dat are read from $SPS_HOME)

Also I'm not sure but this change may be overwritten or cause issues when updating python-fsps in the future. A more robust solution would be to make a PR in the fsps repository that adds these filters.

kh-kr commented 3 years ago

Thanks, @bd-j !!! I already changed the value of nbands from 143 to 149 in python-fsps/src/fsps/libfsps/src/sps_vars.f90.

And I do not know how to make a PR. So could you please help me with this?

dfm commented 3 years ago

One comment: I'm only approximately following this, but the command that you're using to install

FFLAGS="-DBASTI=1 -DMIST=0 -DPADOVA=0 -DMILES=1 -DBASEL=0" python -m pip install fsps==0.4.0rc1 --no-binary fsps

Will install an older version of this library and the Fortran dependencies. If you need updates on the Fortran side, it's probably better to install using the GitHub version:

git clone --recursive https://github.com/dfm/python-fsps
cd python-fsps
FFLAGS="-DBASTI=1 -DMIST=0 -DPADOVA=0 -DMILES=1 -DBASEL=0" python -m pip install .

Apologies if this is what you're already doing.

kh-kr commented 3 years ago

It worked. Thank you very much, @bd-j and @dfm.

kh-kr commented 3 years ago

I am closing this issue now. Thanks!!!