Generated by Cython 0.29.32

Yellow lines hint at Python interaction.
Click on a line that starts with a "+" to see the C code that Cython generated for it.

Raw output: _insert.c

+001: # encoding: utf-8
  __pyx_t_2 = __Pyx_PyDict_NewPresized(0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 1, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  if (PyDict_SetItem(__pyx_d, __pyx_n_s_test, __pyx_t_2) < 0) __PYX_ERR(0, 1, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 002: # cython: profile=False, boundscheck=False, wraparound=False
 003: 
 004: from ._bp cimport BP
+005: from . import to_skbio_treenode
  __pyx_t_1 = PyList_New(1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 5, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __Pyx_INCREF(__pyx_n_s_to_skbio_treenode);
  __Pyx_GIVEREF(__pyx_n_s_to_skbio_treenode);
  PyList_SET_ITEM(__pyx_t_1, 0, __pyx_n_s_to_skbio_treenode);
  __pyx_t_2 = __Pyx_Import(__pyx_n_s__22, __pyx_t_1, 1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 5, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  __pyx_t_1 = __Pyx_ImportFrom(__pyx_t_2, __pyx_n_s_to_skbio_treenode); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 5, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  if (PyDict_SetItem(__pyx_d, __pyx_n_s_to_skbio_treenode, __pyx_t_1) < 0) __PYX_ERR(0, 5, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+006: import pandas as pd
  __pyx_t_2 = __Pyx_Import(__pyx_n_s_pandas, 0, -1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 6, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  if (PyDict_SetItem(__pyx_d, __pyx_n_s_pd, __pyx_t_2) < 0) __PYX_ERR(0, 6, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+007: import json
  __pyx_t_2 = __Pyx_Import(__pyx_n_s_json, 0, -1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 7, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  if (PyDict_SetItem(__pyx_d, __pyx_n_s_json, __pyx_t_2) < 0) __PYX_ERR(0, 7, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+008: import skbio
  __pyx_t_2 = __Pyx_Import(__pyx_n_s_skbio, 0, -1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 8, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  if (PyDict_SetItem(__pyx_d, __pyx_n_s_skbio, __pyx_t_2) < 0) __PYX_ERR(0, 8, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 009: cimport cython
 010: 
 011: 
 012: # see the comment in _insert_setup. Avoid the use of invalidate_caches as it
 013: # is very expensive for tree mutation operations
+014: class TreeNodeNoValidate(skbio.TreeNode):
  __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_skbio); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 14, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_t_2, __pyx_n_s_TreeNode); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 14, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __pyx_t_2 = PyTuple_New(1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 14, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __Pyx_GIVEREF(__pyx_t_1);
  PyTuple_SET_ITEM(__pyx_t_2, 0, __pyx_t_1);
  __pyx_t_1 = 0;
  __pyx_t_1 = __Pyx_CalculateMetaclass(NULL, __pyx_t_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 14, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __pyx_t_3 = __Pyx_Py3MetaclassPrepare(__pyx_t_1, __pyx_t_2, __pyx_n_s_TreeNodeNoValidate, __pyx_n_s_TreeNodeNoValidate, (PyObject *) NULL, __pyx_n_s_bp__insert, (PyObject *) NULL); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 14, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
/* … */
  __pyx_t_4 = __Pyx_Py3ClassCreate(__pyx_t_1, __pyx_n_s_TreeNodeNoValidate, __pyx_t_2, __pyx_t_3, NULL, 0, 1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 14, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  if (PyDict_SetItem(__pyx_d, __pyx_n_s_TreeNodeNoValidate, __pyx_t_4) < 0) __PYX_ERR(0, 14, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+015:     def invalidate_caches(self):
/* Python wrapper */
static PyObject *__pyx_pw_2bp_7_insert_18TreeNodeNoValidate_1invalidate_caches(PyObject *__pyx_self, PyObject *__pyx_v_self); /*proto*/
static PyMethodDef __pyx_mdef_2bp_7_insert_18TreeNodeNoValidate_1invalidate_caches = {"invalidate_caches", (PyCFunction)__pyx_pw_2bp_7_insert_18TreeNodeNoValidate_1invalidate_caches, METH_O, 0};
static PyObject *__pyx_pw_2bp_7_insert_18TreeNodeNoValidate_1invalidate_caches(PyObject *__pyx_self, PyObject *__pyx_v_self) {
  PyObject *__pyx_r = 0;
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("invalidate_caches (wrapper)", 0);
  __pyx_r = __pyx_pf_2bp_7_insert_18TreeNodeNoValidate_invalidate_caches(__pyx_self, ((PyObject *)__pyx_v_self));

  /* function exit code */
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}

static PyObject *__pyx_pf_2bp_7_insert_18TreeNodeNoValidate_invalidate_caches(CYTHON_UNUSED PyObject *__pyx_self, CYTHON_UNUSED PyObject *__pyx_v_self) {
  PyObject *__pyx_r = NULL;
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("invalidate_caches", 0);

  /* function exit code */
  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
  __Pyx_XGIVEREF(__pyx_r);
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}
/* … */
  __pyx_tuple__23 = PyTuple_Pack(1, __pyx_n_s_self); if (unlikely(!__pyx_tuple__23)) __PYX_ERR(0, 15, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_tuple__23);
  __Pyx_GIVEREF(__pyx_tuple__23);
/* … */
  __pyx_t_4 = __Pyx_CyFunction_New(&__pyx_mdef_2bp_7_insert_18TreeNodeNoValidate_1invalidate_caches, 0, __pyx_n_s_TreeNodeNoValidate_invalidate_ca, NULL, __pyx_n_s_bp__insert, __pyx_d, ((PyObject *)__pyx_codeobj__24)); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 15, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  if (__Pyx_SetNameInClass(__pyx_t_3, __pyx_n_s_invalidate_caches, __pyx_t_4) < 0) __PYX_ERR(0, 15, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
  __pyx_codeobj__24 = (PyObject*)__Pyx_PyCode_New(1, 0, 1, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__23, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_bp__insert_pyx, __pyx_n_s_invalidate_caches, 15, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__24)) __PYX_ERR(0, 15, __pyx_L1_error)
 016:         pass
 017: 
 018: 
 019: # our noop used when monkey patching invalidate_caches
+020: def noop(*arg, **kwargs):
/* Python wrapper */
static PyObject *__pyx_pw_2bp_7_insert_1noop(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
static PyMethodDef __pyx_mdef_2bp_7_insert_1noop = {"noop", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_2bp_7_insert_1noop, METH_VARARGS|METH_KEYWORDS, 0};
static PyObject *__pyx_pw_2bp_7_insert_1noop(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
  CYTHON_UNUSED PyObject *__pyx_v_arg = 0;
  CYTHON_UNUSED PyObject *__pyx_v_kwargs = 0;
  PyObject *__pyx_r = 0;
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("noop (wrapper)", 0);
  if (unlikely(__pyx_kwds) && unlikely(!__Pyx_CheckKeywordStrings(__pyx_kwds, "noop", 1))) return NULL;
  __Pyx_INCREF(__pyx_args);
  __pyx_v_arg = __pyx_args;
  __pyx_r = __pyx_pf_2bp_7_insert_noop(__pyx_self, __pyx_v_arg, __pyx_v_kwargs);

  /* function exit code */
  __Pyx_XDECREF(__pyx_v_arg);
  __Pyx_XDECREF(__pyx_v_kwargs);
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}

static PyObject *__pyx_pf_2bp_7_insert_noop(CYTHON_UNUSED PyObject *__pyx_self, CYTHON_UNUSED PyObject *__pyx_v_arg, CYTHON_UNUSED PyObject *__pyx_v_kwargs) {
  PyObject *__pyx_r = NULL;
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("noop", 0);

  /* function exit code */
  __pyx_r = Py_None; __Pyx_INCREF(Py_None);
  __Pyx_XGIVEREF(__pyx_r);
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}
/* … */
  __pyx_tuple__25 = PyTuple_Pack(2, __pyx_n_s_arg, __pyx_n_s_kwargs); if (unlikely(!__pyx_tuple__25)) __PYX_ERR(0, 20, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_tuple__25);
  __Pyx_GIVEREF(__pyx_tuple__25);
/* … */
  __pyx_t_2 = PyCFunction_NewEx(&__pyx_mdef_2bp_7_insert_1noop, NULL, __pyx_n_s_bp__insert); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 20, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  if (PyDict_SetItem(__pyx_d, __pyx_n_s_noop, __pyx_t_2) < 0) __PYX_ERR(0, 20, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __pyx_codeobj__26 = (PyObject*)__Pyx_PyCode_New(0, 0, 2, 0, CO_OPTIMIZED|CO_NEWLOCALS|CO_VARARGS|CO_VARKEYWORDS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__25, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_bp__insert_pyx, __pyx_n_s_noop, 20, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__26)) __PYX_ERR(0, 20, __pyx_L1_error)
 021:     pass
 022: 
 023: 
 024: # pandas apply functions for preallocation of objects in bulk
+025: def _preallocate_fragment(r):
/* Python wrapper */
static PyObject *__pyx_pw_2bp_7_insert_3_preallocate_fragment(PyObject *__pyx_self, PyObject *__pyx_v_r); /*proto*/
static PyMethodDef __pyx_mdef_2bp_7_insert_3_preallocate_fragment = {"_preallocate_fragment", (PyCFunction)__pyx_pw_2bp_7_insert_3_preallocate_fragment, METH_O, 0};
static PyObject *__pyx_pw_2bp_7_insert_3_preallocate_fragment(PyObject *__pyx_self, PyObject *__pyx_v_r) {
  PyObject *__pyx_r = 0;
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("_preallocate_fragment (wrapper)", 0);
  __pyx_r = __pyx_pf_2bp_7_insert_2_preallocate_fragment(__pyx_self, ((PyObject *)__pyx_v_r));

  /* function exit code */
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}

static PyObject *__pyx_pf_2bp_7_insert_2_preallocate_fragment(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_r) {
  PyObject *__pyx_r = NULL;
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("_preallocate_fragment", 0);
/* … */
  /* function exit code */
  __pyx_L1_error:;
  __Pyx_XDECREF(__pyx_t_1);
  __Pyx_XDECREF(__pyx_t_2);
  __Pyx_XDECREF(__pyx_t_3);
  __Pyx_AddTraceback("bp._insert._preallocate_fragment", __pyx_clineno, __pyx_lineno, __pyx_filename);
  __pyx_r = NULL;
  __pyx_L0:;
  __Pyx_XGIVEREF(__pyx_r);
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}
/* … */
  __pyx_tuple__27 = PyTuple_Pack(1, __pyx_n_s_r); if (unlikely(!__pyx_tuple__27)) __PYX_ERR(0, 25, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_tuple__27);
  __Pyx_GIVEREF(__pyx_tuple__27);
/* … */
  __pyx_t_2 = PyCFunction_NewEx(&__pyx_mdef_2bp_7_insert_3_preallocate_fragment, NULL, __pyx_n_s_bp__insert); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 25, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  if (PyDict_SetItem(__pyx_d, __pyx_n_s_preallocate_fragment, __pyx_t_2) < 0) __PYX_ERR(0, 25, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __pyx_codeobj__28 = (PyObject*)__Pyx_PyCode_New(1, 0, 1, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__27, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_bp__insert_pyx, __pyx_n_s_preallocate_fragment, 25, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__28)) __PYX_ERR(0, 25, __pyx_L1_error)
+026:     return TreeNodeNoValidate(name=r['fragment'], length=r['pendant_length'])
  __Pyx_XDECREF(__pyx_r);
  __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_TreeNodeNoValidate); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 26, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __pyx_t_2 = __Pyx_PyDict_NewPresized(2); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 26, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __pyx_t_3 = __Pyx_PyObject_Dict_GetItem(__pyx_v_r, __pyx_n_s_fragment); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 26, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
  if (PyDict_SetItem(__pyx_t_2, __pyx_n_s_name, __pyx_t_3) < 0) __PYX_ERR(0, 26, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
  __pyx_t_3 = __Pyx_PyObject_Dict_GetItem(__pyx_v_r, __pyx_n_s_pendant_length); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 26, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
  if (PyDict_SetItem(__pyx_t_2, __pyx_n_s_length, __pyx_t_3) < 0) __PYX_ERR(0, 26, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
  __pyx_t_3 = __Pyx_PyObject_Call(__pyx_t_1, __pyx_empty_tuple, __pyx_t_2); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 26, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __pyx_r = __pyx_t_3;
  __pyx_t_3 = 0;
  goto __pyx_L0;
 027: 
 028: 
+029: def _preallocate_empty(r):
/* Python wrapper */
static PyObject *__pyx_pw_2bp_7_insert_5_preallocate_empty(PyObject *__pyx_self, PyObject *__pyx_v_r); /*proto*/
static PyMethodDef __pyx_mdef_2bp_7_insert_5_preallocate_empty = {"_preallocate_empty", (PyCFunction)__pyx_pw_2bp_7_insert_5_preallocate_empty, METH_O, 0};
static PyObject *__pyx_pw_2bp_7_insert_5_preallocate_empty(PyObject *__pyx_self, PyObject *__pyx_v_r) {
  PyObject *__pyx_r = 0;
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("_preallocate_empty (wrapper)", 0);
  __pyx_r = __pyx_pf_2bp_7_insert_4_preallocate_empty(__pyx_self, ((PyObject *)__pyx_v_r));

  /* function exit code */
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}

static PyObject *__pyx_pf_2bp_7_insert_4_preallocate_empty(CYTHON_UNUSED PyObject *__pyx_self, CYTHON_UNUSED PyObject *__pyx_v_r) {
  PyObject *__pyx_r = NULL;
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("_preallocate_empty", 0);
/* … */
  /* function exit code */
  __pyx_L1_error:;
  __Pyx_XDECREF(__pyx_t_1);
  __Pyx_XDECREF(__pyx_t_2);
  __Pyx_XDECREF(__pyx_t_3);
  __Pyx_AddTraceback("bp._insert._preallocate_empty", __pyx_clineno, __pyx_lineno, __pyx_filename);
  __pyx_r = NULL;
  __pyx_L0:;
  __Pyx_XGIVEREF(__pyx_r);
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}
/* … */
  __pyx_tuple__29 = PyTuple_Pack(1, __pyx_n_s_r); if (unlikely(!__pyx_tuple__29)) __PYX_ERR(0, 29, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_tuple__29);
  __Pyx_GIVEREF(__pyx_tuple__29);
/* … */
  __pyx_t_2 = PyCFunction_NewEx(&__pyx_mdef_2bp_7_insert_5_preallocate_empty, NULL, __pyx_n_s_bp__insert); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 29, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  if (PyDict_SetItem(__pyx_d, __pyx_n_s_preallocate_empty, __pyx_t_2) < 0) __PYX_ERR(0, 29, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __pyx_codeobj__30 = (PyObject*)__Pyx_PyCode_New(1, 0, 1, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__29, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_bp__insert_pyx, __pyx_n_s_preallocate_empty, 29, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__30)) __PYX_ERR(0, 29, __pyx_L1_error)
+030:     return TreeNodeNoValidate()
  __Pyx_XDECREF(__pyx_r);
  __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_TreeNodeNoValidate); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 30, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __pyx_t_3 = NULL;
  if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_2))) {
    __pyx_t_3 = PyMethod_GET_SELF(__pyx_t_2);
    if (likely(__pyx_t_3)) {
      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2);
      __Pyx_INCREF(__pyx_t_3);
      __Pyx_INCREF(function);
      __Pyx_DECREF_SET(__pyx_t_2, function);
    }
  }
  __pyx_t_1 = (__pyx_t_3) ? __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_3) : __Pyx_PyObject_CallNoArg(__pyx_t_2);
  __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0;
  if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 30, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __pyx_r = __pyx_t_1;
  __pyx_t_1 = 0;
  goto __pyx_L0;
 031: 
 032: 
+033: def _insert_setup(placements, bptree, insert_type):
/* Python wrapper */
static PyObject *__pyx_pw_2bp_7_insert_7_insert_setup(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
static PyMethodDef __pyx_mdef_2bp_7_insert_7_insert_setup = {"_insert_setup", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_2bp_7_insert_7_insert_setup, METH_VARARGS|METH_KEYWORDS, 0};
static PyObject *__pyx_pw_2bp_7_insert_7_insert_setup(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
  PyObject *__pyx_v_placements = 0;
  PyObject *__pyx_v_bptree = 0;
  PyObject *__pyx_v_insert_type = 0;
  PyObject *__pyx_r = 0;
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("_insert_setup (wrapper)", 0);
  {
    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_placements,&__pyx_n_s_bptree,&__pyx_n_s_insert_type,0};
    PyObject* values[3] = {0,0,0};
    if (unlikely(__pyx_kwds)) {
      Py_ssize_t kw_args;
      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
      switch (pos_args) {
        case  3: values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
        CYTHON_FALLTHROUGH;
        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
        CYTHON_FALLTHROUGH;
        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
        CYTHON_FALLTHROUGH;
        case  0: break;
        default: goto __pyx_L5_argtuple_error;
      }
      kw_args = PyDict_Size(__pyx_kwds);
      switch (pos_args) {
        case  0:
        if (likely((values[0] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_placements)) != 0)) kw_args--;
        else goto __pyx_L5_argtuple_error;
        CYTHON_FALLTHROUGH;
        case  1:
        if (likely((values[1] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_bptree)) != 0)) kw_args--;
        else {
          __Pyx_RaiseArgtupleInvalid("_insert_setup", 1, 3, 3, 1); __PYX_ERR(0, 33, __pyx_L3_error)
        }
        CYTHON_FALLTHROUGH;
        case  2:
        if (likely((values[2] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_insert_type)) != 0)) kw_args--;
        else {
          __Pyx_RaiseArgtupleInvalid("_insert_setup", 1, 3, 3, 2); __PYX_ERR(0, 33, __pyx_L3_error)
        }
      }
      if (unlikely(kw_args > 0)) {
        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "_insert_setup") < 0)) __PYX_ERR(0, 33, __pyx_L3_error)
      }
    } else if (PyTuple_GET_SIZE(__pyx_args) != 3) {
      goto __pyx_L5_argtuple_error;
    } else {
      values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
      values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
      values[2] = PyTuple_GET_ITEM(__pyx_args, 2);
    }
    __pyx_v_placements = values[0];
    __pyx_v_bptree = values[1];
    __pyx_v_insert_type = values[2];
  }
  goto __pyx_L4_argument_unpacking_done;
  __pyx_L5_argtuple_error:;
  __Pyx_RaiseArgtupleInvalid("_insert_setup", 1, 3, 3, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 33, __pyx_L3_error)
  __pyx_L3_error:;
  __Pyx_AddTraceback("bp._insert._insert_setup", __pyx_clineno, __pyx_lineno, __pyx_filename);
  __Pyx_RefNannyFinishContext();
  return NULL;
  __pyx_L4_argument_unpacking_done:;
  __pyx_r = __pyx_pf_2bp_7_insert_6_insert_setup(__pyx_self, __pyx_v_placements, __pyx_v_bptree, __pyx_v_insert_type);
  int __pyx_lineno = 0;
  const char *__pyx_filename = NULL;
  int __pyx_clineno = 0;

  /* function exit code */
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}

static PyObject *__pyx_pf_2bp_7_insert_6_insert_setup(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_placements, PyObject *__pyx_v_bptree, PyObject *__pyx_v_insert_type) {
  PyObject *__pyx_v_sktree = NULL;
  PyObject *__pyx_v_node_lookup = NULL;
  PyObject *__pyx_v_node = NULL;
  PyObject *__pyx_7genexpr__pyx_v_n = NULL;
  PyObject *__pyx_r = NULL;
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("_insert_setup", 0);
  __Pyx_INCREF(__pyx_v_placements);
/* … */
  /* function exit code */
  __pyx_L1_error:;
  __Pyx_XDECREF(__pyx_t_1);
  __Pyx_XDECREF(__pyx_t_2);
  __Pyx_XDECREF(__pyx_t_3);
  __Pyx_XDECREF(__pyx_t_4);
  __Pyx_AddTraceback("bp._insert._insert_setup", __pyx_clineno, __pyx_lineno, __pyx_filename);
  __pyx_r = NULL;
  __pyx_L0:;
  __Pyx_XDECREF(__pyx_v_sktree);
  __Pyx_XDECREF(__pyx_v_node_lookup);
  __Pyx_XDECREF(__pyx_v_node);
  __Pyx_XDECREF(__pyx_7genexpr__pyx_v_n);
  __Pyx_XDECREF(__pyx_v_placements);
  __Pyx_XGIVEREF(__pyx_r);
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}
/* … */
  __pyx_tuple__31 = PyTuple_Pack(7, __pyx_n_s_placements, __pyx_n_s_bptree, __pyx_n_s_insert_type, __pyx_n_s_sktree, __pyx_n_s_node_lookup, __pyx_n_s_node, __pyx_n_s_n); if (unlikely(!__pyx_tuple__31)) __PYX_ERR(0, 33, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_tuple__31);
  __Pyx_GIVEREF(__pyx_tuple__31);
/* … */
  __pyx_t_2 = PyCFunction_NewEx(&__pyx_mdef_2bp_7_insert_7_insert_setup, NULL, __pyx_n_s_bp__insert); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 33, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  if (PyDict_SetItem(__pyx_d, __pyx_n_s_insert_setup, __pyx_t_2) < 0) __PYX_ERR(0, 33, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __pyx_codeobj__32 = (PyObject*)__Pyx_PyCode_New(3, 0, 7, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__31, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_bp__insert_pyx, __pyx_n_s_insert_setup, 33, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__32)) __PYX_ERR(0, 33, __pyx_L1_error)
 034:     # insertion setup addresses:
 035:     # * treenode caching
 036:     # * placement ordering
 037:     # * preallocation of objects where "easy"
 038: 
+039:     sktree = to_skbio_treenode(bptree)
  __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_to_skbio_treenode); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 39, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __pyx_t_3 = NULL;
  if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_2))) {
    __pyx_t_3 = PyMethod_GET_SELF(__pyx_t_2);
    if (likely(__pyx_t_3)) {
      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2);
      __Pyx_INCREF(__pyx_t_3);
      __Pyx_INCREF(function);
      __Pyx_DECREF_SET(__pyx_t_2, function);
    }
  }
  __pyx_t_1 = (__pyx_t_3) ? __Pyx_PyObject_Call2Args(__pyx_t_2, __pyx_t_3, __pyx_v_bptree) : __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_v_bptree);
  __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0;
  if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 39, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __pyx_v_sktree = __pyx_t_1;
  __pyx_t_1 = 0;
