Commit 9fea0933 authored by BO ZHANG's avatar BO ZHANG 🏀
Browse files

major updates

parent 99a15c89
Pipeline #1423 failed with stage
in 0 seconds
......@@ -2,5 +2,4 @@
omit =
tests/*
setup.py
csst_proto/api.py
test_codestyle.py
install:
pip install .
rm -rf build csst_proto.egg-info
uninstall:
pip uninstall csst_proto -y
......@@ -40,7 +40,7 @@ from astropy.io import fits
# read an L0 image
img = fits.getdata("CSST_MS_SCI_06_L0_img.fits")
# flip the image
img_flipped = flip_image(img=img)
img_flipped = flip_image(image=img)
```
## algorithm description
......
import os
from .flip_image import flip_image, read_default_image
from .demo import demo_function, DemoClass
__version__ = "0.0.1"
PACKAGE_PATH = os.path.dirname(__file__)
__all__ = [
"flip_image",
"read_default_image",
"demo_function",
"DemoClass",
]
"""
Identifier: csst_proto/demo.py
Name: demo.py
Description: 这个文件包括了一个演示函数和演示类
Author: Bo Zhang
Created: 2023-10-26
Modified-History:
2023-10-26, Bo Zhang, add module header
2023-10-28,
"""
import toml
import os
import pathlib
from typing import Optional
# 如何找到当前.py文件所在的文件夹绝对路径?
# 方法1: 使用 pathlib
# HERE: pathlib.Path = pathlib.Path(__file__).parent.resolve()
# 方法2: 使用 os
HERE: str = os.path.dirname(__file__)
# 这个函数演示了如何利用随包数据
# 当config_path被指定时,会读取指定的config_path
# 当config_path=None时,读取随包数据中的config/default_config.toml
def read_config(config_path: Optional[str] = None):
"""Get config info from a toml file.
Read a `toml` format config file.
If `config_path` is specified, read that config.
Otherwise, read the default config in `config/default_config.toml`.
Parameters
----------
config_path : Optional[str]
The config file path.
Returns
-------
dict
The configuration dictionary.
"""
# if config_path is specified, use it, otherwise use the default
if config_path is None:
config_path: str = os.path.join(HERE, "config", "default_config.toml")
# read the config file
config: dict = toml.load(config_path)
return config
A=1
B=2
\ No newline at end of file
def a_demo_function(*args):
"""
Identifier: csst_proto/demo.py
Name: demo.py
Description: 这个文件包括了一个演示函数和演示类
Author: Bo Zhang
Created: 2023-10-26
Modified-History:
2023-10-28, Bo Zhang, add module header
"""
from typing import Any
def demo_function(*args: Any):
"""
A demo function.
This function is a demo.
This function count the input positional arguments and returns the counts.
Parameters
----------
*args : any
The argument list.
*args : Any
The input positional arguments.
Returns
-------
int
The number of input arguments.
The count of input positional arguments.
Examples
--------
>>> a_demo_function(None)
>>> demo_function(None)
"""
return len(args)
class ADemoClass:
class DemoClass:
"""
A demo class.
......@@ -49,9 +62,10 @@ class ADemoClass:
Examples
--------
>>> a = ADemoClass("Jane", "Doe")
>>> a = DemoClass("Jane", "Doe")
>>> a.say_hello()
"""
def __init__(self, first_name, last_name):
self.first_name = first_name
self.last_name = last_name
......
import numpy as np
import joblib
"""
Identifier: csst_proto/flip_image.py
Name: flip_image.py
Description: 这个模块包括了一个图像翻转函数和一个读取随包默认图像的函数
Author: Bo Zhang
Created: 2023-10-26
Modified-History:
2023-10-26, Bo Zhang, add module header
2023-10-28, Bo Zhang, add comments
"""
import multiprocessing
from . import PACKAGE_PATH
import os
import joblib
import numpy as np
import pathlib
# find the absolute path of this file
# use pathlib
# HERE: pathlib.Path = pathlib.Path(__file__).parent.resolve()
# or use os
HERE: str = os.path.dirname(__file__)
# the main algorithm
def flip_image(img: np.ndarray) -> np.ndarray:
# 此函数翻转了输入图像
# 当use_numpy=True时用numpy函数进行翻转
# 当use_numpy=False时用用指标进行翻转
def flip_image(image: np.ndarray, use_numpy: bool = False) -> np.ndarray:
"""
Flip an input image.
......@@ -13,8 +32,10 @@ def flip_image(img: np.ndarray) -> np.ndarray:
Parameters
----------
img : np.ndarray
image : np.ndarray
The input image.
use_numpy : bool
Use numpy.flipud and numpy.fliplr if True, otherwise use indices.
Returns
-------
......@@ -23,22 +44,27 @@ def flip_image(img: np.ndarray) -> np.ndarray:
Examples
--------
>>> flip_image(np.array([1, 2], [3, 4]))
>>> flip_image(np.array([[1, 2], [3, 4]]), use_numpy=False)
array([[4, 3],
[2, 1]])
"""
try:
assert img.ndim == 2
img_flipped = img[::-1, ::-1]
return img_flipped
assert image.ndim == 2
if use_numpy:
image_flipped = np.fliplr(np.flipud(image))
else:
image_flipped = image[::-1, ::-1]
return image_flipped
except AssertionError:
raise AssertionError("The input image is {}D not 2D!".format(img.ndim))
raise AssertionError("The input image is {}D not 2D!".format(image.ndim))
# a demo on how to read test image
def read_test_image():
"""
Read test image.
# 此函数读取了随包数据中的test_image.txt
def read_default_image():
"""Read default image.
This function reads the test image associated with this package.
This function reads the default image associated with this package.
Returns
-------
......@@ -47,22 +73,8 @@ def read_test_image():
Examples
--------
>>> test_image = read_test_image()
>>> test_image = read_default_image()
"""
fp_img = PACKAGE_PATH + "/data/test_image.txt"
fp_img = os.path.join(HERE, "/data/test_image.txt")
print("reading file {} ...".format(fp_img))
return np.loadtxt(fp_img, dtype=int)
def flip_multiple_images_mp(imgs: list, n_jobs: int) -> list:
""" parallel with multiprocessing """
with multiprocessing.Pool(n_jobs) as p:
results = p.map(flip_image, imgs)
return results
def flip_multiple_images_jl(imgs: list, n_jobs: int) -> list:
""" parallel with joblib """
return joblib.Parallel(n_jobs=n_jobs, backend="multiprocessing")(
joblib.delayed(flip_image)(img) for img in imgs
)
"""
Identifier: csst_proto/flip_image_in_parallel.py
Name: flip_image_in_parallel.py
Description: 这个模块包括了基于joblib和multiprocessing的两种并行翻转图像的函数
Author: Bo Zhang
Created: 2023-10-26
Modified-History:
2023-10-26, Bo Zhang, add module header
2023-10-28, Bo Zhang, add comments, separated from flip_image.py
"""
import multiprocessing
import joblib
import numpy as np
from .flip_image import flip_image
def flip_multiple_images_mp(images: list[np.ndarray], n_jobs: int) -> list[np.ndarray]:
"""Flip input images in parallel.
Flip images in parallel with `multiprocessing`.
Parameters
----------
images : list[np.ndarray]
The input image list.
n_jobs : int
The number of processes.
Returns
-------
The flipped image list.
"""
with multiprocessing.Pool(n_jobs) as p:
results = p.map(flip_image, images)
return results
def flip_multiple_images_jl(images: list[np.ndarray], n_jobs: int) -> list[np.ndarray]:
"""Flip input images in parallel.
Flip images in parallel with `joblib`.
Parameters
----------
images : list[np.ndarray]
The input image list.
n_jobs : int
The number of processes.
Returns
-------
The flipped image list.
"""
return joblib.Parallel(n_jobs=n_jobs, backend="multiprocessing")(
joblib.delayed(flip_image)(image) for image in images
)
numpy==1.23.3
scipy==1.9.2
joblib==1.2.0
setuptools==65.5.1
astropy==5.1
pycodestyle==2.9.1
pytest==7.2.1
pytest-cov==4.0.0
coverage==7.2.1
\ No newline at end of file
coverage==7.2.1
toml==0.10.2
\ No newline at end of file
import setuptools
import csst_proto
# 读取README.md作为长描述
with open("README.md", "r") as fh:
long_description = fh.read()
setuptools.setup(
name='csst_proto',
version=csst_proto.__version__,
author='Bo Zhang',
author_email='bozhang@nao.cas.cn',
description='The CSST L1 pipeline - prototype', # short description
long_description=long_description,
long_description_content_type="text/markdown",
url='https://csst-tb.bao.ac.cn/code/csst-l1/csst_proto',
project_urls={
'Source': 'https://csst-tb.bao.ac.cn/code/csst-l1/csst_proto',
},
packages=setuptools.find_packages(),
license='MIT',
classifiers=["Development Status :: 5 - Production/Stable",
"Intended Audience :: Science/Research",
"License :: OSI Approved :: MIT License",
"Operating System :: OS Independent",
"Programming Language :: Python :: 3.9",
"Topic :: Scientific/Engineering :: Physics",
"Topic :: Scientific/Engineering :: Astronomy"],
package_dir={'csst_proto': 'csst_proto'},
# include_package_data=True,
package_data={"": ["LICENSE", "README.md"],
"csst_proto": ["data/test_image.txt",
"data/table_data.csv"
]},
# install_requires=['numpy>1.20.3',
# 'scipy',
# 'matplotlib',
# 'astropy',
# ],
python_requires='>=3.9',
ext_modules=[
name="csst_proto", # 包名
version="0.0.1", # 版本号
author="Bo Zhang", # 作者
author_email="bozhang@nao.cas.cn", # 邮箱
description="The CSST L1 pipeline - prototype", # 短描述
long_description=long_description, # 长描述
long_description_content_type="text/markdown", # 长描述类型
url="https://csst-tb.bao.ac.cn/code/csst-l1/csst_proto", # 主页
packages=setuptools.find_packages(), # 用setuptools工具自动发现带有__init__.py的包
license="MIT", # 证书类型
classifiers=[ # 程序分类, 参考 https://pypi.org/classifiers/
# How mature is this project?
# 3 - Alpha
# 4 - Beta
# 5 - Production/Stable
"Development Status :: 3 - Alpha",
"Intended Audience :: Science/Research",
"License :: OSI Approved :: MIT License",
"Operating System :: OS Independent",
"Programming Language :: Python :: 3.11",
"Topic :: Scientific/Engineering :: Physics",
"Topic :: Scientific/Engineering :: Astronomy",
],
include_package_data=True, # 包含所有随包数据
# 请注意检查,防止临时文件或其他不必要的文件被提交到仓库,否则会一同安装
python_requires=">=3.11", # Python版本要求
ext_modules=[ # 如果有随包的C代码,需要在这里定义扩展
setuptools.Extension(
name="csst_proto.cext.helloworld", sources=["cextern/helloworld.c"]
name="csst_proto.cext.helloworld",
sources=["cextern/helloworld.c"],
)
]
)
\ No newline at end of file
],
)
"""
Identifier: csst_proto/test_demo_function.py
Name: test_demo_function.py
Description: Test demo function.
Author: Bo Zhang
Created: 2023-10-26
Modified-History:
2023-10-26, Bo Zhang, created
2023-10-26, Bo Zhang, add module header
"""
import unittest
from csst_proto.api import a_demo_function
class TestDemoFunction(unittest.TestCase):
def test_demo_function_1(self):
"""
Aim
---
Test demo function.
Criteria
--------
Pass if the demo function returns `1`.
Details
-------
The demo function returns the length of the input argument list.
This case aims to test whether the demo function returns `1` if input is `None`.
"""
# demo function test
self.assertTrue(
a_demo_function(None) == 1,
"Single-argument case failed.",
)
def test_demo_function_2(self):
"""
Aim
---
Test demo function.
Criteria
--------
Pass if the demo function returns `2`.
Details
-------
The demo function returns the length of the input argument list.
This case aims to test whether the demo function returns `2` if input is `None, None`.
"""
# demo function test
self.assertEqual(
a_demo_function(None, None),
2,
"Double-argument case failed.",
)
def test_demo_function_bad_case(self):
"""
Aim
---
Test demo function.
Criteria
--------
Pass if the demo function result is not equal to `2`.
Details
-------
The demo function returns the length of the input argument list.
This case aims to test whether the demo function result is not equal to `2`
if input is `None, None, None`.
"""
# demo function test
self.assertNotEquals(
a_demo_function(None, None, None),
2,
"Triple-argument case failed.",
)
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment