cioseq


Namecioseq JSON
Version 0.5.1 PyPI version JSON
download
home_pagehttps://github.com/ConductorTechnologies/cioseq
SummaryManage sequences of frame numbers.
upload_time2023-11-01 23:00:23
maintainer
docs_urlNone
authorconductor
requires_python
license
keywords
VCS
bugtrack_url
requirements setuptools wheel twine skulk
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # sequence
Manage sequences of frame numbers

## Install

```bash
pip install cioseq
```

## Usage

Import
```
>>> from cioseq.sequence import Sequence
```

Several ways to create a Sequence using the `create()` factory method.
```
# [start [end [step]]] - Unlike range(), end is inclusive.

>>> s = Sequence.create("1")

>>> s = Sequence.create(1,10,2)

# list
>>> s = Sequence.create([5,6,7,10,12])

# spec
>>> s = Sequence.create("1-10x2")

# compound spec with negative frame numbers
>>> s = Sequence.create("0-10x3, 100, -10--2x2")

# From files on disk
>>> s = Sequence.create(prefix="/path/to/images/image.", extension=".exr")

NOTE: You must provide both prefix and extension, even if they are empty strings

# Copy constructor
>>> s2 = Sequence.create(s)
>>> s2 == s
False
>>> list(s2) == list(s)
True

>>> list(s)
[-10, -8, -6, -4, -2, 0, 3, 6, 9, 100]

>>> print(s)
-10-0x2,3-9x3,100

>>> repr(s)
"Sequence.create('-10-0x2,3-9x3,100')"
```

Indexing
```
>>> s[-1]
100

s[0]
-10
```

An arithmetic progression is a set of numbers with a common step.
```
>>> s = Sequence.create([1,4,7,10,13])
>>> type(s)
<class 'cioseq.sequence.Progression'>

>>> s=Sequence.create([1,2,3,5,78])
>>> type(s)
<class 'cioseq.sequence.Sequence'>
>>> s.is_progression()
False

```

Chunks
```
# Split into chunks, which are themselves Sequences.
>>> s = Sequence.create("1-20", chunk_size=5)
>>> s.chunk_count()
4
>>> s.chunks()
[Sequence.create('1-5'), Sequence.create('6-10'), Sequence.create('11-15'), Sequence.create('16-20')]

# Chunks can be cyclic.
>>> s.chunk_strategy = "cycle"
>>> for c in s.chunks():
...    print(list(c))

[1, 5, 9, 13, 17]
[2, 6, 10, 14, 18]
[3, 7, 11, 15, 19]
[4, 8, 12, 16, 20]

# Set a maximum number of chunks. If the current chunk size is too small, it will be increased.

>>> s = Sequence.create("1-100")
>>> s.chunk_size = 10
>>> s.cap_chunk_count(3)
>>> s.chunk_count()
3
>>> s.chunk_size
34
```


Booleans
```
>>> s = Sequence.create("1-10")
>>> isect = s.intersection(range(5, 15))
>>> print(isect)
5-10


>>> s = Sequence.create("1-10")
>>> uni = s.union(range(5, 15))
>>> print(uni)
1-14

```

Intersecting chunks. Helps to determine which tasks contain scout frames.

```
>>> s = Sequence.create("1-50", chunk_size=5)
>>> scout =  Sequence.create("1,2,7")
>>> chunks = s.intersecting_chunks(scout)
>>> print(chunks)
[Sequence.create('1-5'), Sequence.create('6-10')]
```

Multi sequence filename permutations

```
# single sequence
>>> template = "/path/%(frame)d/image.%(frame)04d.tif"
>>> filenames = list(Sequence.permutations(template, frame="0-6x2"))
>>> print(filenames)
['/path/0/image.0000.tif', '/path/2/image.0002.tif', '/path/4/image.0004.tif', '/path/6/image.0006.tif']

# several sequences
>>> template = "image_%(uval)02d_%(vval)02d.%(frame)04d.tif"
>>> kw = {"uval": "1-2", "vval": "1-2", "frame": "10-11"}
>>> filenames = Sequence.permutations(template, **kw)

>>> print(filenames)
<generator object permutations at 0x10260f960>

>>> for f in filenames:
...    print f

image_01_01.0010.tif
image_01_02.0010.tif
image_02_01.0010.tif
image_02_02.0010.tif
image_01_01.0011.tif
image_01_02.0011.tif
image_02_01.0011.tif
image_02_02.0011.tif
```