+040:     node_lookup = {n.edge_num: n for n in sktree.traverse(include_self=True)}
  { /* enter inner scope */
    __pyx_t_1 = PyDict_New(); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 40, __pyx_L5_error)
    __Pyx_GOTREF(__pyx_t_1);
    __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_sktree, __pyx_n_s_traverse); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 40, __pyx_L5_error)
    __Pyx_GOTREF(__pyx_t_2);
    __pyx_t_3 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 40, __pyx_L5_error)
    __Pyx_GOTREF(__pyx_t_3);
    if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_include_self, Py_True) < 0) __PYX_ERR(0, 40, __pyx_L5_error)
    __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_empty_tuple, __pyx_t_3); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 40, __pyx_L5_error)
    __Pyx_GOTREF(__pyx_t_4);
    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
    if (likely(PyList_CheckExact(__pyx_t_4)) || PyTuple_CheckExact(__pyx_t_4)) {
      __pyx_t_3 = __pyx_t_4; __Pyx_INCREF(__pyx_t_3); __pyx_t_5 = 0;
      __pyx_t_6 = NULL;
    } else {
      __pyx_t_5 = -1; __pyx_t_3 = PyObject_GetIter(__pyx_t_4); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 40, __pyx_L5_error)
      __Pyx_GOTREF(__pyx_t_3);
      __pyx_t_6 = Py_TYPE(__pyx_t_3)->tp_iternext; if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 40, __pyx_L5_error)
    }
    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
    for (;;) {
      if (likely(!__pyx_t_6)) {
        if (likely(PyList_CheckExact(__pyx_t_3))) {
          if (__pyx_t_5 >= PyList_GET_SIZE(__pyx_t_3)) break;
          #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS
          __pyx_t_4 = PyList_GET_ITEM(__pyx_t_3, __pyx_t_5); __Pyx_INCREF(__pyx_t_4); __pyx_t_5++; if (unlikely(0 < 0)) __PYX_ERR(0, 40, __pyx_L5_error)
          #else
          __pyx_t_4 = PySequence_ITEM(__pyx_t_3, __pyx_t_5); __pyx_t_5++; if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 40, __pyx_L5_error)
          __Pyx_GOTREF(__pyx_t_4);
          #endif
        } else {
          if (__pyx_t_5 >= PyTuple_GET_SIZE(__pyx_t_3)) break;
          #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS
          __pyx_t_4 = PyTuple_GET_ITEM(__pyx_t_3, __pyx_t_5); __Pyx_INCREF(__pyx_t_4); __pyx_t_5++; if (unlikely(0 < 0)) __PYX_ERR(0, 40, __pyx_L5_error)
          #else
          __pyx_t_4 = PySequence_ITEM(__pyx_t_3, __pyx_t_5); __pyx_t_5++; if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 40, __pyx_L5_error)
          __Pyx_GOTREF(__pyx_t_4);
          #endif
        }
      } else {
        __pyx_t_4 = __pyx_t_6(__pyx_t_3);
        if (unlikely(!__pyx_t_4)) {
          PyObject* exc_type = PyErr_Occurred();
          if (exc_type) {
            if (likely(__Pyx_PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear();
            else __PYX_ERR(0, 40, __pyx_L5_error)
          }
          break;
        }
        __Pyx_GOTREF(__pyx_t_4);
      }
      __Pyx_XDECREF_SET(__pyx_7genexpr__pyx_v_n, __pyx_t_4);
      __pyx_t_4 = 0;
      __pyx_t_4 = __Pyx_PyObject_GetAttrStr(__pyx_7genexpr__pyx_v_n, __pyx_n_s_edge_num); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 40, __pyx_L5_error)
      __Pyx_GOTREF(__pyx_t_4);
      if (unlikely(PyDict_SetItem(__pyx_t_1, (PyObject*)__pyx_t_4, (PyObject*)__pyx_7genexpr__pyx_v_n))) __PYX_ERR(0, 40, __pyx_L5_error)
      __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
    }
    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
    __Pyx_XDECREF(__pyx_7genexpr__pyx_v_n); __pyx_7genexpr__pyx_v_n = 0;
    goto __pyx_L8_exit_scope;
    __pyx_L5_error:;
    __Pyx_XDECREF(__pyx_7genexpr__pyx_v_n); __pyx_7genexpr__pyx_v_n = 0;
    goto __pyx_L1_error;
    __pyx_L8_exit_scope:;
  } /* exit inner scope */
  __pyx_v_node_lookup = ((PyObject*)__pyx_t_1);
  __pyx_t_1 = 0;
 041: 
 042:     # mutation operations against TreeNode is expensive as every append or
 043:     # remove triggers a call to invalidate caches, which requires a traversal
 044:     # to find the root (and do other stuff). so let's monkey patch the method
 045:     # to force a noop
