bw2calc ======= .. py:module:: bw2calc Submodules ---------- .. toctree:: :maxdepth: 1 /content/api/bw2calc/dense_lca/index /content/api/bw2calc/errors/index /content/api/bw2calc/graph_traversal/index /content/api/bw2calc/independent_lca/index /content/api/bw2calc/indexing/index /content/api/bw2calc/lca/index /content/api/bw2calc/least_squares/index /content/api/bw2calc/log_utils/index /content/api/bw2calc/matrices/index /content/api/bw2calc/mc_vector/index /content/api/bw2calc/monte_carlo/index /content/api/bw2calc/multi_lca/index /content/api/bw2calc/single_matrix/index /content/api/bw2calc/speed_test/index /content/api/bw2calc/utils/index Classes ------- .. autoapisummary:: bw2calc.DenseLCA bw2calc.IndependentLCAMixin bw2calc.LCA bw2calc.LeastSquaresLCA bw2calc.MatrixBuilder bw2calc.MultiLCA bw2calc.TechnosphereBiosphereMatrixBuilder Functions --------- .. autoapisummary:: bw2calc.load_calculation_package Package Contents ---------------- .. py:class:: DenseLCA Bases: :py:obj:`bw2calc.lca.LCA` .. autoapi-inheritance-diagram:: bw2calc.DenseLCA :parts: 1 :private-bases: .. py:method:: solve_linear_system() Master solution function for linear system :math:`Ax=B`. To most numerical analysts, matrix inversion is a sin. -- Nicolas Higham, Accuracy and Stability of Numerical Algorithms, Society for Industrial and Applied Mathematics, Philadelphia, PA, USA, 2002, p. 260. We use `UMFpack `_, which is a very fast solver for sparse matrices. If the technosphere matrix has already been factorized, then the decomposed technosphere (``self.solver``) is reused. Otherwise the calculation is redone completely. .. py:class:: IndependentLCAMixin Bases: :py:obj:`object` Mixin that allows `method`, etc. to be filepaths or ``np.ndarray`` instead of DataStore object names. Removes dependency on `bw2data`. .. py:method:: fix_dictionaries() Don't adjust dictionaries even if ``bw2data`` is present, as functional unit is an integer. .. py:method:: get_array_filepaths() Pass through already correct values .. py:class:: LCA(demand, method=None, weighting=None, normalization=None, database_filepath=None, log_config=None, presamples=None, seed=None, override_presamples_seed=False) Bases: :py:obj:`object` A static LCI or LCIA calculation. Following the general philosophy of Brightway2, and good software practices, there is a clear separation of concerns between retrieving and formatting data and doing an LCA. Building the necessary matrices is done with MatrixBuilder objects (:ref:`matrixbuilders`). The LCA class only does the LCA calculations themselves. Create a new LCA calculation. :param \* *demand*: The demand or functional unit. Needs to be a dictionary to indicate amounts, e.g. ``{("my database", "my process"): 2.5}``. :type \* *demand*: dict :param \* *method*: LCIA Method tuple, e.g. ``("My", "great", "LCIA", "method")``. Can be omitted if only interested in calculating the life cycle inventory. :type \* *method*: tuple, optional :returns: A new LCA object .. py:method:: build_demand_array(demand=None) Turn the demand dictionary into a *NumPy* array of correct size. :param \* *demand*: Demand dictionary. Optional, defaults to ``self.demand``. :type \* *demand*: dict, optional :returns: A 1-dimensional NumPy array .. py:method:: decompose_technosphere() Factorize the technosphere matrix into lower and upper triangular matrices, :math:`A=LU`. Does not solve the linear system :math:`Ax=B`. Doesn't return anything, but creates ``self.solver``. .. warning:: Incorrect results could occur if a technosphere matrix was factorized, and then a new technosphere matrix was constructed, as ``self.solver`` would still be the factorized older technosphere matrix. You are responsible for deleting ``self.solver`` when doing these types of advanced calculations. .. py:method:: fix_dictionaries() Fix technosphere and biosphere dictionaries from this: .. code-block:: python {mapping integer id: matrix row/column index} To this: .. code-block:: python {(database, key): matrix row/column index} This isn't needed for the LCA calculation itself, but is helpful when interpreting results. Doesn't require any arguments or return anything, but changes ``self.activity_dict``, ``self.product_dict`` and ``self.biosphere_dict``. .. py:method:: get_array_filepaths() Use utility functions to get all array filepaths .. py:method:: lci(factorize=False, builder=TBMBuilder) Calculate a life cycle inventory. #. Load LCI data, and construct the technosphere and biosphere matrices. #. Build the demand array #. Solve the linear system to get the supply array and life cycle inventory. :param \* *factorize*: Factorize the technosphere matrix. Makes additional calculations with the same technosphere matrix much faster. Default is ``False``; not useful is only doing one LCI calculation. :type \* *factorize*: bool, optional :param \* *builder*: Default is ``bw2calc.matrices.TechnosphereBiosphereMatrixBuilder``, which is fine for most cases. Custom matrix builders can be used to manipulate data in creative ways before building the matrices. :type \* *builder*: ``MatrixBuilder`` object, optional .. warning:: Custom matrix builders should inherit from ``TechnosphereBiosphereMatrixBuilder``, because technosphere inputs need to have their signs flipped to be negative, as we do :math:`A^{-1}f` directly instead of :math:`(I - A^{-1})f`. Doesn't return anything, but creates ``self.supply_array`` and ``self.inventory``. .. py:method:: lci_calculation() The actual LCI calculation. Separated from ``lci`` to be reusable in cases where the matrices are already built, e.g. ``redo_lci`` and Monte Carlo classes. .. py:method:: lcia(builder=MatrixBuilder) Calculate the life cycle impact assessment. #. Load and construct the characterization matrix #. Multiply the characterization matrix by the life cycle inventory :param \* *builder*: Default is ``bw2calc.matrices.MatrixBuilder``, which is fine for most cases. Custom matrix builders can be used to manipulate data in creative ways before building the characterization matrix. :type \* *builder*: ``MatrixBuilder`` object, optional Doesn't return anything, but creates ``self.characterized_inventory``. .. py:method:: lcia_calculation() The actual LCIA calculation. Separated from ``lcia`` to be reusable in cases where the matrices are already built, e.g. ``redo_lcia`` and Monte Carlo classes. .. py:method:: load_lci_data(fix_dictionaries=True, builder=TBMBuilder) Load data and create technosphere and biosphere matrices. .. py:method:: load_lcia_data(builder=MatrixBuilder) Load data and create characterization matrix. This method will filter out regionalized characterization factors. This filtering needs access to ``bw2data`` - therefore, regionalized methods will cause incorrect results if ``bw2data`` is not importable. .. py:method:: load_normalization_data(builder=MatrixBuilder) Load normalization data. .. py:method:: load_weighting_data() Load weighting data, a 1-element array. .. py:method:: normalization_calculation() The actual normalization calculation. Creates ``self.normalized_inventory``. .. py:method:: normalize() Multiply characterized inventory by flow-specific normalization factors. .. py:method:: rebuild_biosphere_matrix(vector) Build a new biosphere matrix using the same row and column indices, but different values. Useful for Monte Carlo iteration or sensitivity analysis. :param \* *vector*: 1-dimensional NumPy array with length (# of biosphere parameters), in same order as ``self.bio_params``. :type \* *vector*: array Doesn't return anything, but overwrites ``self.biosphere_matrix``. .. py:method:: rebuild_characterization_matrix(vector) Build a new characterization matrix using the same row and column indices, but different values. Useful for Monte Carlo iteration or sensitivity analysis. :param \* *vector*: 1-dimensional NumPy array with length (# of characterization parameters), in same order as ``self.cf_params``. :type \* *vector*: array Doesn't return anything, but overwrites ``self.characterization_matrix``. .. py:method:: rebuild_technosphere_matrix(vector) Build a new technosphere matrix using the same row and column indices, but different values. Useful for Monte Carlo iteration or sensitivity analysis. :param \* *vector*: 1-dimensional NumPy array with length (# of technosphere parameters), in same order as ``self.tech_params``. :type \* *vector*: array Doesn't return anything, but overwrites ``self.technosphere_matrix``. .. py:method:: redo_lci(demand=None) Redo LCI with same databases but different demand. :param \* *demand*: A demand dictionary. :type \* *demand*: dict Doesn't return anything, but overwrites ``self.demand_array``, ``self.supply_array``, and ``self.inventory``. .. warning:: If you want to redo the LCIA as well, use ``redo_lcia(demand)`` directly. .. py:method:: redo_lcia(demand=None) Redo LCIA, optionally with new demand. :param \* *demand*: New demand dictionary. Optional, defaults to ``self.demand``. :type \* *demand*: dict, optional Doesn't return anything, but overwrites ``self.characterized_inventory``. If ``demand`` is given, also overwrites ``self.demand_array``, ``self.supply_array``, and ``self.inventory``. .. py:method:: reverse_dict() Construct reverse dicts from technosphere and biosphere row and col indices to activity_dict/product_dict/biosphere_dict keys. :returns: (reversed ``self.activity_dict``, ``self.product_dict`` and ``self.biosphere_dict``) .. py:method:: solve_linear_system() Master solution function for linear system :math:`Ax=B`. To most numerical analysts, matrix inversion is a sin. -- Nicolas Higham, Accuracy and Stability of Numerical Algorithms, Society for Industrial and Applied Mathematics, Philadelphia, PA, USA, 2002, p. 260. We use `UMFpack `_, which is a very fast solver for sparse matrices. If the technosphere matrix has already been factorized, then the decomposed technosphere (``self.solver``) is reused. Otherwise the calculation is redone completely. .. py:method:: switch_method(method) Switch to LCIA method `method` .. py:method:: switch_normalization(normalization) Switch to LCIA normalization `normalization` .. py:method:: switch_weighting(weighting) Switch to LCIA weighting `weighting` .. py:method:: to_dataframe(cutoff=200) Return all nonzero elements of characterized inventory as Pandas dataframe .. py:method:: top_activities(**kwargs) Call ``bw2analyzer.ContributionAnalyses.annotated_top_processes`` .. py:method:: top_emissions(**kwargs) Call ``bw2analyzer.ContributionAnalyses.annotated_top_emissions`` .. py:method:: weight() Multiply characterized inventory by weighting value. Can be done with or without normalization. .. py:method:: weighting_calculation() The actual weighting calculation. Multiples weighting value by normalized inventory, if available, otherwise by characterized inventory. Creates ``self.weighted_inventory``. .. py:attribute:: _fixed :value: False .. py:attribute:: database_filepath .. py:attribute:: demand .. py:attribute:: logger .. py:attribute:: method .. py:attribute:: normalization .. py:property:: score The LCIA score as a ``float``. Note that this is a `property `_, so it is ``foo.lca``, not ``foo.score()`` .. py:attribute:: seed .. py:attribute:: weighting .. py:class:: LeastSquaresLCA(demand, method=None, weighting=None, normalization=None, database_filepath=None, log_config=None, presamples=None, seed=None, override_presamples_seed=False) Bases: :py:obj:`bw2calc.lca.LCA` .. autoapi-inheritance-diagram:: bw2calc.LeastSquaresLCA :parts: 1 :private-bases: Solve overdetermined technosphere matrix with more products than activities using least-squares approximation. See also: * `Multioutput processes in LCA `_ * `LSMR in SciPy `_ * `Another least-squares algorithm in SciPy `_ Create a new LCA calculation. :param \* *demand*: The demand or functional unit. Needs to be a dictionary to indicate amounts, e.g. ``{("my database", "my process"): 2.5}``. :type \* *demand*: dict :param \* *method*: LCIA Method tuple, e.g. ``("My", "great", "LCIA", "method")``. Can be omitted if only interested in calculating the life cycle inventory. :type \* *method*: tuple, optional :returns: A new LCA object .. py:method:: decompose_technosphere() :abstractmethod: Factorize the technosphere matrix into lower and upper triangular matrices, :math:`A=LU`. Does not solve the linear system :math:`Ax=B`. Doesn't return anything, but creates ``self.solver``. .. warning:: Incorrect results could occur if a technosphere matrix was factorized, and then a new technosphere matrix was constructed, as ``self.solver`` would still be the factorized older technosphere matrix. You are responsible for deleting ``self.solver`` when doing these types of advanced calculations. .. py:method:: solve_linear_system(solver=lsmr) Master solution function for linear system :math:`Ax=B`. To most numerical analysts, matrix inversion is a sin. -- Nicolas Higham, Accuracy and Stability of Numerical Algorithms, Society for Industrial and Applied Mathematics, Philadelphia, PA, USA, 2002, p. 260. We use `UMFpack `_, which is a very fast solver for sparse matrices. If the technosphere matrix has already been factorized, then the decomposed technosphere (``self.solver``) is reused. Otherwise the calculation is redone completely. .. py:class:: MatrixBuilder Bases: :py:obj:`object` The class, and its subclasses, load structured arrays, manipulate them, and generate `SciPy sparse matrices `_. Matrix builders use an array of row indices, an array of column indices, and an array of values to create a `coordinate (coo) matrix `_, which is then converted to a `compressed sparse row (csr) matrix `_. See the following for more information on structured arrays: * `NumPy structured arrays `_ * `Intermediate and processed data `_ These classes are not instantiated, and have only `classmethods `__. They are not really true classes, but more organizational. In other words, you should use: .. code-block:: python MatrixBuilder.build(args) and not: .. code-block:: python mb = MatrixBuilder() mb.build(args) .. py:method:: build(paths, data_label, row_id_label, row_index_label, col_id_label=None, col_index_label=None, row_dict=None, col_dict=None, one_d=False, drop_missing=True) :classmethod: Build a sparse matrix from NumPy structured array(s). See more detailed documentation at :ref:`building-matrices`. This method does the following: TODO: Update #. Load and concatenate the :ref:`structured arrays files ` in filepaths ``paths`` using the function :func:`.utils.load_arrays` into a parameter array. #. If not ``row_dict``, use :meth:`.build_dictionary` to build ``row_dict`` from the parameter array column ``row_id_label``. #. Using the ``row_id_label`` and the ``row_dict``, use the method :meth:`.add_matrix_indices` to add matrix indices to the ``row_index_label`` column. #. If not ``one_d``, do the same to ``col_dict`` and ``col_index_label``, using ``col_id_label``. #. If not ``one_d``, use :meth:`.build_matrix` to build a sparse matrix using ``data_label`` for the matrix data values, and ``row_index_label`` and ``col_index_label`` for row and column indices. #. Else if ``one_d``, use :meth:`.build_diagonal_matrix` to build a diagonal matrix using ``data_label`` for diagonal matrix data values and ``row_index_label`` as row/column indices. #. Return the loaded parameter arrays from step 1, row and column dicts from steps 2 & 4, and matrix from step 5 or 6. :param \* *paths*: List of array filepaths to load. :type \* *paths*: list :param \* *data_label*: Label of column in parameter arrays with matrix data values. :type \* *data_label*: str :param \* *row_id_label*: Label of column in parameter arrays with row ID values, i.e. the integer values returned from ``mapping``. :type \* *row_id_label*: str :param \* *row_index_label*: Label of column in parameter arrays where matrix row indices will be stored. :type \* *row_index_label*: str :param \* *col_id_label*: Label of column in parameter arrays with column ID values, i.e. the integer values returned from ``mapping``. Not needed for diagonal matrices. :type \* *col_id_label*: str, optional :param \* *col_index_label*: Label of column in parameter arrays where matrix column indices will be stored. Not needed for diagonal matrices. :type \* *col_index_label*: str, optional :param \* *row_dict*: Mapping dictionary linking ``row_id_label`` values to ``row_index_label`` values. Will be built if not given. :type \* *row_dict*: dict, optional :param \* *col_dict*: Mapping dictionary linking ``col_id_label`` values to ``col_index_label`` values. Will be built if not given. :type \* *col_dict*: dict, optional :param \* *one_d*: Build diagonal matrix. :type \* *one_d*: bool :param \* *drop_missing*: Remove rows from the parameter array which aren't mapped by ``row_dict`` or ``col_dict``. Default is ``True``. Advanced use only. :type \* *drop_missing*: bool :returns: A :ref:`numpy parameter array `, the row mapping dictionary, the column mapping dictionary, and a COO sparse matrix. .. py:method:: build_diagonal_matrix(array, row_dict, index_label, data_label=None, new_data=None) :classmethod: Build diagonal sparse matrix. .. py:method:: build_matrix(array, row_dict, col_dict, row_index_label, col_index_label, data_label=None, new_data=None) :classmethod: Build sparse matrix. .. py:class:: MultiLCA(cs_name, log_config=None) Bases: :py:obj:`object` Wrapper class for performing LCA calculations with many functional units and LCIA methods. Needs to be passed a ``calculation_setup`` name. This class does not subclass the `LCA` class, and performs all calculations upon instantiation. Initialization creates `self.results`, which is a NumPy array of LCA scores, with rows of functional units and columns of LCIA methods. Ordering is the same as in the `calculation_setup`. .. py:property:: all Get all possible databases by merging all functional units .. py:attribute:: func_units .. py:attribute:: lca .. py:attribute:: method_matrices :value: [] .. py:attribute:: methods .. py:attribute:: results .. py:class:: TechnosphereBiosphereMatrixBuilder Bases: :py:obj:`MatrixBuilder` .. autoapi-inheritance-diagram:: bw2calc.TechnosphereBiosphereMatrixBuilder :parts: 1 :private-bases: Subclass of ``MatrixBuilder`` that separates technosphere and biosphere parameters .. py:method:: build(paths) :classmethod: Build the technosphere and biosphere sparse matrices. .. py:method:: build_technosphere_matrix(array, activity_dict, product_dict, new_data=None) :classmethod: .. py:method:: fix_supply_use(array, vector) :classmethod: Make technosphere inputs negative. .. py:method:: get_biosphere_inputs_mask(array) :classmethod: Get boolean mask of biosphere flows from ``array`` (i.e. the ones to include when building the biosphere matrix). .. py:method:: get_technosphere_inputs_mask(array) :classmethod: Get boolean mask of technosphere inputs from ``array`` (i.e. the ones to include when building the technosphere matrix). .. py:method:: select_biosphere_array(array) :classmethod: Create a new array with biosphere matrix exchanges .. py:method:: select_technosphere_array(array) :classmethod: Create a new array with technosphere matrix exchanges .. py:function:: load_calculation_package(fp) Load a calculation package created by ``save_calculation_package``. NumPy arrays are saved to a temporary directory, and file paths are adjusted. ``fp`` is the absolute file path of a calculation package file. Returns a dictionary suitable for passing to an LCA object, e.g. ``LCA(**load_calculation_package(fp))``.