MCPcopy Create free account
hub / github.com/ashvardanian/StringZilla / NeedlemanWunsch_init

Function NeedlemanWunsch_init

python/stringzillas.c:940–1000  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

938}
939
940static int NeedlemanWunsch_init(NeedlemanWunsch *self, PyObject *args, PyObject *kwargs) {
941 PyObject *substitution_matrix_obj = NULL;
942 sz_error_cost_t open = -1, extend = -1;
943 PyObject *capabilities_tuple = NULL;
944 sz_capability_t capabilities = default_hardware_capabilities;
945
946 // Parse arguments: substitution_matrix, open, extend, capabilities
947 static char *kwlist[] = {"substitution_matrix", "open", "extend", "capabilities", NULL};
948 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|iiO", kwlist, &substitution_matrix_obj, &open, &extend,
949 &capabilities_tuple))
950 return -1;
951
952 // Validate substitution matrix (should be a 256x256 numpy array)
953 if (!numpy_available || !PyArray_Check(substitution_matrix_obj)) {
954 PyErr_SetString(PyExc_TypeError, "substitution_matrix must be a NumPy array");
955 return -1;
956 }
957
958 PyArrayObject *subs_array = (PyArrayObject *)substitution_matrix_obj;
959 if (PyArray_NDIM(subs_array) != 2 || PyArray_DIM(subs_array, 0) != 256 || PyArray_DIM(subs_array, 1) != 256) {
960 PyErr_SetString(PyExc_ValueError, "substitution_matrix must be a 256x256 array");
961 return -1;
962 }
963
964 if (PyArray_TYPE(subs_array) != NPY_INT8) {
965 PyErr_SetString(PyExc_TypeError, "substitution_matrix must have int8 dtype");
966 return -1;
967 }
968
969 // Check that array is C-contiguous for safe memory access
970 if (!PyArray_IS_C_CONTIGUOUS(subs_array)) {
971 PyErr_SetString(PyExc_ValueError,
972 "substitution_matrix must be a C-contiguous array. Use np.ascontiguousarray() to convert.");
973 return -1;
974 }
975
976 // Parse capabilities if provided
977 if (capabilities_tuple) {
978 if (parse_and_intersect_capabilities(capabilities_tuple, &capabilities) != 0) { return -1; }
979 }
980
981 // Initialize the engine
982 sz_error_cost_t *subs_data = (sz_error_cost_t *)PyArray_DATA(subs_array);
983
984 // Create a simple checksum of the substitution matrix for the description
985 sz_u32_t subs_checksum = 0;
986 for (int i = 0; i < 256; i += 16) // Sample every 16th element
987 subs_checksum += (sz_u32_t)subs_data[i * 256 + i]; // Diagonal elements
988
989 char const *error_detail = NULL;
990 sz_status_t status =
991 szs_needleman_wunsch_scores_init(subs_data, open, extend, NULL, capabilities, &self->handle, &error_detail);
992 if (status != sz_success_k) {
993 set_stringzilla_error(status, error_detail, "NeedlemanWunsch initialization");
994 return -1;
995 }
996
997 snprintf(self->description, sizeof(self->description), "%X,%d,%d", subs_checksum & 0xFFFF, open, extend);

Callers

nothing calls this directly

Calls 2

set_stringzilla_errorFunction · 0.85

Tested by

no test coverage detected

Used in the wild real call sites across dependent graphs

searching dependent graphs…