+046:     for node in sktree.traverse(include_self=True):
  __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_sktree, __pyx_n_s_traverse); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 46, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __pyx_t_3 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 46, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
  if (PyDict_SetItem(__pyx_t_3, __pyx_n_s_include_self, Py_True) < 0) __PYX_ERR(0, 46, __pyx_L1_error)
  __pyx_t_4 = __Pyx_PyObject_Call(__pyx_t_1, __pyx_empty_tuple, __pyx_t_3); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 46, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
  if (likely(PyList_CheckExact(__pyx_t_4)) || PyTuple_CheckExact(__pyx_t_4)) {
    __pyx_t_3 = __pyx_t_4; __Pyx_INCREF(__pyx_t_3); __pyx_t_5 = 0;
    __pyx_t_6 = NULL;
  } else {
    __pyx_t_5 = -1; __pyx_t_3 = PyObject_GetIter(__pyx_t_4); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 46, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_3);
    __pyx_t_6 = Py_TYPE(__pyx_t_3)->tp_iternext; if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 46, __pyx_L1_error)
  }
  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
  for (;;) {
    if (likely(!__pyx_t_6)) {
      if (likely(PyList_CheckExact(__pyx_t_3))) {
        if (__pyx_t_5 >= PyList_GET_SIZE(__pyx_t_3)) break;
        #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS
        __pyx_t_4 = PyList_GET_ITEM(__pyx_t_3, __pyx_t_5); __Pyx_INCREF(__pyx_t_4); __pyx_t_5++; if (unlikely(0 < 0)) __PYX_ERR(0, 46, __pyx_L1_error)
        #else
        __pyx_t_4 = PySequence_ITEM(__pyx_t_3, __pyx_t_5); __pyx_t_5++; if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 46, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_4);
        #endif
      } else {
        if (__pyx_t_5 >= PyTuple_GET_SIZE(__pyx_t_3)) break;
        #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS
        __pyx_t_4 = PyTuple_GET_ITEM(__pyx_t_3, __pyx_t_5); __Pyx_INCREF(__pyx_t_4); __pyx_t_5++; if (unlikely(0 < 0)) __PYX_ERR(0, 46, __pyx_L1_error)
        #else
        __pyx_t_4 = PySequence_ITEM(__pyx_t_3, __pyx_t_5); __pyx_t_5++; if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 46, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_4);
        #endif
      }
    } else {
      __pyx_t_4 = __pyx_t_6(__pyx_t_3);
      if (unlikely(!__pyx_t_4)) {
        PyObject* exc_type = PyErr_Occurred();
        if (exc_type) {
          if (likely(__Pyx_PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear();
          else __PYX_ERR(0, 46, __pyx_L1_error)
        }
        break;
      }
      __Pyx_GOTREF(__pyx_t_4);
    }
    __Pyx_XDECREF_SET(__pyx_v_node, __pyx_t_4);
    __pyx_t_4 = 0;
/* … */
  }
  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+047:         node.invalidate_caches = noop
    __Pyx_GetModuleGlobalName(__pyx_t_4, __pyx_n_s_noop); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 47, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_4);
    if (__Pyx_PyObject_SetAttrStr(__pyx_v_node, __pyx_n_s_invalidate_caches, __pyx_t_4) < 0) __PYX_ERR(0, 47, __pyx_L1_error)
    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
 048: 
 049:     # we are only setup to handle a single placement per fragment, so pull 
 050:     # deduplicated following guidance from Prof. Siavash Mirarab. We sort so
 051:     # "better" has a smaller index value
 052:     # fragment -> group the rows by the fragment, fragment order doesn't matter
 053:     # like_weight_ratio -> our first selection criteria, higher is better
 054:     # pendant_length -> our second selection criteria, lower is better