Offset
```
>>> s = Sequence.create("1-10")
>>> s = s.offset(-5)
>>> print(s)
-4-5
```

Hash (#) filename expansion

```
>>> s = Sequence.create("8-10")
s.expand("image.#.exr")
['image.8.exr', 'image.9.exr', 'image.10.exr']

s.expand("/some/dir_###/img.#####.exr")
['/some/dir_008/img.00008.exr', '/some/dir_009/img.00009.exr', '/some/dir_010/img.00010.exr']
```

Dollar(n)F filename expansion

```
>>> s = Sequence.create("1")
>>> s.expand_dollar_f("image.$F.exr")
['image.1.exr']

>>> s.expand_dollar_f("image.$F.$5F.$2F.exr")
['image.1.00001.01.exr']

```

Use different symbols for frame spec
```
>>> s = Sequence.create("1-10, 14, 20-48x4")
>>> print(s)
1-10,14,20-48x4

>>> print(s.to(":", "%", ";"))
1:10;14;20:48%4

>>> print(s.to("to", "by", " "))
1to10 14 20to48by4

```

Reformat with no step separator
```
>>> s = Sequence.create("1-10x2,22-25")
>>> print(s.to("-", "", ","))
1,3,5,7,9,22-25
```


Take a subsample of frames
```
s = Sequence.create("1-10")
>>> print(s.subsample(1))
6

>>> print(s.subsample(2))
3-8x5

>>> print(s.subsample(3))
2-6x4,9

>>> print(s.subsample(5))
2-10x2

>>> print(list(s.subsample(4)))
[2, 4, 7, 9]
```

## Test

From git repo
```
python -m unittest discover -v -s ./tests  -p 'test_*.py'
```

## Contributing


Clone the repo.

```
git clone git@github.com:ConductorTechnologies/cioseq.git
cd cioseq
```

Set up a clean virtual envirionment with Python 2.7 for development (optional).

```
python -m virtualenv venv
. ./venv/bin/activate
```

Install development dependencies
```
pip install -r requirements_dev.txt
```

pip install --upgrade . 

```

## Changelog

## Version:0.5.1 -- 01 Nov 2023

Adds a method, cap_chunk_count(), to limit the number of chunks. Chunk size is adjusted accordingly.

## Version:0.4.1 -- 28 Aug 2023

* Adds a boolean difference method to the Sequence class.

## Version:0.4.0 -- 26 Aug 2023

* adds the abilliity to build a sequence from files on disk

## Version:0.3.0 -- 10 Jul 2023

* the `to()` function now handles an empty string for step separator, which enables frame spec strings compatible with Katana's command-line.

### Version:0.2.2 -- 25 May 2023

* Simple edit to remove circle test release. [b92a2c9]


### Version:0.2.0 -- 25 May 2023

* Implemented a feature to calculate first, middle, and last frames.

### Version:0.1.16 -- 24 May 2023

* Added tests for step and irregular sequences. [742d4c4]

### Version:0.1.15 -- 07 Aug 2021

* Use range without importing builtins. [f148290]

### Version:0.1.14 -- 27 Jun 2021

* Removed builtins module to avoid py2/3 errors. [f148290]

### Version:0.1.13 -- 26 Mar 2021

* CICD tweaks and readme. [b9d05ac]

### Version:0.1.12 -- 11 Mar 2021

* Universal flag. [958ef56]
* Adds pip-dependency-file key. [719ec31]

### Version:0.1.10 -- 10 Mar 2021

* Adds ssh key so we can push the tag in circleci. [60360af]
* Use skulk context. [3459bc0]

### Version:0.1.9 -- 09 Mar 2021

* Fixed wrong pypi registry. [a3d82e1]

### Version:0.1.6 -- 09 Mar 2021

* Adds release flow to circleci. [71bbca2]
* Add .circleci/config.yml. [30fd9d9]
* Adds tox for py 2.7 and 3.8. [7ce0970]

### Version:0.1.5 -- 21 Sep 2020

* Bad test name and $f4 token support. [f3c1923]

### Version:0.1.3 -- 20 Sep 2020

* Added several examples to the README and implemented and indexing. [fdec3b4]
 
### Version:0.1.2 -- 19 Sep 2020

* Python 2 and 3 compatibility. [4aba985]

### Version:0.1.1 -- 19 Sep 2020

* Transfer from core. As such, this is the first changelog entry. [54f9132]
* Sequence consumers must use factory. [a9fd08a]
* Adds cycle_progressions chunk strategy. [37075c9]
* Expander path list enhancements (#5)
* Lib enhancements (#4)
* adds sequence intersection check
* allows uppercase characters in angle-bracket template.. [255f61f]
* Initial commit. [7cf8fd3]


--

            

Raw data

            {
    "_id": null,
    "home_page": "https://github.com/ConductorTechnologies/cioseq",
    "name": "cioseq",
    "maintainer": "",
    "docs_url": null,
    "requires_python": "",
    "maintainer_email": "",
    "keywords": "",
    "author": "conductor",
    "author_email": "info@conductortech.com",
    "download_url": "",
    "platform": null,
    "description": "# sequence\nManage sequences of frame numbers\n\n## Install\n\n```bash\npip install cioseq\n```\n\n## Usage\n\nImport\n```\n>>> from cioseq.sequence import Sequence\n```\n\nSeveral ways to create a Sequence using the `create()` factory method.\n```\n# [start [end [step]]] - Unlike range(), end is inclusive.\n\n>>> s = Sequence.create(\"1\")\n\n>>> s = Sequence.create(1,10,2)\n\n# list\n>>> s = Sequence.create([5,6,7,10,12])\n\n# spec\n>>> s = Sequence.create(\"1-10x2\")\n\n# compound spec with negative frame numbers\n>>> s = Sequence.create(\"0-10x3, 100, -10--2x2\")\n\n# From files on disk\n>>> s = Sequence.create(prefix=\"/path/to/images/image.\", extension=\".exr\")\n\nNOTE: You must provide both prefix and extension, even if they are empty strings\n\n# Copy constructor\n>>> s2 = Sequence.create(s)\n>>> s2 == s\nFalse\n>>> list(s2) == list(s)\nTrue\n\n>>> list(s)\n[-10, -8, -6, -4, -2, 0, 3, 6, 9, 100]\n\n>>> print(s)\n-10-0x2,3-9x3,100\n\n>>> repr(s)\n\"Sequence.create('-10-0x2,3-9x3,100')\"\n```\n\nIndexing\n```\n>>> s[-1]\n100\n\ns[0]\n-10\n```\n\nAn arithmetic progression is a set of numbers with a common step.\n```\n>>> s = Sequence.create([1,4,7,10,13])\n>>> type(s)\n<class 'cioseq.sequence.Progression'>\n\n>>> s=Sequence.create([1,2,3,5,78])\n>>> type(s)\n<class 'cioseq.sequence.Sequence'>\n>>> s.is_progression()\nFalse\n\n```\n\nChunks\n```\n# Split into chunks, which are themselves Sequences.\n>>> s = Sequence.create(\"1-20\", chunk_size=5)\n>>> s.chunk_count()\n4\n>>> s.chunks()\n[Sequence.create('1-5'), Sequence.create('6-10'), Sequence.create('11-15'), Sequence.create('16-20')]\n\n# Chunks can be cyclic.\n>>> s.chunk_strategy = \"cycle\"\n>>> for c in s.chunks():\n...    print(list(c))\n\n[1, 5, 9, 13, 17]\n[2, 6, 10, 14, 18]\n[3, 7, 11, 15, 19]\n[4, 8, 12, 16, 20]\n\n# Set a maximum number of chunks. If the current chunk size is too small, it will be increased.\n\n>>> s = Sequence.create(\"1-100\")\n>>> s.chunk_size = 10\n>>> s.cap_chunk_count(3)\n>>> s.chunk_count()\n3\n>>> s.chunk_size\n34\n```\n\n\nBooleans\n```\n>>> s = Sequence.create(\"1-10\")\n>>> isect = s.intersection(range(5, 15))\n>>> print(isect)\n5-10\n\n\n>>> s = Sequence.create(\"1-10\")\n>>> uni = s.union(range(5, 15))\n>>> print(uni)\n1-14\n\n```\n\nIntersecting chunks. Helps to determine which tasks contain scout frames.\n\n```\n>>> s = Sequence.create(\"1-50\", chunk_size=5)\n>>> scout =  Sequence.create(\"1,2,7\")\n>>> chunks = s.intersecting_chunks(scout)\n>>> print(chunks)\n[Sequence.create('1-5'), Sequence.create('6-10')]\n```\n\nMulti sequence filename permutations\n\n```\n# single sequence\n>>> template = \"/path/%(frame)d/image.%(frame)04d.tif\"\n>>> filenames = list(Sequence.permutations(template, frame=\"0-6x2\"))\n>>> print(filenames)\n['/path/0/image.0000.tif', '/path/2/image.0002.tif', '/path/4/image.0004.tif', '/path/6/image.0006.tif']\n\n# several sequences\n>>> template = \"image_%(uval)02d_%(vval)02d.%(frame)04d.tif\"\n>>> kw = {\"uval\": \"1-2\", \"vval\": \"1-2\", \"frame\": \"10-11\"}\n>>> filenames = Sequence.permutations(template, **kw)\n\n>>> print(filenames)\n<generator object permutations at 0x10260f960>\n\n>>> for f in filenames:\n...    print f\n\nimage_01_01.0010.tif\nimage_01_02.0010.tif\nimage_02_01.0010.tif\nimage_02_02.0010.tif\nimage_01_01.0011.tif\nimage_01_02.0011.tif\nimage_02_01.0011.tif\nimage_02_02.0011.tif\n```\n\nOffset\n```\n>>> s = Sequence.create(\"1-10\")\n>>> s = s.offset(-5)\n>>> print(s)\n-4-5\n```\n\nHash (#) filename expansion\n\n```\n>>> s = Sequence.create(\"8-10\")\ns.expand(\"image.#.exr\")\n['image.8.exr', 'image.9.exr', 'image.10.exr']\n\ns.expand(\"/some/dir_###/img.#####.exr\")\n['/some/dir_008/img.00008.exr', '/some/dir_009/img.00009.exr', '/some/dir_010/img.00010.exr']\n```\n\nDollar(n)F filename expansion\n\n```\n>>> s = Sequence.create(\"1\")\n>>> s.expand_dollar_f(\"image.$F.exr\")\n['image.1.exr']\n\n>>> s.expand_dollar_f(\"image.$F.$5F.$2F.exr\")\n['image.1.00001.01.exr']\n\n```\n\nUse different symbols for frame spec\n```\n>>> s = Sequence.create(\"1-10, 14, 20-48x4\")\n>>> print(s)\n1-10,14,20-48x4\n\n>>> print(s.to(\":\", \"%\", \";\"))\n1:10;14;20:48%4\n\n>>> print(s.to(\"to\", \"by\", \" \"))\n1to10 14 20to48by4\n\n```\n\nReformat with no step separator\n```\n>>> s = Sequence.create(\"1-10x2,22-25\")\n>>> print(s.to(\"-\", \"\", \",\"))\n1,3,5,7,9,22-25\n```\n\n\nTake a subsample of frames\n```\ns = Sequence.create(\"1-10\")\n>>> print(s.subsample(1))\n6\n\n>>> print(s.subsample(2))\n3-8x5\n\n>>> print(s.subsample(3))\n2-6x4,9\n\n>>> print(s.subsample(5))\n2-10x2\n\n>>> print(list(s.subsample(4)))\n[2, 4, 7, 9]\n```\n\n## Test\n\nFrom git repo\n```\npython -m unittest discover -v -s ./tests  -p 'test_*.py'\n```\n\n## Contributing\n\n\nClone the repo.\n\n```\ngit clone git@github.com:ConductorTechnologies/cioseq.git\ncd cioseq\n```\n\nSet up a clean virtual envirionment with Python 2.7 for development (optional).\n\n```\npython -m virtualenv venv\n. ./venv/bin/activate\n```\n\nInstall development dependencies\n```\npip install -r requirements_dev.txt\n```\n\npip install --upgrade . \n\n```\n\n## Changelog\n\n## Version:0.5.1 -- 01 Nov 2023\n\nAdds a method, cap_chunk_count(), to limit the number of chunks. Chunk size is adjusted accordingly.\n\n## Version:0.4.1 -- 28 Aug 2023\n\n* Adds a boolean difference method to the Sequence class.\n\n## Version:0.4.0 -- 26 Aug 2023\n\n* adds the abilliity to build a sequence from files on disk\n\n## Version:0.3.0 -- 10 Jul 2023\n\n* the `to()` function now handles an empty string for step separator, which enables frame spec strings compatible with Katana's command-line.\n\n### Version:0.2.2 -- 25 May 2023\n\n* Simple edit to remove circle test release. [b92a2c9]\n\n\n### Version:0.2.0 -- 25 May 2023\n\n* Implemented a feature to calculate first, middle, and last frames.\n\n### Version:0.1.16 -- 24 May 2023\n\n* Added tests for step and irregular sequences. [742d4c4]\n\n### Version:0.1.15 -- 07 Aug 2021\n\n* Use range without importing builtins. [f148290]\n\n### Version:0.1.14 -- 27 Jun 2021\n\n* Removed builtins module to avoid py2/3 errors. [f148290]\n\n### Version:0.1.13 -- 26 Mar 2021\n\n* CICD tweaks and readme. [b9d05ac]\n\n### Version:0.1.12 -- 11 Mar 2021\n\n* Universal flag. [958ef56]\n* Adds pip-dependency-file key. [719ec31]\n\n### Version:0.1.10 -- 10 Mar 2021\n\n* Adds ssh key so we can push the tag in circleci. [60360af]\n* Use skulk context. [3459bc0]\n\n### Version:0.1.9 -- 09 Mar 2021\n\n* Fixed wrong pypi registry. [a3d82e1]\n\n### Version:0.1.6 -- 09 Mar 2021\n\n* Adds release flow to circleci. [71bbca2]\n* Add .circleci/config.yml. [30fd9d9]\n* Adds tox for py 2.7 and 3.8. [7ce0970]\n\n### Version:0.1.5 -- 21 Sep 2020\n\n* Bad test name and $f4 token support. [f3c1923]\n\n### Version:0.1.3 -- 20 Sep 2020\n\n* Added several examples to the README and implemented and indexing. [fdec3b4]\n \n### Version:0.1.2 -- 19 Sep 2020\n\n* Python 2 and 3 compatibility. [4aba985]\n\n### Version:0.1.1 -- 19 Sep 2020\n\n* Transfer from core. As such, this is the first changelog entry. [54f9132]\n* Sequence consumers must use factory. [a9fd08a]\n* Adds cycle_progressions chunk strategy. [37075c9]\n* Expander path list enhancements (#5)\n* Lib enhancements (#4)\n* adds sequence intersection check\n* allows uppercase characters in angle-bracket template.. [255f61f]\n* Initial commit. [7cf8fd3]\n\n\n--\n",
    "bugtrack_url": null,
    "license": "",
    "summary": "Manage sequences of frame numbers.",
    "version": "0.5.1",
    "project_urls": {
        "Homepage": "https://github.com/ConductorTechnologies/cioseq"
    },
    "split_keywords": [],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "e2d3231cd24046d18543800051027ec5c629f1f93807499a5db0544ffac5b8b3",
                "md5": "78ce5e2ba2b8936090616c0c3e9fd487",
                "sha256": "93487243bbbc34f519e0d6380984edda53b28b99324eda5468a0e6ece0b502f2"
            },
            "downloads": -1,
            "filename": "cioseq-0.5.1-py2.py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "78ce5e2ba2b8936090616c0c3e9fd487",
            "packagetype": "bdist_wheel",
            "python_version": "py2.py3",
            "requires_python": null,
            "size": 18820,
            "upload_time": "2023-11-01T23:00:23",
            "upload_time_iso_8601": "2023-11-01T23:00:23.840925Z",
            "url": "https://files.pythonhosted.org/packages/e2/d3/231cd24046d18543800051027ec5c629f1f93807499a5db0544ffac5b8b3/cioseq-0.5.1-py2.py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2023-11-01 23:00:23",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "ConductorTechnologies",
    "github_project": "cioseq",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": false,
    "circle": true,
    "requirements": [
        {
            "name": "setuptools",
            "specs": []
        },
        {
            "name": "wheel",
            "specs": []
        },
        {
            "name": "twine",
            "specs": []
        },
        {
            "name": "skulk",
            "specs": [
                [
                    ">=",
                    "3.0.0"
                ]
            ]
        }
    ],
    "lcname": "cioseq"
}
        
Elapsed time: 0.13061s