# -*- coding: utf-8 -*- import struct import numpy as np import multiprocessing # To get CPU count. import os import tempfile import subprocess import phstuff.barcode as bc """Handle marshalling data into and out of DIPHA's formats, and optionally manage running the DIPHA executable. """ # FIXME, TODO: These magic numbers should really be read from the # DIPHA header files. DIPHA_MAGIC = 8067171840 DIPHA_WEIGHTED_BOUNDARY_MATRIX = 0 DIPHA_IMAGE_DATA = 1 DIPHA_PERSISTENCE_DIAGRAM = 2 DIPHA_DISTANCE_MATRIX = 7 DIPHA_SPARSE_DISTANCE_MATRIX = 8 def save_weight_matrix(fname, weights): """Write a NumPy weight matrix to a DIPHA full distance matrix file. Attention: DIPHA uses a convention wherein an edge's filtration value is *half* its weight. This function compensates by multiplying every weight by 2. Pay attention in case DIPHA's behavior changes in the future! Parameters: ----------- fname: Name of file to write. weights: NumPy array. Elements will be converted to IEEE-754 doubles and used as weights. The entire array is passed on to DIPHA, whose behvior is undefined if it's not symmetric. """ # override_dipha_half: DIPHA currently (commit 0081862) divides all # entries by 2 when loading the file. If this argument is `True`, # we compensate by multiplying all entries by 2. Be sure to pay # attention if DIPHA's behavior changes! factor = 2.0 m = weights.shape[0] if weights.shape[0] != weights.shape[1]: raise ValueError("Matrix is not square.") with open(fname, "wb") as f: f.write(struct.pack("