+055:     placements = placements.sort_values(['fragment', 'like_weight_ratio',
  __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_v_placements, __pyx_n_s_sort_values); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 55, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
  __pyx_t_4 = PyList_New(3); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 55, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  __Pyx_INCREF(__pyx_n_s_fragment);
  __Pyx_GIVEREF(__pyx_n_s_fragment);
  PyList_SET_ITEM(__pyx_t_4, 0, __pyx_n_s_fragment);
  __Pyx_INCREF(__pyx_n_s_like_weight_ratio);
  __Pyx_GIVEREF(__pyx_n_s_like_weight_ratio);
  PyList_SET_ITEM(__pyx_t_4, 1, __pyx_n_s_like_weight_ratio);
  __Pyx_INCREF(__pyx_n_s_pendant_length);
  __Pyx_GIVEREF(__pyx_n_s_pendant_length);
  PyList_SET_ITEM(__pyx_t_4, 2, __pyx_n_s_pendant_length);
  __pyx_t_1 = PyTuple_New(1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 55, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __Pyx_GIVEREF(__pyx_t_4);
  PyTuple_SET_ITEM(__pyx_t_1, 0, __pyx_t_4);
  __pyx_t_4 = 0;
/* … */
  __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_1, __pyx_t_4); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 55, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
  __Pyx_DECREF_SET(__pyx_v_placements, __pyx_t_2);
  __pyx_t_2 = 0;
 056:                                          'pendant_length'],
+057:                                         ascending=[True, False, True])
  __pyx_t_4 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 57, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  __pyx_t_2 = PyList_New(3); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 57, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __Pyx_INCREF(Py_True);
  __Pyx_GIVEREF(Py_True);
  PyList_SET_ITEM(__pyx_t_2, 0, Py_True);
  __Pyx_INCREF(Py_False);
  __Pyx_GIVEREF(Py_False);
  PyList_SET_ITEM(__pyx_t_2, 1, Py_False);
  __Pyx_INCREF(Py_True);
  __Pyx_GIVEREF(Py_True);
  PyList_SET_ITEM(__pyx_t_2, 2, Py_True);
  if (PyDict_SetItem(__pyx_t_4, __pyx_n_s_ascending, __pyx_t_2) < 0) __PYX_ERR(0, 57, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 058: 
 059:     # take the first non-duplicated row per fragment. because of the sort, this
 060:     # is assured to be the highest weight ratio, and the smallest pendant 
 061:     # length. Ties are handled arbitrarily. 
+062:     placements = placements[~placements['fragment'].duplicated()]
  __pyx_t_4 = __Pyx_PyObject_Dict_GetItem(__pyx_v_placements, __pyx_n_s_fragment); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 62, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_t_4, __pyx_n_s_duplicated); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 62, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
  __pyx_t_4 = NULL;
  if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_1))) {
    __pyx_t_4 = PyMethod_GET_SELF(__pyx_t_1);
    if (likely(__pyx_t_4)) {
      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_1);
      __Pyx_INCREF(__pyx_t_4);
      __Pyx_INCREF(function);
      __Pyx_DECREF_SET(__pyx_t_1, function);
    }
  }
  __pyx_t_2 = (__pyx_t_4) ? __Pyx_PyObject_CallOneArg(__pyx_t_1, __pyx_t_4) : __Pyx_PyObject_CallNoArg(__pyx_t_1);
  __Pyx_XDECREF(__pyx_t_4); __pyx_t_4 = 0;
  if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 62, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  __pyx_t_1 = PyNumber_Invert(__pyx_t_2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 62, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __pyx_t_2 = __Pyx_PyObject_GetItem(__pyx_v_placements, __pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 62, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  __Pyx_DECREF_SET(__pyx_v_placements, __pyx_t_2);
  __pyx_t_2 = 0;
 063: 
+064:     if insert_type == 'multifurcating':
  __pyx_t_7 = (__Pyx_PyString_Equals(__pyx_v_insert_type, __pyx_n_s_multifurcating, Py_EQ)); if (unlikely(__pyx_t_7 < 0)) __PYX_ERR(0, 64, __pyx_L1_error)
  if (__pyx_t_7) {
/* … */
    goto __pyx_L11;
  }
+065:         placements = placements.sort_values(['edge_num', 'pendant_length'])
    __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_placements, __pyx_n_s_sort_values); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 65, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_1);
    __pyx_t_4 = PyList_New(2); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 65, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_4);
    __Pyx_INCREF(__pyx_n_s_edge_num);
    __Pyx_GIVEREF(__pyx_n_s_edge_num);
    PyList_SET_ITEM(__pyx_t_4, 0, __pyx_n_s_edge_num);
    __Pyx_INCREF(__pyx_n_s_pendant_length);
    __Pyx_GIVEREF(__pyx_n_s_pendant_length);
    PyList_SET_ITEM(__pyx_t_4, 1, __pyx_n_s_pendant_length);
    __pyx_t_3 = NULL;
    if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_1))) {
      __pyx_t_3 = PyMethod_GET_SELF(__pyx_t_1);
      if (likely(__pyx_t_3)) {
        PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_1);
        __Pyx_INCREF(__pyx_t_3);
        __Pyx_INCREF(function);
        __Pyx_DECREF_SET(__pyx_t_1, function);
      }
    }
    __pyx_t_2 = (__pyx_t_3) ? __Pyx_PyObject_Call2Args(__pyx_t_1, __pyx_t_3, __pyx_t_4) : __Pyx_PyObject_CallOneArg(__pyx_t_1, __pyx_t_4);
    __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0;
    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
    if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 65, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_2);
    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
    __Pyx_DECREF_SET(__pyx_v_placements, __pyx_t_2);
    __pyx_t_2 = 0;
+066:     elif insert_type == 'fully_resolved':
  __pyx_t_7 = (__Pyx_PyString_Equals(__pyx_v_insert_type, __pyx_n_s_fully_resolved, Py_EQ)); if (unlikely(__pyx_t_7 < 0)) __PYX_ERR(0, 66, __pyx_L1_error)
  if (likely(__pyx_t_7)) {
/* … */
    goto __pyx_L11;
  }
+067:         placements = placements.sort_values(['edge_num', 'distal_length'],
    __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_placements, __pyx_n_s_sort_values); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 67, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_2);
    __pyx_t_1 = PyList_New(2); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 67, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_1);
    __Pyx_INCREF(__pyx_n_s_edge_num);
    __Pyx_GIVEREF(__pyx_n_s_edge_num);
    PyList_SET_ITEM(__pyx_t_1, 0, __pyx_n_s_edge_num);
    __Pyx_INCREF(__pyx_n_s_distal_length);
    __Pyx_GIVEREF(__pyx_n_s_distal_length);
    PyList_SET_ITEM(__pyx_t_1, 1, __pyx_n_s_distal_length);
    __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 67, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_4);
    __Pyx_GIVEREF(__pyx_t_1);
    PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_1);
    __pyx_t_1 = 0;
/* … */
    __pyx_t_3 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_4, __pyx_t_1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 67, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_3);
    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
    __Pyx_DECREF_SET(__pyx_v_placements, __pyx_t_3);
    __pyx_t_3 = 0;
+068:                                             ascending=[True, False])
    __pyx_t_1 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 68, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_1);
    __pyx_t_3 = PyList_New(2); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 68, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_3);
    __Pyx_INCREF(Py_True);
    __Pyx_GIVEREF(Py_True);
    PyList_SET_ITEM(__pyx_t_3, 0, Py_True);
    __Pyx_INCREF(Py_False);
    __Pyx_GIVEREF(Py_False);
    PyList_SET_ITEM(__pyx_t_3, 1, Py_False);
    if (PyDict_SetItem(__pyx_t_1, __pyx_n_s_ascending, __pyx_t_3) < 0) __PYX_ERR(0, 68, __pyx_L1_error)
    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
 069:     else:
