这是我正在运行的模拟的布局
----main directory
-----my_script.py
-----settings_centroid.py
-----utilities (directory)
-----gizmo_analysis (directory)
----gizmo_analysis.py
----gizmo_diagnostic.py
----gizmo_file.py
----gizmo_ic.py
----gizmo_io.py
----gizmo_star.py
----gizmo_track
----gizmo_yield.py
----__init__.py
----
-----gizmo_read (directory)
-----center.py
-----constant.py
-----coordinate.py
-----read.py
-----__init__.py
我的my_script.py
是:
import gizmo_analysis
import gizmo_read
import utilities as ut
import settings_centroid
settings_centroid.init()
.
.
.
我的settings_centroid.py
脚本是:
import utilities as ut
import gizmo_analysis
import rockstar_analysis
import gizmo_read
def init():
global h, omega_m, omega_l, part, species, properties
species, properties = 'all', 'all'
part=gizmo_read.read.Read.read_snapshot(species, properties, directory='./output/')
.
.
.
我的gizmo_analysis.py
是:
#!/usr/bin/env python3
from __future__ import absolute_import, division, print_function # python 2 compatability
import collections
import numpy as np
from numpy import Inf
import matplotlib
from matplotlib import pyplot as plt
from matplotlib.ticker import AutoMinorLocator
from matplotlib import colors
# local ----
import utilities as ut
import gizmo_analysis
import rockstar_analysis
import settings_centroid
settings_centroid.init()
.
.
.
我的read.py
是:
# system ----
from __future__ import absolute_import, division, print_function # python 2 compatibility
import collections
import glob
import h5py
import numpy as np
from scipy import integrate, interpolate
# local ----
from . import center, constant, coordinate
import settings_centroid
#from .. import settings_centroid
settings_centroid.init()
snapshot_index = settings_centroid.snapshot_number
# store particles as dictionary class
class DictClass(dict):
pass
class ReadClass():
'''
Read Gizmo snapshot.
'''
def __init__(self):
'''
Set properties for snapshot files.
'''
self.snapshot_name_base = 'snap*[!txt]' # avoid accidentally reading snapshot indices file
self.file_extension = '.hdf5'
self.gas_eos = 5 / 3 # gas equation of state
# create ordered dictionary to convert particle species name to its id,
# set all possible species, and set the order in which to read species
self.species_dict = collections.OrderedDict()
# dark-matter species
self.species_dict['dark'] = 1 # dark matter at highest resolution
self.species_dict['dark.2'] = 2 # dark matter at all lower resolutions
# baryon species
self.species_dict['gas'] = 0
self.species_dict['star'] = 4
self.species_all = tuple(self.species_dict.keys())
self.species_read = list(self.species_all)
# use to translate between element name and index in element table
self.element_dict = {}
self.element_dict['total'] = 0
self.element_dict['he'] = 1
self.element_dict['c'] = 2
self.element_dict['n'] = 3
self.element_dict['o'] = 4
self.element_dict['ne'] = 5
self.element_dict['mg'] = 6
self.element_dict['si'] = 7
self.element_dict['s'] = 8
self.element_dict['ca'] = 9
self.element_dict['fe'] = 10
def read_snapshot(
self, species='all', properties='all', directory='.', particle_subsample_factor=None):
'''
Read properties for input particle species from simulation snapshot file[s].
Return particle catalog as a dictionary class.
Parameters
----------
species : string or list : name[s] of particle species:
'all' = all species in file
'star' = stars
'gas' = gas
'dark' = dark matter at highest resolution
'dark.2' = dark matter at lower resolution
properties : string or list : name[s] of particle properties to read - options:
'all' = all species in file
otherwise, list subset from among read_particles.property_dict
for example: ['mass', 'position', 'velocity']
directory : string : directory of snapshot file[s]
particle_subsample_factor : int : factor to periodically subsample particles, to save memory
Returns
-------
part : dictionary class : catalog of particles at snapshot
'''
#snapshot_index = snapshot_index # corresponds to z = 0
# parse input species to read
if species == 'all' or species == ['all'] or not species:
# read all species in snapshot
species = self.species_all
else:
# read subsample of species in snapshot
if np.isscalar(species):
species = [species] # ensure is list
# check if input species names are valid
for spec_name in list(species):
if spec_name not in self.species_dict:
species.remove(spec_name)
print('! not recognize input species = {}'.format(spec_name))
self.species_read = list(species)
# read header from snapshot file
header = self.read_header(snapshot_index, directory)
# read particles from snapshot file[s]
part = self.read_particles(snapshot_index, directory, properties, header)
# assign auxilliary information to particle dictionary class
# store header dictionary
part.info = header
for spec_name in part:
part[spec_name].info = part.info
# get and store cosmological parameters
part.Cosmology = CosmologyClass(
header['omega_lambda'], header['omega_matter'], hubble=header['hubble'])
for spec_name in part:
part[spec_name].Cosmology = part.Cosmology
# store information about snapshot time
time = part.Cosmology.get_time(header['redshift'], 'redshift')
part.snapshot = {
'index': snapshot_index,
'redshift': header['redshift'],
'scalefactor': header['scalefactor'],
'time': time,
'time.lookback': part.Cosmology.get_time(0) - time,
'time.hubble': constant.Gyr_per_sec / part.Cosmology.get_hubble_parameter(0),
}
for spec_name in part:
part[spec_name].snapshot = part.snapshot
# adjust properties for each species
self.adjust_particle_properties(part, header, particle_subsample_factor)
# assign galaxy center position and velocity, principal axes rotation vectors
self.read_galaxy_center_coordinates(part, directory)
# alternately can assign these on the fly
#center.assign_center(part)
#center.assign_principal_axes(part)
# adjust coordinates to be relative to galaxy center position and velocity
# and aligned with principal axes
self.adjust_particle_coordinates(part)
return part
def read_header(self, snapshot_index=snapshot_index, directory='.'):
'''
Read header from snapshot file.
Parameters
----------
snapshot_index : int : index (number) of snapshot file
directory : directory of snapshot
Returns
-------
header : dictionary class : header dictionary
'''
# convert name in snapshot's header dictionary to custom name preference
header_dict = {
# 6-element array of number of particles of each type in file
'NumPart_ThisFile': 'particle.numbers.in.file',
# 6-element array of total number of particles of each type (across all files)
'NumPart_Total': 'particle.numbers.total',
'NumPart_Total_HighWord': 'particle.numbers.total.high.word',
# mass of each particle species, if all particles are same
# (= 0 if they are different, which is usually true)
'MassTable': 'particle.masses',
'Time': 'time', # [Gyr/h]
'BoxSize': 'box.length', # [kpc/h comoving]
'Redshift': 'redshift',
# number of output files per snapshot
'NumFilesPerSnapshot': 'file.number.per.snapshot',
'Omega0': 'omega_matter',
'OmegaLambda': 'omega_lambda',
'HubbleParam': 'hubble',
'Flag_Sfr': 'has.star.formation',
'Flag_Cooling': 'has.cooling',
'Flag_StellarAge': 'has.star.age',
'Flag_Metals': 'has.metals',
'Flag_Feedback': 'has.feedback',
'Flag_DoublePrecision': 'has.double.precision',
'Flag_IC_Info': 'has.ic.info',
# level of compression of snapshot file
'CompactLevel': 'compression.level',
'Compactify_Version': 'compression.version',
'ReadMe': 'compression.readme',
}
header = {} # dictionary to store header information
if directory[-1] != '/':
directory += '/'
file_name = self.get_snapshot_file_name(directory, snapshot_index)
print('reading header from:\n {}'.format(file_name.replace('./', '')))
print()
# open snapshot file
with h5py.File(file_name, 'r') as file_in:
header_in = file_in['Header'].attrs # load header dictionary
for prop_in in header_in:
prop = header_dict[prop_in]
header[prop] = header_in[prop_in] # transfer to custom header dict
# convert header quantities
header['scalefactor'] = float(header['time'])
del(header['time'])
header['box.length/h'] = float(header['box.length'])
header['box.length'] /= header['hubble'] # convert to [kpc comoving]
print('snapshot contains the following number of particles:')
# keep only species that have any particles
read_particle_number = 0
species_read = list(self.species_read)
for species_name in species_read:
if species_name not in self.species_all:
species_read.append(species_name)
for spec_name in species_read:
spec_id = self.species_dict[spec_name]
print(' {:6s} (id = {}): {} particles'.format(
spec_name, spec_id, header['particle.numbers.total'][spec_id]))
if header['particle.numbers.total'][spec_id] > 0:
read_particle_number += header['particle.numbers.total'][spec_id]
elif spec_name in self.species_read:
self.species_read.remove(spec_name)
if read_particle_number <= 0:
raise ValueError('snapshot file[s] contain no particles of species = {}'.format(
self.species_read))
print()
return header
这是gizmo_analysis中的 init .py:
from __future__ import absolute_import # python 2 compatability
from . import gizmo_io as io
from . import gizmo_analysis as analysis
from . import gizmo_ic as ic
from . import gizmo_diagnostic as diagnostic
from . import gizmo_file as file
from . import gizmo_track as track
from . import gizmo_star as star
这是gizmo_read中的 init .py:
#from __future__ import absolute_import # python 2 compatability
from . import read
from . import center
from . import constant
from . import coordinate
#from .. import settings_centroid
但这是运行my_script.py
时收到的错误消息:
Traceback (most recent call last):
File "my_script.py", line 6, in <module>
settings_centroid.init()
File "/usr5/username/settings_centroid.py", line 9, in init
part=gizmo_read.read.Read.read_snapshot(species, properties, directory='./output/')
AttributeError: module 'gizmo_read' has no attribute 'read'
我的理解是,我不知道脚本之间使用 inti .py而不是使用包。我确实确实希望我的主目录下的所有脚本实际上都“看到” settings_centroid.py
。但是,由于某种原因,我认为目前还没有发生这种情况。在实施了Adam,Christian和J_H建议的两种不同的更改之后,我仍然收到错误消息。
答案 0 :(得分:3)
编辑:在更好地理解问题后,我更改了答案。
您的问题来自循环导入(例如,参见this tutorial):您的文件settings_centroid.py
和gizmo_read/read.py
相互包含。
当您导入settings_centroid.py
时,它会导入直接运行reads.py
的{{1}},但是在那时,Python并未加载settings_centroid.init()
内的所有符号,因此找不到settings_centroid.py
。
圆形进口带来棘手的问题需要解决。 我的建议是重构代码以避免它们,如果您的代码库已经很大,则可能需要一些时间。
如果init()
是帮助类的话,一个选项可能对整个代码的逻辑没有意义(如果没有,抱歉,您必须仔细考虑)。制作一个子包并尝试限制其对其他模块的依赖。
如果您确实无法重构,则可以 尝试 将导入限制在功能范围内。
例如,settings_centroid.py
可能变为
settings_centroid.py
但是我很确定您还会遇到其他类似的问题。
希望它会有所帮助:)
答案 1 :(得分:1)
您解释说您的python3程序具有以下代码:
import gizmo_read
...
def init():
...
part=gizmo_read.read.Read.read_snapshot(...)
from __future__ import absolute_import # python 2 compatability
"""
from . import read
"""
,执行该命令将报告符号read
不存在。
是的,听起来不错。
看来您从未将read.py导入该名称空间。
文档字符串就像注释一样-不会执行。
您可以通过将其附加到settings_centroid.py来进行验证:
print('centroid debug')
print('\n'.join(dir(gizmo_read)))
请注意,没有read
符号。
要修复此问题,只需放弃python2 future 行,
并执行import
语句,而不是将其埋入文档字符串中。
答案 2 :(得分:0)
我相信问题出在您的read.py文件中。 settings_centroid的导入语句不正确。应该是:
from .. import settings_centroid
我也不确定
from . import center, constant, coordinate
是有意的,除非没有代码在“ gizmo_read”模块中看不到。尝试解决这些错误,导入应该可以进行。