Metadata-Version: 2.4
Name: cmflow
Version: 0.4.0
Summary: Building TOUGH2/Waiwera models from layers of conceptual models
Project-URL: Homepage, https://github.com/cyeh015/cmflow
Project-URL: Source Code, https://github.com/cyeh015/cmflow
Author-email: Angus Yeh <a.yeh@auckland.ac.nz>
Classifier: License :: OSI Approved :: GNU Lesser General Public License v3 (LGPLv3)
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Requires-Python: >=3.8
Requires-Dist: pytough
Requires-Dist: rtree
Requires-Dist: shapely
Description-Content-Type: text/markdown

# Install

    pip install -U cmflow

# Install Dependency

On most platforms, you should be able to install these packages by:

    pip install shapely
    pip install rtree
    pip install pytough

On Linux (Ubuntu shown here) these can be installed via apt-get:

    sudo apt-get install -y python-shapely
    sudo apt-get install -y python-rtree

# Example

Creates BMStats that can be used later, from Leapfrog Geology:

    # (ONLY ONCE) geo used to get geology from Leapfrog geological model
    cmgeo = mulgrid('g_very_fine.dat')
    
    # CSV file created by Leapfrog using cmgeo above
    leapfrog = LeapfrogGM()
    leapfrog.import_leapfrog_csv('grid_gtmp_ay2017_03_6_fit.csv')
    
    cm_geology = CM_Blocky(cmgeo, leapfrog)
    
    # whatever active model we are working on
    bmgeo = mulgrid('gwaixx_yy.dat')
    
    bms_geology = cm_geology.calc_bmstats(bm_geo)
    bms_geology.save('a.json')

A BMStats object can be reused (very fast) to eg.

    bms_geology = BMStats('a.json')
    
    # get a cell's stats
    cs = bms_geology.cellstats['abc12']
    
    # rock that occupies most in cell 'abc12'
    rock_name = bms_geology.zones[np.argmax(cs)]
    
    # how many rock in cell 'abc12'
    n_rock = len(np.nonzero(cs))
    
    # list all rocks in cell 'abc12'
    rocks = [bm_geology.zones[i] for i in np.nonzero(cs)]
    
    # find all blocks intersect with the zone
    blocks, ratios = bm_geology.blocks_in_zone('BASE1')
    block_idx, ratios = bm_geology.blocks_in_zone('BASE1', indices=True)
    

# BMStats

This is the object that we keep for later use.  It is associated to a certain
"geometry" file.  So each cell has information on zones. Usually this is
generated by cm.populate_model(), which can be expensive.

- ? should I call it CMStats?
- ? TODO, .cellstats access by cell index
- ? TODO, .

Base Model Stats, mainly numpy arrays with rows corresponding to mulgrid
blocks, and columns corresponding to zones.  Each is a value, usually
between 0.0 and 1.0.  Often 1.0 is indicating that particular block is fully
within the zone.

.stats numpy array (n,m), n = num of model blocks, m = num of zones
.zones list of zone names (str)
.zonestats dict of stats column by zone names
.cellstats dict of stats row by block name

    6 elements, 3 zones
     A    B    C
    0.0, 0.7, 0.3,  -> row sum to 1.0, element 0, 0.7 rock B, 0.3 rock C 
    1.0, 0.0, 0.0, 
    1.0, 0.0, 0.0, 
    0.0, 0.5, 0.5, 
    0.1, 0.2, 0.7, 
    0.0, 1.0, 0.0, 
    (this is only one way of using it, such as a rocktype)

.stats, numpy array (n * m), n number of geometry cells, m number of zones
.zones, a list of zone name, eg. geology rock names, fault names etc
.zonestats, a dict keyed by zone name, an array of size number of cells, each cell is between 
.cellstats, a dict of stats by cell name

.save()
.load()
.add_stats() add another bmstat, merge stats
.add_cm() calls cm.populate_model, and merge stats

# CM
# CM_Blocky
# CM_Prism
# CM_Faults

These are the objects that can be created in order to create the final BMStats
objects.  The common method .populate_model(bm_geo) is called to create BMStats
objects.  It means the conceptual model is "applied" onto the bm_geo.

- TODO, .populate_model() should return BMStats instead
- ? TODO, .populate_model() should be called something else?

.populate_model(bm_geo) takes a target geometry, and return/creates BMStats


# LeapfrogGM




# Build and Publish

To bump version, create a tag, eg. `v0.1.0`.

If upload for the first time, create a PyPI account token, then use it for the publish step. The PyPI project will be created on first upload. Then revoke the account token and create a project token for later publishes.

Publish to PyPI:

```console
hatch build
hatch publish dist/*
```