+070:         raise ValueError()
  /*else*/ {
    __pyx_t_3 = __Pyx_PyObject_CallNoArg(__pyx_builtin_ValueError); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 70, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_3);
    __Pyx_Raise(__pyx_t_3, 0, 0, 0);
    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
    __PYX_ERR(0, 70, __pyx_L1_error)
  }
  __pyx_L11:;
 071: 
 072: 
+073:     placements['node'] = placements.apply(_preallocate_fragment, axis=1)
  __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_v_placements, __pyx_n_s_apply); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 73, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
  __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_preallocate_fragment); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 73, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 73, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_4);
  __Pyx_GIVEREF(__pyx_t_1);
  PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_1);
  __pyx_t_1 = 0;
  __pyx_t_1 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 73, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  if (PyDict_SetItem(__pyx_t_1, __pyx_n_s_axis, __pyx_int_1) < 0) __PYX_ERR(0, 73, __pyx_L1_error)
  __pyx_t_2 = __Pyx_PyObject_Call(__pyx_t_3, __pyx_t_4, __pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 73, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
  __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  if (unlikely(PyObject_SetItem(__pyx_v_placements, __pyx_n_s_node, __pyx_t_2) < 0)) __PYX_ERR(0, 73, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
 074: 
+075:     if insert_type == 'fully_resolved':
  __pyx_t_7 = (__Pyx_PyString_Equals(__pyx_v_insert_type, __pyx_n_s_fully_resolved, Py_EQ)); if (unlikely(__pyx_t_7 < 0)) __PYX_ERR(0, 75, __pyx_L1_error)
  if (__pyx_t_7) {
/* … */
  }
+076:         placements['parent'] = placements.apply(_preallocate_empty, axis=1)
    __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_placements, __pyx_n_s_apply); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 76, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_2);
    __Pyx_GetModuleGlobalName(__pyx_t_1, __pyx_n_s_preallocate_empty); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 76, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_1);
    __pyx_t_4 = PyTuple_New(1); if (unlikely(!__pyx_t_4)) __PYX_ERR(0, 76, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_4);
    __Pyx_GIVEREF(__pyx_t_1);
    PyTuple_SET_ITEM(__pyx_t_4, 0, __pyx_t_1);
    __pyx_t_1 = 0;
    __pyx_t_1 = __Pyx_PyDict_NewPresized(1); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 76, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_1);
    if (PyDict_SetItem(__pyx_t_1, __pyx_n_s_axis, __pyx_int_1) < 0) __PYX_ERR(0, 76, __pyx_L1_error)
    __pyx_t_3 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_4, __pyx_t_1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 76, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_3);
    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
    __Pyx_DECREF(__pyx_t_4); __pyx_t_4 = 0;
    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
    if (unlikely(PyObject_SetItem(__pyx_v_placements, __pyx_n_s_parent, __pyx_t_3) < 0)) __PYX_ERR(0, 76, __pyx_L1_error)
    __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
 077: 
+078:     return placements, sktree, node_lookup
  __Pyx_XDECREF(__pyx_r);
  __pyx_t_3 = PyTuple_New(3); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 78, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
  __Pyx_INCREF(__pyx_v_placements);
  __Pyx_GIVEREF(__pyx_v_placements);
  PyTuple_SET_ITEM(__pyx_t_3, 0, __pyx_v_placements);
  __Pyx_INCREF(__pyx_v_sktree);
  __Pyx_GIVEREF(__pyx_v_sktree);
  PyTuple_SET_ITEM(__pyx_t_3, 1, __pyx_v_sktree);
  __Pyx_INCREF(__pyx_v_node_lookup);
  __Pyx_GIVEREF(__pyx_v_node_lookup);
  PyTuple_SET_ITEM(__pyx_t_3, 2, __pyx_v_node_lookup);
  __pyx_r = __pyx_t_3;
  __pyx_t_3 = 0;
  goto __pyx_L0;
 079: 
 080: 
 081: # pd.DataFrame is not a resolved type so we cannot use it here for cython
+082: def insert_fully_resolved(object placements, BP bptree):
/* Python wrapper */
static PyObject *__pyx_pw_2bp_7_insert_9insert_fully_resolved(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds); /*proto*/
static char __pyx_doc_2bp_7_insert_8insert_fully_resolved[] = "Update the backbone, fully resolving edges with multiple queries\n\n    Parameters\n    ----------\n    placements : pd.DataFrame\n        jplace data represented as a DataFrame\n    bptree : bp.BP\n        An instance of a BP tree, this is expected to contain edge numbers\n        and correspond to the backbone for the jplace data\n\n    Returns\n    -------\n    skbio.TreeNode\n        A tree with the fragments placed\n    ";
static PyMethodDef __pyx_mdef_2bp_7_insert_9insert_fully_resolved = {"insert_fully_resolved", (PyCFunction)(void*)(PyCFunctionWithKeywords)__pyx_pw_2bp_7_insert_9insert_fully_resolved, METH_VARARGS|METH_KEYWORDS, __pyx_doc_2bp_7_insert_8insert_fully_resolved};
static PyObject *__pyx_pw_2bp_7_insert_9insert_fully_resolved(PyObject *__pyx_self, PyObject *__pyx_args, PyObject *__pyx_kwds) {
  PyObject *__pyx_v_placements = 0;
  struct __pyx_obj_2bp_3_bp_BP *__pyx_v_bptree = 0;
  PyObject *__pyx_r = 0;
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("insert_fully_resolved (wrapper)", 0);
  {
    static PyObject **__pyx_pyargnames[] = {&__pyx_n_s_placements,&__pyx_n_s_bptree,0};
    PyObject* values[2] = {0,0};
    if (unlikely(__pyx_kwds)) {
      Py_ssize_t kw_args;
      const Py_ssize_t pos_args = PyTuple_GET_SIZE(__pyx_args);
      switch (pos_args) {
        case  2: values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
        CYTHON_FALLTHROUGH;
        case  1: values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
        CYTHON_FALLTHROUGH;
        case  0: break;
        default: goto __pyx_L5_argtuple_error;
      }
      kw_args = PyDict_Size(__pyx_kwds);
      switch (pos_args) {
        case  0:
        if (likely((values[0] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_placements)) != 0)) kw_args--;
        else goto __pyx_L5_argtuple_error;
        CYTHON_FALLTHROUGH;
        case  1:
        if (likely((values[1] = __Pyx_PyDict_GetItemStr(__pyx_kwds, __pyx_n_s_bptree)) != 0)) kw_args--;
        else {
          __Pyx_RaiseArgtupleInvalid("insert_fully_resolved", 1, 2, 2, 1); __PYX_ERR(0, 82, __pyx_L3_error)
        }
      }
      if (unlikely(kw_args > 0)) {
        if (unlikely(__Pyx_ParseOptionalKeywords(__pyx_kwds, __pyx_pyargnames, 0, values, pos_args, "insert_fully_resolved") < 0)) __PYX_ERR(0, 82, __pyx_L3_error)
      }
    } else if (PyTuple_GET_SIZE(__pyx_args) != 2) {
      goto __pyx_L5_argtuple_error;
    } else {
      values[0] = PyTuple_GET_ITEM(__pyx_args, 0);
      values[1] = PyTuple_GET_ITEM(__pyx_args, 1);
    }
    __pyx_v_placements = values[0];
    __pyx_v_bptree = ((struct __pyx_obj_2bp_3_bp_BP *)values[1]);
  }
  goto __pyx_L4_argument_unpacking_done;
  __pyx_L5_argtuple_error:;
  __Pyx_RaiseArgtupleInvalid("insert_fully_resolved", 1, 2, 2, PyTuple_GET_SIZE(__pyx_args)); __PYX_ERR(0, 82, __pyx_L3_error)
  __pyx_L3_error:;
  __Pyx_AddTraceback("bp._insert.insert_fully_resolved", __pyx_clineno, __pyx_lineno, __pyx_filename);
  __Pyx_RefNannyFinishContext();
  return NULL;
  __pyx_L4_argument_unpacking_done:;
  if (unlikely(!__Pyx_ArgTypeTest(((PyObject *)__pyx_v_bptree), __pyx_ptype_2bp_3_bp_BP, 1, "bptree", 0))) __PYX_ERR(0, 82, __pyx_L1_error)
  __pyx_r = __pyx_pf_2bp_7_insert_8insert_fully_resolved(__pyx_self, __pyx_v_placements, __pyx_v_bptree);
  int __pyx_lineno = 0;
  const char *__pyx_filename = NULL;
  int __pyx_clineno = 0;

  /* function exit code */
  goto __pyx_L0;
  __pyx_L1_error:;
  __pyx_r = NULL;
  __pyx_L0:;
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}

static PyObject *__pyx_pf_2bp_7_insert_8insert_fully_resolved(CYTHON_UNUSED PyObject *__pyx_self, PyObject *__pyx_v_placements, struct __pyx_obj_2bp_3_bp_BP *__pyx_v_bptree) {
  PyObject *__pyx_v_sktree = NULL;
  PyObject *__pyx_v_node_lookup = NULL;
  PyObject *__pyx_v_edge = NULL;
  PyObject *__pyx_v_edge_grp = NULL;
  PyObject *__pyx_v_existing_node = NULL;
  PyObject *__pyx_v_current_parent = NULL;
  PyObject *__pyx_v_existing_length = NULL;
  CYTHON_UNUSED PyObject *__pyx_v__ = NULL;
  PyObject *__pyx_v_fragment = NULL;
  PyObject *__pyx_v_distal_length = NULL;
  PyObject *__pyx_v_fragment_node = NULL;
  PyObject *__pyx_v_fragment_parent = NULL;
  PyObject *__pyx_r = NULL;
  __Pyx_RefNannyDeclarations
  __Pyx_RefNannySetupContext("insert_fully_resolved", 0);
  __Pyx_INCREF(__pyx_v_placements);
/* … */
  /* function exit code */
  __pyx_L1_error:;
  __Pyx_XDECREF(__pyx_t_1);
  __Pyx_XDECREF(__pyx_t_2);
  __Pyx_XDECREF(__pyx_t_3);
  __Pyx_XDECREF(__pyx_t_5);
  __Pyx_XDECREF(__pyx_t_6);
  __Pyx_XDECREF(__pyx_t_12);
  __Pyx_AddTraceback("bp._insert.insert_fully_resolved", __pyx_clineno, __pyx_lineno, __pyx_filename);
  __pyx_r = NULL;
  __pyx_L0:;
  __Pyx_XDECREF(__pyx_v_sktree);
  __Pyx_XDECREF(__pyx_v_node_lookup);
  __Pyx_XDECREF(__pyx_v_edge);
  __Pyx_XDECREF(__pyx_v_edge_grp);
  __Pyx_XDECREF(__pyx_v_existing_node);
  __Pyx_XDECREF(__pyx_v_current_parent);
  __Pyx_XDECREF(__pyx_v_existing_length);
  __Pyx_XDECREF(__pyx_v__);
  __Pyx_XDECREF(__pyx_v_fragment);
  __Pyx_XDECREF(__pyx_v_distal_length);
  __Pyx_XDECREF(__pyx_v_fragment_node);
  __Pyx_XDECREF(__pyx_v_fragment_parent);
  __Pyx_XDECREF(__pyx_v_placements);
  __Pyx_XGIVEREF(__pyx_r);
  __Pyx_RefNannyFinishContext();
  return __pyx_r;
}
/* … */
  __pyx_tuple__34 = PyTuple_Pack(14, __pyx_n_s_placements, __pyx_n_s_bptree, __pyx_n_s_sktree, __pyx_n_s_node_lookup, __pyx_n_s_edge, __pyx_n_s_edge_grp, __pyx_n_s_existing_node, __pyx_n_s_current_parent, __pyx_n_s_existing_length, __pyx_n_s__33, __pyx_n_s_fragment, __pyx_n_s_distal_length, __pyx_n_s_fragment_node, __pyx_n_s_fragment_parent); if (unlikely(!__pyx_tuple__34)) __PYX_ERR(0, 82, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_tuple__34);
  __Pyx_GIVEREF(__pyx_tuple__34);
/* … */
  __pyx_t_2 = PyCFunction_NewEx(&__pyx_mdef_2bp_7_insert_9insert_fully_resolved, NULL, __pyx_n_s_bp__insert); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 82, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  if (PyDict_SetItem(__pyx_d, __pyx_n_s_insert_fully_resolved, __pyx_t_2) < 0) __PYX_ERR(0, 82, __pyx_L1_error)
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  __pyx_codeobj__35 = (PyObject*)__Pyx_PyCode_New(2, 0, 14, 0, CO_OPTIMIZED|CO_NEWLOCALS, __pyx_empty_bytes, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_tuple__34, __pyx_empty_tuple, __pyx_empty_tuple, __pyx_kp_s_bp__insert_pyx, __pyx_n_s_insert_fully_resolved, 82, __pyx_empty_bytes); if (unlikely(!__pyx_codeobj__35)) __PYX_ERR(0, 82, __pyx_L1_error)
 083:     """Update the backbone, fully resolving edges with multiple queries
 084: 
 085:     Parameters
 086:     ----------
 087:     placements : pd.DataFrame
 088:         jplace data represented as a DataFrame
 089:     bptree : bp.BP
 090:         An instance of a BP tree, this is expected to contain edge numbers
 091:         and correspond to the backbone for the jplace data
 092: 
 093:     Returns
 094:     -------
 095:     skbio.TreeNode
 096:         A tree with the fragments placed
 097:     """
 098:     # TODO: profile, type and re-profile
+099:     placements, sktree, node_lookup = \
  __Pyx_DECREF_SET(__pyx_v_placements, __pyx_t_2);
  __pyx_t_2 = 0;
  __pyx_v_sktree = __pyx_t_5;
  __pyx_t_5 = 0;
  __pyx_v_node_lookup = __pyx_t_3;
  __pyx_t_3 = 0;
+100:         _insert_setup(placements, bptree, 'fully_resolved')
  __Pyx_GetModuleGlobalName(__pyx_t_2, __pyx_n_s_insert_setup); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 100, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_2);
  __pyx_t_3 = NULL;
  __pyx_t_4 = 0;
  if (CYTHON_UNPACK_METHODS && unlikely(PyMethod_Check(__pyx_t_2))) {
    __pyx_t_3 = PyMethod_GET_SELF(__pyx_t_2);
    if (likely(__pyx_t_3)) {
      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2);
      __Pyx_INCREF(__pyx_t_3);
      __Pyx_INCREF(function);
      __Pyx_DECREF_SET(__pyx_t_2, function);
      __pyx_t_4 = 1;
    }
  }
  #if CYTHON_FAST_PYCALL
  if (PyFunction_Check(__pyx_t_2)) {
    PyObject *__pyx_temp[4] = {__pyx_t_3, __pyx_v_placements, ((PyObject *)__pyx_v_bptree), __pyx_n_s_fully_resolved};
    __pyx_t_1 = __Pyx_PyFunction_FastCall(__pyx_t_2, __pyx_temp+1-__pyx_t_4, 3+__pyx_t_4); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 100, __pyx_L1_error)
    __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0;
    __Pyx_GOTREF(__pyx_t_1);
  } else
  #endif
  #if CYTHON_FAST_PYCCALL
  if (__Pyx_PyFastCFunction_Check(__pyx_t_2)) {
    PyObject *__pyx_temp[4] = {__pyx_t_3, __pyx_v_placements, ((PyObject *)__pyx_v_bptree), __pyx_n_s_fully_resolved};
    __pyx_t_1 = __Pyx_PyCFunction_FastCall(__pyx_t_2, __pyx_temp+1-__pyx_t_4, 3+__pyx_t_4); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 100, __pyx_L1_error)
    __Pyx_XDECREF(__pyx_t_3); __pyx_t_3 = 0;
    __Pyx_GOTREF(__pyx_t_1);
  } else
  #endif
  {
    __pyx_t_5 = PyTuple_New(3+__pyx_t_4); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 100, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_5);
    if (__pyx_t_3) {
      __Pyx_GIVEREF(__pyx_t_3); PyTuple_SET_ITEM(__pyx_t_5, 0, __pyx_t_3); __pyx_t_3 = NULL;
    }
    __Pyx_INCREF(__pyx_v_placements);
    __Pyx_GIVEREF(__pyx_v_placements);
    PyTuple_SET_ITEM(__pyx_t_5, 0+__pyx_t_4, __pyx_v_placements);
    __Pyx_INCREF(((PyObject *)__pyx_v_bptree));
    __Pyx_GIVEREF(((PyObject *)__pyx_v_bptree));
    PyTuple_SET_ITEM(__pyx_t_5, 1+__pyx_t_4, ((PyObject *)__pyx_v_bptree));
    __Pyx_INCREF(__pyx_n_s_fully_resolved);
    __Pyx_GIVEREF(__pyx_n_s_fully_resolved);
    PyTuple_SET_ITEM(__pyx_t_5, 2+__pyx_t_4, __pyx_n_s_fully_resolved);
    __pyx_t_1 = __Pyx_PyObject_Call(__pyx_t_2, __pyx_t_5, NULL); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 100, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_1);
    __Pyx_DECREF(__pyx_t_5); __pyx_t_5 = 0;
  }
  __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
  if ((likely(PyTuple_CheckExact(__pyx_t_1))) || (PyList_CheckExact(__pyx_t_1))) {
    PyObject* sequence = __pyx_t_1;
    Py_ssize_t size = __Pyx_PySequence_SIZE(sequence);
    if (unlikely(size != 3)) {
      if (size > 3) __Pyx_RaiseTooManyValuesError(3);
      else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size);
      __PYX_ERR(0, 99, __pyx_L1_error)
    }
    #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS
    if (likely(PyTuple_CheckExact(sequence))) {
      __pyx_t_2 = PyTuple_GET_ITEM(sequence, 0); 
      __pyx_t_5 = PyTuple_GET_ITEM(sequence, 1); 
      __pyx_t_3 = PyTuple_GET_ITEM(sequence, 2); 
    } else {
      __pyx_t_2 = PyList_GET_ITEM(sequence, 0); 
      __pyx_t_5 = PyList_GET_ITEM(sequence, 1); 
      __pyx_t_3 = PyList_GET_ITEM(sequence, 2); 
    }
    __Pyx_INCREF(__pyx_t_2);
    __Pyx_INCREF(__pyx_t_5);
    __Pyx_INCREF(__pyx_t_3);
    #else
    __pyx_t_2 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 99, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_2);
    __pyx_t_5 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 99, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_5);
    __pyx_t_3 = PySequence_ITEM(sequence, 2); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 99, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_3);
    #endif
    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  } else {
    Py_ssize_t index = -1;
    __pyx_t_6 = PyObject_GetIter(__pyx_t_1); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 99, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_6);
    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
    __pyx_t_7 = Py_TYPE(__pyx_t_6)->tp_iternext;
    index = 0; __pyx_t_2 = __pyx_t_7(__pyx_t_6); if (unlikely(!__pyx_t_2)) goto __pyx_L3_unpacking_failed;
    __Pyx_GOTREF(__pyx_t_2);
    index = 1; __pyx_t_5 = __pyx_t_7(__pyx_t_6); if (unlikely(!__pyx_t_5)) goto __pyx_L3_unpacking_failed;
    __Pyx_GOTREF(__pyx_t_5);
    index = 2; __pyx_t_3 = __pyx_t_7(__pyx_t_6); if (unlikely(!__pyx_t_3)) goto __pyx_L3_unpacking_failed;
    __Pyx_GOTREF(__pyx_t_3);
    if (__Pyx_IternextUnpackEndCheck(__pyx_t_7(__pyx_t_6), 3) < 0) __PYX_ERR(0, 99, __pyx_L1_error)
    __pyx_t_7 = NULL;
    __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
    goto __pyx_L4_unpacking_done;
    __pyx_L3_unpacking_failed:;
    __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
    __pyx_t_7 = NULL;
    if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index);
    __PYX_ERR(0, 99, __pyx_L1_error)
    __pyx_L4_unpacking_done:;
  }
 101: 
+102:     for edge, edge_grp in placements.groupby('edge_num'):
  __pyx_t_3 = __Pyx_PyObject_GetAttrStr(__pyx_v_placements, __pyx_n_s_groupby); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 102, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_3);
  __pyx_t_5 = NULL;
  if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_3))) {
    __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_3);
    if (likely(__pyx_t_5)) {
      PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_3);
      __Pyx_INCREF(__pyx_t_5);
      __Pyx_INCREF(function);
      __Pyx_DECREF_SET(__pyx_t_3, function);
    }
  }
  __pyx_t_1 = (__pyx_t_5) ? __Pyx_PyObject_Call2Args(__pyx_t_3, __pyx_t_5, __pyx_n_s_edge_num) : __Pyx_PyObject_CallOneArg(__pyx_t_3, __pyx_n_s_edge_num);
  __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
  if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 102, __pyx_L1_error)
  __Pyx_GOTREF(__pyx_t_1);
  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
  if (likely(PyList_CheckExact(__pyx_t_1)) || PyTuple_CheckExact(__pyx_t_1)) {
    __pyx_t_3 = __pyx_t_1; __Pyx_INCREF(__pyx_t_3); __pyx_t_8 = 0;
    __pyx_t_9 = NULL;
  } else {
    __pyx_t_8 = -1; __pyx_t_3 = PyObject_GetIter(__pyx_t_1); if (unlikely(!__pyx_t_3)) __PYX_ERR(0, 102, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_3);
    __pyx_t_9 = Py_TYPE(__pyx_t_3)->tp_iternext; if (unlikely(!__pyx_t_9)) __PYX_ERR(0, 102, __pyx_L1_error)
  }
  __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
  for (;;) {
    if (likely(!__pyx_t_9)) {
      if (likely(PyList_CheckExact(__pyx_t_3))) {
        if (__pyx_t_8 >= PyList_GET_SIZE(__pyx_t_3)) break;
        #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS
        __pyx_t_1 = PyList_GET_ITEM(__pyx_t_3, __pyx_t_8); __Pyx_INCREF(__pyx_t_1); __pyx_t_8++; if (unlikely(0 < 0)) __PYX_ERR(0, 102, __pyx_L1_error)
        #else
        __pyx_t_1 = PySequence_ITEM(__pyx_t_3, __pyx_t_8); __pyx_t_8++; if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 102, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_1);
        #endif
      } else {
        if (__pyx_t_8 >= PyTuple_GET_SIZE(__pyx_t_3)) break;
        #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS
        __pyx_t_1 = PyTuple_GET_ITEM(__pyx_t_3, __pyx_t_8); __Pyx_INCREF(__pyx_t_1); __pyx_t_8++; if (unlikely(0 < 0)) __PYX_ERR(0, 102, __pyx_L1_error)
        #else
        __pyx_t_1 = PySequence_ITEM(__pyx_t_3, __pyx_t_8); __pyx_t_8++; if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 102, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_1);
        #endif
      }
    } else {
      __pyx_t_1 = __pyx_t_9(__pyx_t_3);
      if (unlikely(!__pyx_t_1)) {
        PyObject* exc_type = PyErr_Occurred();
        if (exc_type) {
          if (likely(__Pyx_PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear();
          else __PYX_ERR(0, 102, __pyx_L1_error)
        }
        break;
      }
      __Pyx_GOTREF(__pyx_t_1);
    }
    if ((likely(PyTuple_CheckExact(__pyx_t_1))) || (PyList_CheckExact(__pyx_t_1))) {
      PyObject* sequence = __pyx_t_1;
      Py_ssize_t size = __Pyx_PySequence_SIZE(sequence);
      if (unlikely(size != 2)) {
        if (size > 2) __Pyx_RaiseTooManyValuesError(2);
        else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size);
        __PYX_ERR(0, 102, __pyx_L1_error)
      }
      #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS
      if (likely(PyTuple_CheckExact(sequence))) {
        __pyx_t_5 = PyTuple_GET_ITEM(sequence, 0); 
        __pyx_t_2 = PyTuple_GET_ITEM(sequence, 1); 
      } else {
        __pyx_t_5 = PyList_GET_ITEM(sequence, 0); 
        __pyx_t_2 = PyList_GET_ITEM(sequence, 1); 
      }
      __Pyx_INCREF(__pyx_t_5);
      __Pyx_INCREF(__pyx_t_2);
      #else
      __pyx_t_5 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 102, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_5);
      __pyx_t_2 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 102, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_2);
      #endif
      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
    } else {
      Py_ssize_t index = -1;
      __pyx_t_6 = PyObject_GetIter(__pyx_t_1); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 102, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_6);
      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
      __pyx_t_7 = Py_TYPE(__pyx_t_6)->tp_iternext;
      index = 0; __pyx_t_5 = __pyx_t_7(__pyx_t_6); if (unlikely(!__pyx_t_5)) goto __pyx_L7_unpacking_failed;
      __Pyx_GOTREF(__pyx_t_5);
      index = 1; __pyx_t_2 = __pyx_t_7(__pyx_t_6); if (unlikely(!__pyx_t_2)) goto __pyx_L7_unpacking_failed;
      __Pyx_GOTREF(__pyx_t_2);
      if (__Pyx_IternextUnpackEndCheck(__pyx_t_7(__pyx_t_6), 2) < 0) __PYX_ERR(0, 102, __pyx_L1_error)
      __pyx_t_7 = NULL;
      __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
      goto __pyx_L8_unpacking_done;
      __pyx_L7_unpacking_failed:;
      __Pyx_DECREF(__pyx_t_6); __pyx_t_6 = 0;
      __pyx_t_7 = NULL;
      if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index);
      __PYX_ERR(0, 102, __pyx_L1_error)
      __pyx_L8_unpacking_done:;
    }
    __Pyx_XDECREF_SET(__pyx_v_edge, __pyx_t_5);
    __pyx_t_5 = 0;
    __Pyx_XDECREF_SET(__pyx_v_edge_grp, __pyx_t_2);
    __pyx_t_2 = 0;
/* … */
  }
  __Pyx_DECREF(__pyx_t_3); __pyx_t_3 = 0;
+103:         existing_node = node_lookup[edge]
    __pyx_t_1 = __Pyx_PyObject_GetItem(__pyx_v_node_lookup, __pyx_v_edge); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 103, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_1);
    __Pyx_XDECREF_SET(__pyx_v_existing_node, __pyx_t_1);
    __pyx_t_1 = 0;
+104:         current_parent = existing_node.parent
    __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_existing_node, __pyx_n_s_parent); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 104, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_1);
    __Pyx_XDECREF_SET(__pyx_v_current_parent, __pyx_t_1);
    __pyx_t_1 = 0;
 105: 
 106:         # break the edge
+107:         current_parent.remove(existing_node)
    __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_current_parent, __pyx_n_s_remove); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 107, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_2);
    __pyx_t_5 = NULL;
    if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_2))) {
      __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_2);
      if (likely(__pyx_t_5)) {
        PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2);
        __Pyx_INCREF(__pyx_t_5);
        __Pyx_INCREF(function);
        __Pyx_DECREF_SET(__pyx_t_2, function);
      }
    }
    __pyx_t_1 = (__pyx_t_5) ? __Pyx_PyObject_Call2Args(__pyx_t_2, __pyx_t_5, __pyx_v_existing_node) : __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_v_existing_node);
    __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
    if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 107, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_1);
    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+108:         existing_node.parent = None
    if (__Pyx_PyObject_SetAttrStr(__pyx_v_existing_node, __pyx_n_s_parent, Py_None) < 0) __PYX_ERR(0, 108, __pyx_L1_error)
+109:         existing_length = existing_node.length
    __pyx_t_1 = __Pyx_PyObject_GetAttrStr(__pyx_v_existing_node, __pyx_n_s_length); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 109, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_1);
    __Pyx_XDECREF_SET(__pyx_v_existing_length, __pyx_t_1);
    __pyx_t_1 = 0;
 110: 
+111:         for _, fragment in edge_grp.iterrows():
    __pyx_t_2 = __Pyx_PyObject_GetAttrStr(__pyx_v_edge_grp, __pyx_n_s_iterrows); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 111, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_2);
    __pyx_t_5 = NULL;
    if (CYTHON_UNPACK_METHODS && likely(PyMethod_Check(__pyx_t_2))) {
      __pyx_t_5 = PyMethod_GET_SELF(__pyx_t_2);
      if (likely(__pyx_t_5)) {
        PyObject* function = PyMethod_GET_FUNCTION(__pyx_t_2);
        __Pyx_INCREF(__pyx_t_5);
        __Pyx_INCREF(function);
        __Pyx_DECREF_SET(__pyx_t_2, function);
      }
    }
    __pyx_t_1 = (__pyx_t_5) ? __Pyx_PyObject_CallOneArg(__pyx_t_2, __pyx_t_5) : __Pyx_PyObject_CallNoArg(__pyx_t_2);
    __Pyx_XDECREF(__pyx_t_5); __pyx_t_5 = 0;
    if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 111, __pyx_L1_error)
    __Pyx_GOTREF(__pyx_t_1);
    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
    if (likely(PyList_CheckExact(__pyx_t_1)) || PyTuple_CheckExact(__pyx_t_1)) {
      __pyx_t_2 = __pyx_t_1; __Pyx_INCREF(__pyx_t_2); __pyx_t_10 = 0;
      __pyx_t_11 = NULL;
    } else {
      __pyx_t_10 = -1; __pyx_t_2 = PyObject_GetIter(__pyx_t_1); if (unlikely(!__pyx_t_2)) __PYX_ERR(0, 111, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_2);
      __pyx_t_11 = Py_TYPE(__pyx_t_2)->tp_iternext; if (unlikely(!__pyx_t_11)) __PYX_ERR(0, 111, __pyx_L1_error)
    }
    __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
    for (;;) {
      if (likely(!__pyx_t_11)) {
        if (likely(PyList_CheckExact(__pyx_t_2))) {
          if (__pyx_t_10 >= PyList_GET_SIZE(__pyx_t_2)) break;
          #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS
          __pyx_t_1 = PyList_GET_ITEM(__pyx_t_2, __pyx_t_10); __Pyx_INCREF(__pyx_t_1); __pyx_t_10++; if (unlikely(0 < 0)) __PYX_ERR(0, 111, __pyx_L1_error)
          #else
          __pyx_t_1 = PySequence_ITEM(__pyx_t_2, __pyx_t_10); __pyx_t_10++; if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 111, __pyx_L1_error)
          __Pyx_GOTREF(__pyx_t_1);
          #endif
        } else {
          if (__pyx_t_10 >= PyTuple_GET_SIZE(__pyx_t_2)) break;
          #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS
          __pyx_t_1 = PyTuple_GET_ITEM(__pyx_t_2, __pyx_t_10); __Pyx_INCREF(__pyx_t_1); __pyx_t_10++; if (unlikely(0 < 0)) __PYX_ERR(0, 111, __pyx_L1_error)
          #else
          __pyx_t_1 = PySequence_ITEM(__pyx_t_2, __pyx_t_10); __pyx_t_10++; if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 111, __pyx_L1_error)
          __Pyx_GOTREF(__pyx_t_1);
          #endif
        }
      } else {
        __pyx_t_1 = __pyx_t_11(__pyx_t_2);
        if (unlikely(!__pyx_t_1)) {
          PyObject* exc_type = PyErr_Occurred();
          if (exc_type) {
            if (likely(__Pyx_PyErr_GivenExceptionMatches(exc_type, PyExc_StopIteration))) PyErr_Clear();
            else __PYX_ERR(0, 111, __pyx_L1_error)
          }
          break;
        }
        __Pyx_GOTREF(__pyx_t_1);
      }
      if ((likely(PyTuple_CheckExact(__pyx_t_1))) || (PyList_CheckExact(__pyx_t_1))) {
        PyObject* sequence = __pyx_t_1;
        Py_ssize_t size = __Pyx_PySequence_SIZE(sequence);
        if (unlikely(size != 2)) {
          if (size > 2) __Pyx_RaiseTooManyValuesError(2);
          else if (size >= 0) __Pyx_RaiseNeedMoreValuesError(size);
          __PYX_ERR(0, 111, __pyx_L1_error)
        }
        #if CYTHON_ASSUME_SAFE_MACROS && !CYTHON_AVOID_BORROWED_REFS
        if (likely(PyTuple_CheckExact(sequence))) {
          __pyx_t_5 = PyTuple_GET_ITEM(sequence, 0); 
          __pyx_t_6 = PyTuple_GET_ITEM(sequence, 1); 
        } else {
          __pyx_t_5 = PyList_GET_ITEM(sequence, 0); 
          __pyx_t_6 = PyList_GET_ITEM(sequence, 1); 
        }
        __Pyx_INCREF(__pyx_t_5);
        __Pyx_INCREF(__pyx_t_6);
        #else
        __pyx_t_5 = PySequence_ITEM(sequence, 0); if (unlikely(!__pyx_t_5)) __PYX_ERR(0, 111, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_5);
        __pyx_t_6 = PySequence_ITEM(sequence, 1); if (unlikely(!__pyx_t_6)) __PYX_ERR(0, 111, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_6);
        #endif
        __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
      } else {
        Py_ssize_t index = -1;
        __pyx_t_12 = PyObject_GetIter(__pyx_t_1); if (unlikely(!__pyx_t_12)) __PYX_ERR(0, 111, __pyx_L1_error)
        __Pyx_GOTREF(__pyx_t_12);
        __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
        __pyx_t_7 = Py_TYPE(__pyx_t_12)->tp_iternext;
        index = 0; __pyx_t_5 = __pyx_t_7(__pyx_t_12); if (unlikely(!__pyx_t_5)) goto __pyx_L11_unpacking_failed;
        __Pyx_GOTREF(__pyx_t_5);
        index = 1; __pyx_t_6 = __pyx_t_7(__pyx_t_12); if (unlikely(!__pyx_t_6)) goto __pyx_L11_unpacking_failed;
        __Pyx_GOTREF(__pyx_t_6);
        if (__Pyx_IternextUnpackEndCheck(__pyx_t_7(__pyx_t_12), 2) < 0) __PYX_ERR(0, 111, __pyx_L1_error)
        __pyx_t_7 = NULL;
        __Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0;
        goto __pyx_L12_unpacking_done;
        __pyx_L11_unpacking_failed:;
        __Pyx_DECREF(__pyx_t_12); __pyx_t_12 = 0;
        __pyx_t_7 = NULL;
        if (__Pyx_IterFinish() == 0) __Pyx_RaiseNeedMoreValuesError(index);
        __PYX_ERR(0, 111, __pyx_L1_error)
        __pyx_L12_unpacking_done:;
      }
      __Pyx_XDECREF_SET(__pyx_v__, __pyx_t_5);
      __pyx_t_5 = 0;
      __Pyx_XDECREF_SET(__pyx_v_fragment, __pyx_t_6);
      __pyx_t_6 = 0;
/* … */
    }
    __Pyx_DECREF(__pyx_t_2); __pyx_t_2 = 0;
+112:             distal_length = fragment['distal_length']
      __pyx_t_1 = __Pyx_PyObject_Dict_GetItem(__pyx_v_fragment, __pyx_n_s_distal_length); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 112, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      __Pyx_XDECREF_SET(__pyx_v_distal_length, __pyx_t_1);
      __pyx_t_1 = 0;
+113:             fragment_node = fragment['node']
      __pyx_t_1 = __Pyx_PyObject_Dict_GetItem(__pyx_v_fragment, __pyx_n_s_node); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 113, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      __Pyx_XDECREF_SET(__pyx_v_fragment_node, __pyx_t_1);
      __pyx_t_1 = 0;
+114:             fragment_parent = fragment['parent']
      __pyx_t_1 = __Pyx_PyObject_Dict_GetItem(__pyx_v_fragment, __pyx_n_s_parent); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 114, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      __Pyx_XDECREF_SET(__pyx_v_fragment_parent, __pyx_t_1);
      __pyx_t_1 = 0;
 115: 
 116:             # update branch lengths
+117:             fragment_parent.length = existing_length - distal_length
      __pyx_t_1 = PyNumber_Subtract(__pyx_v_existing_length, __pyx_v_distal_length); if (unlikely(!__pyx_t_1)) __PYX_ERR(0, 117, __pyx_L1_error)
      __Pyx_GOTREF(__pyx_t_1);
      if (__Pyx_PyObject_SetAttrStr(__pyx_v_fragment_parent, __pyx_n_s_length, __pyx_t_1) < 0) __PYX_ERR(0, 117, __pyx_L1_error)
      __Pyx_DECREF(__pyx_t_1); __pyx_t_1 = 0;
+118:             existing_length = distal_length
      __Pyx_INCREF(__pyx_v_distal_length);
      __Pyx_DECREF_SET(__pyx_v_existing_length, __pyx_v_distal_length);
 119: 
 120:             # attach the nodes
+121:             fragment_parent.append(fragment_node)
      __pyx_t_13 = __Pyx_PyObject_Append(__pyx_v_fragment_parent, __pyx_v_fragment_node); if (unlikely(__pyx_t_13 == ((int)-1))) __PYX_ERR(0, 121, __pyx_L1_error)
+122:             current_parent.append(fragment_parent)
      __pyx_t_13 = __Pyx_PyObject_Append(__pyx_v_current_parent, __pyx_v_fragment_parent); if (unlikely(__pyx_t_13 == ((int)-1))) __PYX_ERR(0, 122, __pyx_L1_error)
 123: 
 124:             # update
+125:             current_parent = fragment_parent
      __Pyx_INCREF(__pyx_v_fragment_parent);
      __Pyx_DECREF_SET(__pyx_v_current_parent, __pyx_v_fragment_parent);
 126: 
+127:         existing_node.length = existing_length
    if (__Pyx_PyObject_SetAttrStr(__pyx_v_existing_node, __pyx_n_s_length, __pyx_v_existing_length) < 0) __PYX_ERR(0, 127, __pyx_L1_error)
+128:         current_parent.append(existing_node)
    __pyx_t_13 = __Pyx_PyObject_Append(__pyx_v_current_parent, __pyx_v_existing_node); if (unlikely(__pyx_t_13 == ((int)-1))) __PYX_ERR(0, 128, __pyx_L1_error)
+129:         existing_node.length = distal_length
    if (unlikely(!__pyx_v_distal_length)) { __Pyx_RaiseUnboundLocalError("distal_length"); __PYX_ERR(0, 129, __pyx_L1_error) }
    if (__Pyx_PyObject_SetAttrStr(__pyx_v_existing_node, __pyx_n_s_length, __pyx_v_distal_length) < 0) __PYX_ERR(0, 129, __pyx_L1_error)
 130: 
+131:     return sktree
  __Pyx_XDECREF(__pyx_r);
  __Pyx_INCREF(__pyx_v_sktree);
  __pyx_r = __pyx_v_sktree;
  goto __pyx_L0;