BUG: solve_ivp fails to solve Possion-Nernst-Planck Equation but ode15s of MATLAB does

Describe your issue.
I am trying to solve pne dimensional Possion-Nernst-Planck (PNP) Equation with solve_ivp, it looks like

Here, $\psi$ is electrode potential, $c_i$ are concentrations of ions.
Here is an example in matlab.
matlab_cc.txt
The function current calculate the currenr density of a reaction. The result will be used to calculate the Robin condition of left boundary. It's a little complex, but jr should decrease during the integration of equation. And ode15s can reach the end of the time span I want to calculate.
I also write a Python version and use solve_ivp to solve this equation.
mkm_electro4.py.txt
However, the current density jr decrease slowly. If you print the t variable in ions_conc_equ,  you will find the time step is very small, t can only reach 8.0e-7. I tried BDF, LSODA solver, but both of them can not reach the end of the time span I want to calculate.
In short, PNP equation is a stiff equation, but BDF or LSODA solver fail to solve it.
Reproducing Code Example
See the attachment

Error message
See the attachment

SciPy/NumPy/Python version information
1.7.1 1.21.2 sys.version_info(major=3, minor=8, micro=10, releaselevel='final', serial=0)

It is not clear to me that you have demonstrated a shortcoming in SciPy's integrate module. However, it seems likely that the Python code you provided is not an accurate translation of the Matlab script you also attached. I would encourage you to start again and be more careful as you work your way through the translation. In particular, try to avoid adding in unnecessary functions and classes until you are sure the code you have written works. You may want to consider the below Python snippet as a new starting point:
import numpy as np
from scipy.constants import N_A, e, epsilon_0, h, k
from scipy.integrate import solve_ivp
from scipy.sparse import spdiags
from scipy.sparse.linalg import spsolve

def ion_conc_equ(t, y):
    return

T = 298.15
a_M = 3.5e-10
N_M = 1 / np.sqrt(3) / a_M**2
potential = 0.5 * e / k / T

delta_RP = 1.5 * 2.75e-10
epsilon_RP = 6
epsilon_s = 78.5
D = 1e-9
n0 = N_A
Ld = 1e-4
lambda_d = np.sqrt(epsilon_s * epsilon_0 * k * T / e**2 / n0)
tref = lambda_d * Ld / D

Length_limit = Ld / lambda_d
x_cal_1 = np.linspace(0, 1, 70)
x_cal_2 = np.linspace(1.1, 10, 50)
x_cal_3 = np.linspace(11, 100, 50)
x_cal_4 = np.linspace(110, Length_limit, 20)
xmesh = np.hstack((x_cal_1, x_cal_2, x_cal_3, x_cal_4))

nx = xmesh.size
harray = np.diff(xmesh)
diag0 = np.hstack(
    (
        -1 / harray[0] - lambda_d * epsilon_RP / epsilon_s / delta_RP,
        -2 / harray[1:-1] / harray[:-2],
        -2 / harray[-1] / harray[-2],
    )
)
diagp1 = np.hstack((1 / harray[0], 2 / harray[1:-1] / (harray[1:-1] + harray[:-2])))
diagm1 = np.hstack(
    (
        2 / harray[0] / (harray[0] + harray[1]),
        2 / harray[1:-1] / (harray[1:-1] + harray[2:]),
    )
)
A = np.column_stack((np.pad(diagm1, (0, 1)), diag0, np.pad(diagp1, (1, 0))))
# https://stackoverflow.com/a/31900194/10640534
pot_M = spdiags(A.T, [-1, 0, 1], nx - 1, nx - 1).tocsc()
pot_b = np.zeros(nx - 1)
pot_b[0] = -potential * lambda_d * epsilon_RP / delta_RP / epsilon_s

y0 = np.ones((5, nx))
y0[-1, :-1] = spsolve(pot_M, pot_b)
y0[-1, -1] = 0

t_end = 5
tmesh = np.linspace(0.1, t_end, 101)
tmesh = np.hstack(([1e-10, 1e-8, 1e-6, 1e-4, 1e-2], tmesh))
t_cal = tmesh / tref

sol = solve_ivp(
    ion_conc_equ, [t_cal[0], t_cal[-1]], y0.flatten(), method="LSODA", t_eval=t_cal
)

It should reproduce the Matlab script until line 74, which is the ode15s call. For example, you could start by making sure that arrays calculated up until there in both languages are identical. Then, you could translate the system's right-hand side into the ion_conc_equ function. Once you are sure that the Python code you have written is an accurate translation of the whole Matlab script, then you can assess if the ODE solvers provided by SciPy are behaving well or not.

Thank you for your kindly reply. I complement the python version script basing on your script. It seems that the problem is the jac_sparsity parameter for BDF solver or lband/uband parameter for LSODA solver.
For BDF solver, if I leave jac_sparsity None, the solver can slowly converge to ode15s result. But if I set jac_sparsity, the result never converges (I mean reach the end of time span). For LSODA, the problem is similar, if I set lband/uband, the result also cannot converge.  It's weird that ode15s cannot converge too if I set its JPattern parameter.  But ode15s still converge much faster that solve_ivp if I don't set the Jacobian matrix.
`import numpy as np
#from scipy.constants import N_A, e, epsilon_0, h, k
from scipy.integrate import solve_ivp
from scipy.sparse import diags, spdiags, kron
from scipy.sparse.linalg import spsolve
e = 1.60217663e-19
k = 1.380649e-23
N_A = 6.0221408e+23
h = 6.626e-34
epsilon_0 = 8.8541878128e-12
def current(NHm,NAm,NBm,Phim):
global T, potential, N_M
e_0 = e
k_B = k
E_0 = 0.6
G_00 = 0.4e_0
eta_HP = (potential - Phim)k_BT/e_0 - E_0
jr = e_0N_Mk_BT/hnp.exp(-G_00/k_B/T)(NBmnp.exp(e_0eta_HP/2/k_B/T) - NAmNHmnp.exp(-e_0*eta_HP/2/k_B/T))
print(jr)
return jr
def ion_conc_equ(t, y):
global nx, harray, Ld, lambda_d, pot_M
ionsD    = np.array([1.0, 1.0, 1.0, 1.0])
ionsZ    = np.array([1.0, -1.0, 0.0, 0.0])
ionsNumDen = np.array([1.0, 1.0, 1.0, 1.0])
dydt = np.zeros((5, nx))
data = np.reshape(y, (5, nx), order='F')
ion_c_array = data[0:4, :]
pot_x = data[4, :]

NHm = data[0, 0]
NAm = data[2, 0]
NBm = data[3, 0]
Phim = data[4, 0]

jr = current(NHm,NAm,NBm,Phim)
jr = jr * Ld/e/n0/D
flux = np.array([-jr, 0, -jr, jr])

dphidx = (pot_x[1] - pot_x[0])/harray[0]
c = 0.5*(ion_c_array[:, 0] + ion_c_array[:, 1])
dcdx = (ion_c_array[:, 1] - ion_c_array[:, 0])/harray[0]
FL = ionsD * ionsZ * c * dphidx + ionsD * dcdx
FL = FL* Ld / lambda_d
dydt[0:4, 0] = (FL - flux)/(0.5*harray[0])

for i in range(1, nx-1):
    dphidx = (pot_x[i+1] - pot_x[i])/harray[i]
    c = 0.5*(ion_c_array[:, i] + ion_c_array[:, i+1])
    dcdx = (ion_c_array[:,i+1] - ion_c_array[:, i])/harray[i]
    FR = ionsD * ionsZ * c * dphidx + ionsD * dcdx
    FR = FR * Ld / lambda_d
    dydt[0:4, i] = (FR - FL)/(0.5*(harray[i]+harray[i-1]))
    FL = FR

dydt[0:4, nx-1] = ion_c_array[:, nx-1] - ionsNumDen

ion_e_array = dydt[0, :] - dydt[1, :]
ion_e_array = -ion_e_array

pot_b = np.zeros((nx-1, ))
pot_b[0] = 0.25*(ion_e_array[0] + ion_e_array[1])*harray[0]
pot_b[1:] = ion_e_array[1:-1]
dydt[4, 0:-1] = spsolve(pot_M, pot_b)

kk = dydt.flatten(order='F')
#print(kk[122], kk[88], kk[76], kk[31])
#print(kk[9], kk[99], kk[104], kk[199])
#a = input("pause: ")
return kk

T = 298.15
a_M = 3.5e-10
N_M = 1 / np.sqrt(3) / a_M**2
potential = 0.5 * e / k / T
delta_RP = 1.5 * 2.75e-10
epsilon_RP = 6
epsilon_s = 78.5
D = 1e-9
n0 = N_A
Ld = 1e-4
lambda_d = np.sqrt(epsilon_s * epsilon_0 * k * T / e**2 / n0)
tref = lambda_d * Ld / D
Length_limit = Ld / lambda_d
x_cal_1 = np.linspace(0, 1, 70)
x_cal_2 = np.linspace(1.1, 10, 50)
x_cal_3 = np.linspace(11, 100, 50)
x_cal_4 = np.linspace(110, Length_limit, 20)
xmesh = np.hstack((x_cal_1, x_cal_2, x_cal_3, x_cal_4))
nx = xmesh.size
harray = np.diff(xmesh)
diag0 = np.hstack(
(
-1 / harray[0] - lambda_d * epsilon_RP / epsilon_s / delta_RP,
-2 / harray[1:-1] / harray[:-2],
-2 / harray[-1] / harray[-2],
)
)
diagp1 = np.hstack((1 / harray[0], 2 / harray[1:-1] / (harray[1:-1] + harray[:-2])))
diagm1 = np.hstack(
(
2 / harray[0] / (harray[0] + harray[1]),
2 / harray[1:-1] / (harray[1:-1] + harray[2:]),
)
)
A = np.column_stack((np.pad(diagm1, (0, 1)), diag0, np.pad(diagp1, (1, 0))))
https://stackoverflow.com/a/31900194/10640534
pot_M = spdiags(A.T, [-1, 0, 1], nx - 1, nx - 1).tocsc()
pot_b = np.zeros(nx - 1)
pot_b[0] = -potential * lambda_d * epsilon_RP / delta_RP / epsilon_s
y0 = np.ones((5, nx))
y0[-1, :-1] = spsolve(pot_M, pot_b)
y0[-1, -1] = 0
#y0[0, :] = np.sin(xmesh)
#y0[1, :] = np.cos(0.1*xmesh)
#y0[2, :] = np.sin(np.cos(xmesh+2))
#y0[3, :] = np.exp(np.sin(xmesh))
#y0[4, :] = np.exp(-np.cos(xmesh))
t_end = 5
tmesh = np.linspace(0.1, t_end, 101)
tmesh = np.hstack(([1e-10, 1e-8, 1e-6, 1e-4, 1e-2], tmesh))
t_cal = tmesh / tref
sol = solve_ivp(ion_conc_equ, [t_cal[0], t_cal[-1]], y0.flatten(order='F'), method="LSODA", t_eval=t_cal)
#jac_sparsity = kron(spdiags(np.ones((3, nx)), [-1, 0, 1], nx, nx), np.ones((5, 5)))
#jac_sparsity = None
#sol = solve_ivp(ion_conc_equ, [t_cal[0], t_cal[-1]], y0.flatten(order='F'), method="BDF", t_eval=t_cal, jac_sparsity=jac_sparsity)
`
Below is the matlab code
`% Constants
clear;
global e_0 k_B T h
e_0 = 1.60217663e-19; % [C] electron charge
k_B = 1.380649e-23; % [J K-1] Boltzmann constant
T = 298.15; % [K] absolute temperature
N_A = 6.0221408e+23; % [mol-1] Avogadro constant
h = 6.626e-34; % [J s] Planck constant
epsilon_0 = 8.8541878128e-12; % [F m-1] vacuum permittivity
% Electrode properties
global N_M potential
a_M = 3.5e-10; % [m] lattice constant of the electrode
N_M = (sqrt(3)*(a_M)^2)^(-1); % [m-2] areal number density of M(111)
potential = 0.5;
% Solution properties
global delta_RP epsilon_RP epsilon_s n0 D BIG BIG2
BIG = 1; % magnify n_A in the calculation to reduce calculation error
BIG2 = 1; % magnify n_B in the calculation to reduce calculation error
delta_RP = 1.52.75e-10; % [m] distance from the electrode to the HP
epsilon_RP = 6; % dielectric permittivity of the space between the electrode and the HP
epsilon_s = 78.5; % bulk dielectric permittivity of the water solvent medium
D = 1.00e-9; %[mA2/s] diffusion coefficient
n0 =1N_A; %[m^-3] number density of total cations (anions) in the solution bulk
% reference values
global Ld lambda
Ld = 100e-6; % [m] distance from the HP to the solution bulk
lambda = sqrt(epsilon_sepsilon_0k_BT/e_0^2/n0); % [m] Debye length
tref= lambdaLd/D; % [s] time reference
Ld = 1.0e-4;
Length_limit = Ld/lambda;
potential = potential * e_0/k_B/T;
x_cal_1 = linspace(0,1,70); % spatial coordinate of 1st layer
x_cal_2 = linspace(1.1,10,50); % spatial coordinate of 2nd layer
x_cal_3 = linspace(11,100,50); % spatial coordinate of 3rd layer
x_cal_4 = linspace(110,Length_limit,20); % spatial coordinate of 4th layer
xmesh = [x_cal_1, x_cal_2, x_cal_3,x_cal_4]; % assembled spatial coordinate
global nx harray pot_M
nx = length(xmesh);
harray = diff(xmesh);
diag0 =  zeros(nx-1, 1);
diagp1 = zeros(nx-2, 1);
diagm1 = zeros(nx-2, 1);
for i = 2:(nx-2)
diag0(i) = -2/(harray(i)harray(i-1));
diagp1(i) = 2/(harray(i)(harray(i) + harray(i-1)));
diagm1(i) = 2/(harray(i)(harray(i) + harray(i+1)));
end
diag0(1) = -(1/harray(1) + lambdaepsilon_RP/epsilon_s/delta_RP);
diag0(nx-1) = -2/(harray(nx-1)harray(nx-2));
diagp1(1) = 1/harray(1);
diagm1(1) = 2/(harray(1)(harray(1) + harray(2)));
A = zeros(nx-1,3);
A(1:(end-1),1) = diagm1;
A(:, 2) = diag0;
A(2:end, 3) = diagp1;
pot_M = spdiags(A, [-1, 0, 1], nx-1, nx-1);
pot_b = zeros(nx-1, 1);
pot_b(1) = -potentiallambdaepsilon_RP/(delta_RP*epsilon_s);
y0 = zeros(5, nx);
y0(1:4, :) = 1.0;
y0(5, 1:(end-1)) = pot_M \ pot_b;
% y0(1, :) = sin(xmesh);
% y0(2, :) = cos(0.1*xmesh);
% y0(3, :) = sin(cos(xmesh+2));
% y0(4, :) = exp(sin(xmesh));
% y0(5, :) = exp(-cos(xmesh));
y0 = y0(:);
t_end = 5; % [s]
tmesh = linspace(0.1,t_end,101);
tmesh = [1.0e-10, 1.0e-8, 1.0e-6, 1.0e-4, 1.0e-2, tmesh];
t_cal = tmesh/tref;
S = kron( spdiags(ones(nx,3),-1:1,nx,nx), ones(5,5));
options = odeset('RelTol',1e-6,'AbsTol',1e-9, 'JPattern', S);
options = odeset('RelTol',1e-6,'AbsTol',1e-9);
[t,y] = ode15s(@ion_conc_equ, t_cal, y0, options);
nt = length(t_cal);
NnH = zeros(nt, nx);
Nnn = zeros(nt, nx);
NnA = zeros(nt, nx);
NnB = zeros(nt, nx);
Pphi= zeros(nt, nx);
for i = 1:nt
sol = reshape(y(i, :), 5, nx);
NnH(i, :) = sol(1, :);
Nnn(i, :) = sol(2, :);
NnA(i, :) = sol(3, :);
NnB(i, :) = sol(4, :);
Pphi(i, :) = sol(5, :);
end
f2 = figure(2);
hold on;
for i = 1:100
if(mod(i, 10) == 1)
plot(xmesh*lambda/1e-6, NnA(i,:)*n0/N_A,'LineWidth',2) % 0.1 s
end
end
hold off;
function dydt = ion_conc_equ(t, y)
global nx Ld lambda e_0 n0 D harray pot_M
dydt = zeros(5, nx);
data = reshape(y, 5, nx);
ion_c_array = data(1:4, :);
pot_x = data(5,:);
NHm = data(1, 1);
NAm = data(3, 1);
NBm = data(4, 1);
Phim = data(5, 1);

jr = current(NHm,NAm,NBm,Phim);
jr = jr * Ld/e_0/n0/D;
flux = [-jr, 0, -jr, jr]';
ionsD = [1, 1, 1, 1]';
ionsZ = [1, -1, 0, 0]';
ionsNumDen = [1, 1, 1, 1]';

dphidx = (pot_x(2) - pot_x(1))/harray(1);
c = 0.5*(ion_c_array(:, 1) + ion_c_array(:, 2));
dcdx = (ion_c_array(:, 2) - ion_c_array(:, 1))/harray(1);
FL = ionsD .* ionsZ .* c * dphidx + ionsD.*dcdx;
FL = FL*Ld/lambda;
dydt(1:4, 1) = (FL - flux)/(0.5*harray(1));

for i = 2:(nx-1)
    dphidx = (pot_x(i+1) - pot_x(i))/harray(i);
    c = 0.5*(ion_c_array(:, i) + ion_c_array(:, i+1));
    dcdx = (ion_c_array(:,i+1) - ion_c_array(:, i))/harray(i);
    FR = ionsD .* ionsZ .* c .* dphidx + ionsD.*dcdx;
    FR = FR*Ld/lambda;
    dydt(1:4, i) = (FR - FL)/(0.5*(harray(i)+harray(i-1)));
    FL = FR;
end
dydt(1:4, nx) = ion_c_array(:, nx) - ionsNumDen;

ion_e_array = dydt(1, :) - dydt(2, :);
ion_e_array = -ion_e_array;

pot_b = zeros(nx-1, 1);
pot_b(1) = 0.25*(ion_e_array(1) + ion_e_array(2))*harray(1);
pot_b(2:end) = ion_e_array(2:end-1);
dydt(5, 1:(end-1)) = pot_M \ pot_b;

dydt = dydt(:);

%     disp([dydt(123), dydt(89), dydt(77), dydt(32)]);
%     disp([dydt(10), dydt(100), dydt(105), dydt(200)]);
%     pause;
end
function jr = current(NHm,NAm,NBm,Phim)
global T e_0 k_B h N_M potential
E_0 = 0.6; % [V] Equilibrium potential of the reaction at standard state
G_00 = 0.4e_0; % [J] Activation energy of the reaction at standard equilibrium state
eta_HP = (potential - Phim)k_BT/e_0 - E_0; % [V] overpotential
jr = e_0N_Mk_BT/hexp(-G_00/k_B/T). (NBm.exp (e_0eta_HP/2/k_B/T)-NAm.*NHm.exp(-e_0eta_HP/2/k_B/T)); % [A2 m-2] current density
disp(jr);
end
`
To make sure ion_conc_equ function in these two cases produce the same output, I initialisze $y_0$ with some sin or cos functions.  Python and matlab outputs are same before 7 or 8 decimal places.

I am not too sure about the Jacobian structure. If you manage to make it work in Matlab, I can help you translate it into Python.
Does the following work better than what you pasted above, or is it still too slow?
from time import perf_counter

import numpy as np
from scipy.constants import N_A, e, epsilon_0, h, k
from scipy.integrate import solve_ivp
from scipy.sparse import spdiags
from scipy.sparse.linalg import spsolve

def current(NHm, NAm, NBm, Phim, E_0=0.6, G_00=0.4 * e):
    eta_HP = (potential - Phim) * k * T / e - E_0
    return (
        (e * N_M * k * T / h)
        * np.exp(-G_00 / k / T)
        * (
            NBm * np.exp(e * eta_HP / 2 / k / T)
            - NAm * NHm * np.exp(-e * eta_HP / 2 / k / T)
        )
    )

def ion_conc_equ(t, y):
    print(t)
    dydt = np.zeros((5, nx))
    data = np.reshape(y, (5, nx), order="F")
    ion_c_array = data[:-1]
    pot_x = data[-1]

    NHm = data[0, 0]
    NAm = data[2, 0]
    NBm = data[3, 0]
    Phim = data[4, 0]

    jr = current(NHm, NAm, NBm, Phim)
    jr *= Ld / e / n0 / D
    flux = np.array([-jr, 0, -jr, jr])
    ionsD = np.array([1, 1, 1, 1])
    ionsZ = np.array([1, -1, 0, 0])
    ionsNumDen = np.array([1, 1, 1, 1])

    dphidx = (pot_x[1:] - pot_x[:-1]) / harray
    c = (ion_c_array[:, :-1] + ion_c_array[:, 1:]) / 2
    dcdx = (ion_c_array[:, 1:] - ion_c_array[:, :-1]) / harray

    # dphidx = (pot_x[1] - pot_x[0]) / harray[0]
    # c = (ion_c_array[:, 0] + ion_c_array[:, 1]) / 2
    # dcdx = (ion_c_array[:, 1] - ion_c_array[:, 0]) / harray[0]
    FL = (ionsD * ionsZ * c[:, 0] * dphidx[0] + ionsD * dcdx[:, 0]) * Ld / lambda_d
    dydt[:-1, 0] = (FL - flux) * 2 / harray[0]

    for i in range(1, nx - 1):
        # dphidx = (pot_x[i + 1] - pot_x[i]) / harray[i]
        # c = (ion_c_array[:, i] + ion_c_array[:, i + 1]) / 2
        # dcdx = (ion_c_array[:, i + 1] - ion_c_array[:, i]) / harray[i]
        FR = (ionsD * ionsZ * c[:, i] * dphidx[i] + ionsD * dcdx[:, i]) * Ld / lambda_d
        dydt[:-1, i] = (FR - FL) * 2 / (harray[i] + harray[i - 1])
        FL = FR

    dydt[:-1, -1] = ion_c_array[:, -1] - ionsNumDen

    ion_e_array = dydt[1] - dydt[0]

    pot_b = np.zeros(nx - 1)
    pot_b[0] = (ion_e_array[0] + ion_e_array[1]) * harray[0] / 4
    pot_b[1:] = ion_e_array[1:-1]
    dydt[-1, :-1] = spsolve(pot_M, pot_b)

    return dydt.flatten(order="F")

T = 298.15
a_M = 3.5e-10
N_M = 1 / np.sqrt(3) / a_M**2
potential = 0.5 * e / k / T

delta_RP = 1.5 * 2.75e-10
epsilon_RP = 6
epsilon_s = 78.5
D = 1e-9
n0 = N_A
Ld = 1e-4
lambda_d = np.sqrt(epsilon_s * epsilon_0 * k * T / e**2 / n0)
tref = lambda_d * Ld / D

Length_limit = Ld / lambda_d
x_cal_1 = np.linspace(0, 1, 70)
x_cal_2 = np.linspace(1.1, 10, 50)
x_cal_3 = np.linspace(11, 100, 50)
x_cal_4 = np.linspace(110, Length_limit, 20)
xmesh = np.hstack((x_cal_1, x_cal_2, x_cal_3, x_cal_4))

nx = xmesh.size
harray = np.diff(xmesh)
diag0 = np.hstack(
    (
        -1 / harray[0] - lambda_d * epsilon_RP / epsilon_s / delta_RP,
        -2 / harray[1:-1] / harray[:-2],
        -2 / harray[-1] / harray[-2],
    )
)
diagp1 = np.hstack((1 / harray[0], 2 / harray[1:-1] / (harray[1:-1] + harray[:-2])))
diagm1 = np.hstack(
    (
        2 / harray[0] / (harray[0] + harray[1]),
        2 / harray[1:-1] / (harray[1:-1] + harray[2:]),
    )
)
A = np.column_stack((np.pad(diagm1, (0, 1)), diag0, np.pad(diagp1, (1, 0))))
# https://stackoverflow.com/a/31900194/10640534
pot_M = spdiags(A.T, [-1, 0, 1], nx - 1, nx - 1).tocsc()
pot_b = np.zeros(nx - 1)
pot_b[0] = -potential * lambda_d * epsilon_RP / delta_RP / epsilon_s

y0 = np.ones((5, nx))
y0[-1, :-1] = spsolve(pot_M, pot_b)
y0[-1, -1] = 0

t_end = 5
tmesh = np.linspace(0.1, t_end, 101)
tmesh = np.hstack(([1e-10, 1e-8, 1e-6, 1e-4, 1e-2], tmesh))
t_cal = tmesh / tref

begin = perf_counter()

sol = solve_ivp(
    ion_conc_equ,
    [t_cal[0], t_cal[-1]],
    y0.flatten(order="F"),
    method="LSODA",
    t_eval=t_cal,
)

print(perf_counter() - begin)
print(sol.t, sol.y)

@Patol75 Thanks for your help. I think I know where I am wrong. In fact I write my code basing on a matlab function pdepe. This function converts parabolic and elliptic PDEs to ODEs and solve them by ode15s, If an elliptic PDE exists (for example Poisson equation here), the eqution becomes algebraic differential equation.  ODE15s can decouple the equations somehow (I don't know the details), so pdepe function can set a Jacobian pattern like

But I my function, because I solve the poisson equation manually with spsolve, the Jacobian is not sparse matrix anymore. So if I set Jacobian matrix with the form above, it will not work.


Fixing crosstool config file to build tensorflow on PowerPC architect…

…ures

Can one of the admins verify this patch?

@keveman could you take a look?

@damienmg Damien, can you take a look? I am not 100% sure about the syntax and semantics of that file.

LGTM

@tensorflow-jenkins test this please

@yifeif - I wanted to know if this change would be part of Tensorflow 0.10.0 release. It actually missed 0.10.0rc0 by just one day or even less than that. Request to kindly include this change in the next RC(if any) or final release of 0.10.0.


Add the logfire.instrument_mysql()

Fixes #310

@Kludex Could you please review the PR ?

We do want that, but I don't know if that needs to block this PR.

@Kludex @alexmojaki I will update this PR as this is not an urgent required changes

Hi @alexmojaki , resolved the comments. Could you please review ?

@alexmojaki Could you please review the changes ?

@Kludex please check this comment https://github.com/pydantic/logfire/pull/341#discussion_r1700471697
Do we need to remove those docstrings ?

Thanks @aditkumar72 🙏


fix: markup shown as tags from some browsers

Chromium notification shows raw HTML. This fixes that
context https://github.com/Aylur/ags/issues/480
Before:

After:

When the notification body is long, the limit  set on label via max_width_chars doesnt work,
The latest commit fixes this as well
After the commit

LGTM otherwise

Sweeet, let's merge it!

When the notification body is long, the limit set on label via max_width_chars doesnt work,
Use this command to test
notify-send -u critical "Build failed!" "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJfaWQiOiI2M2UzNDVlYTAwNmEwMjZhNjVkMzc0MzUiLCJyb2xlcyI6WyJTVVBFUkFETUlOIl0sImlhdCI6MTczMDcxODA5NywiZXhwIjoxNzYyMjU0MDk3LCJhdWQiOiJuZXN0aWZ5IiwiaXNzIjoibmVzdGlmeSIsInN1YiI6IjYzZTM0NWVhMDA2YTAyNmE2NWQzNzQzNSJ9.eY5c9AsXb0iFbjVtqI8jk1VMPSomjO3cHEa1HzZo1yY"

I will have a separate PR for this bug I encountered. Its kind of an edge case


add listfiles option

I would like to use Projekt such that I rarely have to view or edit a raw .fsproj.  But I need to know the current build order to make effective use of the movefile command.  At present this requires me to view the .fsproj, so I might as well move the items around by hand at that point.  This change adds a "listfiles" option which lists all the Included files in the project to the shell, thus providing the data I need to understand my current build order (without showing me the other content in the .fsproj).

@willryan thanks a lot! This is certainly a good addition. I will try it tomorrow.

Looks fine to me apart from the one comment I added.
Thanks @willryan

Thanks for the contribution!


decode number to interface{} as int64 rather than float64

I have a case where I need to decode into an interface{} as an int64, rather than float64.  Is there a way to request that?  Ideally it would be automatic - if the encoded value is a whole number, use int64, else use float64.
stdlib has decoder.UseNumber which is closer to what we need...

RegisterTypeDecoder for interface{} then check for WhatIsNext

Are there examples?  I want this to be as transparent as possible.
On Thu, Aug 10, 2017 at 9:56 PM, Tao Wen<EMAIL_ADDRESS>wrote:

RegisterTypeDecoder for interface{} then check for WhatIsNext
—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub
https://github.com/json-iterator/go/issues/145#issuecomment-321731990,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AFVgVE__I0sHU1vtu2rIrrJRoYed0Eybks5sW98HgaJpZM4O0JJF
.

func Test_unmarshal_empty_interface_as_int64(t *testing.T) {
	var obj interface{}
	RegisterTypeDecoderFunc("interface {}", func(ptr unsafe.Pointer, iter *Iterator) {
		switch iter.WhatIsNext() {
		case NumberValue:
			*(*interface{})(ptr) = iter.ReadInt64()
		default:
			*(*interface{})(ptr) = iter.Read()
		}
	})
	should := require.New(t)
	Unmarshal([]byte("100"), &obj)
	should.Equal(int64(100), obj)
	Unmarshal([]byte(`"hello"`), &obj)
	should.Equal("hello", obj)
}

Is there any way to tell if the next value looks like an int vs looks like
a float?
On Thu, Aug 10, 2017 at 11:16 PM, Tao Wen<EMAIL_ADDRESS>wrote:

func Test_unmarshal_empty_interface_as_int64(t *testing.T) {
var obj interface{}
RegisterTypeDecoderFunc("interface {}", func(ptr unsafe.Pointer, iter *Iterator) {
switch iter.WhatIsNext() {
case NumberValue:
*(*interface{})(ptr) = iter.ReadInt64()
default:
*(*interface{})(ptr) = iter.Read()
}
})
should := require.New(t)
Unmarshal([]byte("100"), &obj)
should.Equal(int64(100), obj)
Unmarshal([]byte("hello"), &obj)
should.Equal("hello", obj)
}
—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub
https://github.com/json-iterator/go/issues/145#issuecomment-321738628,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AFVgVM94U9C_sKjx6Ekn2Z5McOhgQB4Vks5sW_G3gaJpZM4O0JJF
.

var number json.Number
iter.ReadVal(&number)

then you check the number is int or float. event it is int, it might overflow int64 as well.

Would you be open to a PR that made that a config flag?  DecodeIntsToInt64 or somethign?

I added this:
func init() {
    decodeNumberAsInt64IfPossible := func(ptr unsafe.Pointer, iter *jsoniter.Iterator) {
        switch iter.WhatIsNext() {
        case jsoniter.NumberValue:
            var number json.Number
            iter.ReadVal(&number)
            i, err := strconv.ParseInt(string(number), 10, 64)
            if err == nil {
                *(*interface{})(ptr) = i
                return
            }
            f, err := strconv.ParseFloat(string(number), 64)
            if err == nil {
                *(*interface{})(ptr) = f
                return
            }
            // Not much we can do here.
        default:
            *(*interface{})(ptr) = iter.Read()
        }
    }
    jsoniter.RegisterTypeDecoderFunc("interface{}", decodeNumberAsInt64IfPossible)
}

I can tell it is being registered (throw in a panic).  but my callback is never called.  We are decoding into a []interface{} here, and I am getting a float64 out.
Am I doing something wrong?

"interface {}" not "interface{}"

Ahh, got it to kind of work.  Not sure I want to keep it, but it does work. :)  Thanks.

This doesn't seem to catch []interface {} - the inner value gets decoded as a float and my function is never called.

Or rather, this doesn't seem to call any further type decoder functions (recursive).

func Test_unmarshal_empty_interface_as_int64(t *testing.T) {
	var obj interface{}
	RegisterTypeDecoderFunc("interface {}", func(ptr unsafe.Pointer, iter *Iterator) {
		switch iter.WhatIsNext() {
		case NumberValue:
			*(*interface{})(ptr) = iter.ReadInt64()
		default:
			*(*interface{})(ptr) = iter.Read()
		}
	})
	should := require.New(t)
	Unmarshal([]byte("100"), &obj)
	should.Equal(int64(100), obj)
	Unmarshal([]byte(`"hello"`), &obj)
	should.Equal("hello", obj)
	var arr []interface{}
	Unmarshal([]byte("[100]"), &arr)
	should.Equal(int64(100), arr[0])
}

seems []interface{} is working properly. can you give me a failing test case?

I want to decode a JSON array of numbers into an interface{} and have it process array member  with my function.
JSON [ 100, 200, 300 ] => Go interface{}([]interface{ uint64(100), uint64(200), uint64(300) })
func Test_thockin(t *testing.T) {
    var obj interface{}
    RegisterTypeDecoderFunc("interface {}", func(ptr unsafe.Pointer, iter *Iterator) {
        switch iter.WhatIsNext() {
        case NumberValue:
            *(*interface{})(ptr) = iter.ReadInt64()
        default:
            *(*interface{})(ptr) = iter.Read()
        }
    })
    should := require.New(t)
    Unmarshal([]byte("[100]"), &obj)
    spew.Dump(obj)
    should.Equal([]int64{100}, obj)
}

iter.Read() does not recurse into decoder functions.

You have to copy & paste the implementation code of iter.Read() to your custom decoder, and change
	case ArrayValue:
		arr := []interface{}{}
		iter.ReadArrayCB(func(iter *Iterator) bool {
			arr = append(arr, iter.Read())
			return true
		})
		return arr

before reading into the element of array, there is no way to know it is a int or string. so it will be using []interface{}. For example, if the input is [], do we still use []int64 as the type?

I would expect that, of the target type is interface{}, and you need to
decode an array, you would decode to []interface{}, and recursively decode
each value in the array, using decoder funcs for interface{}, for each
element.
On Aug 21, 2017 6:56 PM, "Tao Wen"<EMAIL_ADDRESS>wrote:

You have to copy & paste the implementation code of iter.Read() to your
custom decoder, and change
case ArrayValue:
arr := []interface{}{}
iter.ReadArrayCB(func(iter *Iterator) bool {
arr = append(arr, iter.Read())
return true
})
return arr
before reading into the element of array, there is no way to know it is a
int or string. so it will be using []interface{}. For example, if the
input is [], do we still use []int64 as the type?
—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub
https://github.com/json-iterator/go/issues/145#issuecomment-323897637,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AFVgVM4NVeeRry_lLBkjkFcEGw_5Wc7Dks5sajUxgaJpZM4O0JJF
.

should be fixed now

Will try tonight!
On Aug 21, 2017 7:39 PM, "Tao Wen"<EMAIL_ADDRESS>wrote:

should be fixed now
—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub
https://github.com/json-iterator/go/issues/145#issuecomment-323903165,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AFVgVL4TBf74cOcQoqopo36MJCsMWbHTks5saj9UgaJpZM4O0JJF
.

Looking good so far!  Thanks.
On Mon, Aug 21, 2017 at 7:46 PM, Tim Hockin<EMAIL_ADDRESS>wrote:

Will try tonight!
On Aug 21, 2017 7:39 PM, "Tao Wen"<EMAIL_ADDRESS>wrote:

should be fixed now
—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub
https://github.com/json-iterator/go/issues/145#issuecomment-323903165,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/
AFVgVL4TBf74cOcQoqopo36MJCsMWbHTks5saj9UgaJpZM4O0JJF>

.

—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
https://github.com/json-iterator/go/issues/145#issuecomment-323904045,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AFVgVL9dQPQbTK_L-iok1OeIaoZeH8bSks5sakDtgaJpZM4O0JJF
.

My tests are green!  Now to lobby for switching...


metacontroller handling of dynamic apply for multi-value lists fails for service on same port

Metacontroller appears to fail to handle a service where two services (different names) use two protocols (TCP and UDP) on same port. knownMergeKey prioritises port over name and this results in 'duplicate errors' being thrown when apply occurs.
Not clear if switching name and port in priority list would cause other errors. Service appears to come up but it appears to cause metacontroller issues when revalidating state of environment.

hi @nycnewman could you elaborate a bit ? Are you writing you controller and experiencing some unexpected behavior ?

I'm asking my engineering team to get a better description but as I understand it, the team are using metacontroller to manager a K8s cluster. We deploy a vendor product that by default exposes two services on the same port under different names and using UDP and TCP. When metacontroller comes to compare the as-is against the definition, it doesn't handle arrays well and has a default sort mechanism (using knownMergeKeys) that prioritises port over name. The resulting diff is broken as metacontroller appears merge the two services into one entry. So service comes up but MC throws error later.

Names changed to protect the innocent
I0920 14:53:42.315370       1 controller.go:455] "Sync" parent_kind="testSystem" object="test-system"
I0920 14:53:42.437142       1 manage_children.go:218] "Reflect diff: a=observed, b=desired" diff="\u00a0\u00a0map[string]interface{}{
\u00a0\u00a0	"apiVersion": string("v1"),
\u00a0\u00a0	"kind":       string("Service"),
\u00a0\u00a0	"metadata":   map[string]interface{}{"annotations": map[string]interface{}{"metacontroller.k8s.io/last-applied-configuration": string({\"apiVersion\":\"v1\",\"kind\":\"Service\",\"metadata\":{\"labels\":{\"contr...)}, "creationTimestamp": string("2021-09-20T09:03:04Z"), "labels": map[string]interface{}{"controller-uid": string("4e103700-e8ee-4e85-a6a9-0fcdaff43e42")}, "managedFields": []interface{}{map[string]interface{}{"apiVersion": string("v1"), "fieldsType": string("FieldsV1"), "fieldsV1": map[string]interface{}{"f:metadata": map[string]interface{}{"f:annotations": map[string]interface{}{".": map[string]interface{}{}, "f:metacontroller.k8s.io/last-applied-configuration": map[string]interface{}{}}, "f:labels": map[string]interface{}{".": map[string]interface{}{}, "f:controller-uid": map[string]interface{}{}}, "f:ownerReferences": map[string]interface{}{".": map[string]interface{}{}, k:{\"uid\":\"4e103700-e8ee-4e85-a6a9-0fcdaff43e42\"}: map[string]interface{}{".": map[string]interface{}{}, "f:apiVersion": map[string]interface{}{}, "f:blockOwnerDeletion": map[string]interface{}{}, "f:controller": map[string]interface{}{}, ...}}}, "f:spec": map[string]interface{}{"f:clusterIP": map[string]interface{}{}, "f:ports": map[string]interface{}{".": map[string]interface{}{}, k:{\"port\":18300,\"protocol\":\"TCP\"}: map[string]interface{}{".": map[string]interface{}{}, "f:name": map[string]interface{}{}, "f:port": map[string]interface{}{}, "f:protocol": map[string]interface{}{}, ...}, k:{\"port\":18301,\"protocol\":\"TCP\"}: map[string]interface{}{".": map[string]interface{}{}, "f:name": map[string]interface{}{}, "f:port": map[string]interface{}{}, "f:protocol": map[string]interface{}{}, ...}, k:{\"port\":18301,\"protocol\":\"UDP\"}: map[string]interface{}{".": map[string]interface{}{}, "f:name": map[string]interface{}{}, "f:port": map[string]interface{}{}, "f:protocol": map[string]interface{}{}, ...}}, "f:selector": map[string]interface{}{".": map[string]interface{}{}, "f:app": map[string]interface{}{}}, "f:sessionAffinity": map[string]interface{}{}, ...}}, "manager": string("metacontroller"), ...}}, ...},
\u00a0\u00a0	"spec": map[string]interface{}{
\u00a0\u00a0		"clusterIP":  string("None"),
\u00a0\u00a0		"clusterIPs": []interface{}{string("None")},
\u00a0\u00a0		"ports": []interface{}{
\u00a0\u00a0			map[string]interface{}{"name": string("https-cluster-tcp-18300"), "port": int64(18300), "protocol": string("TCP"), "targetPort": int64(18300)},
\u00a0\u00a0			map[string]interface{}{
-\u00a0				"name":       string("https-cluster-tcp-18301"),
+\u00a0				"name":       string("cluster-udp-18301"),
\u00a0\u00a0				"port":       int64(18301),
-\u00a0				"protocol":   string("TCP"),
+\u00a0				"protocol":   string("UDP"),
\u00a0\u00a0				"targetPort": int64(18301),
\u00a0\u00a0			},
\u00a0\u00a0			map[string]interface{}{"name": string("cluster-udp-18301"), "port": int64(18301), "protocol": string("UDP"), "targetPort": int64(18301)},
\u00a0\u00a0		},
\u00a0\u00a0		"selector":        map[string]interface{}{"app": string("vendor-controller-pod")},
\u00a0\u00a0		"sessionAffinity": string("None"),
\u00a0\u00a0		"type":            string("ClusterIP"),
\u00a0\u00a0	},
\u00a0\u00a0	"status": map[string]interface{}{"loadBalancer": map[string]interface{}{}},
\u00a0\u00a0}
"
I0920 14:53:42.437187       1 manage_children.go:255] "Updating" parent="test-system" child="vendor/vendor-svc-controller" reason="Recreate update strategy selected"
I0920 14:53:42.467483       1 manage_children.go:218] "Reflect diff: a=observed, b=desired" diff="\u00a0\u00a0map[string]interface{}{
\u00a0\u00a0	"apiVersion": string("apps/v1"),
\u00a0\u00a0	"kind":       string("Deployment"),
\u00a0\u00a0	"metadata":   map[string]interface{}{"annotations": map[string]interface{}{"deployment.kubernetes.io/revision": string("1"), "metacontroller.k8s.io/last-applied-configuration": string({\"apiVersion\":\"apps/v1\",\"kind\":\"Deployment\",\"metadata\":{\"labels\"...)}, "creationTimestamp": string("2021-09-20T09:03:01Z"), "generation": int64(1), "labels": map[string]interface{}{"controller-uid": string("4e103700-e8ee-4e85-a6a9-0fcdaff43e42")}, ...},
\u00a0\u00a0	"spec": map[string]interface{}{
\u00a0\u00a0		... // 4 identical entries
\u00a0\u00a0		"selector": map[string]interface{}{"matchLabels": map[string]interface{}{"app": string("vendor-controller-pod")}},
\u00a0\u00a0		"strategy": map[string]interface{}{"rollingUpdate": map[string]interface{}{"maxSurge": int64(1), "maxUnavailable": int64(0)}, "type": string("RollingUpdate")},
\u00a0\u00a0		"template": map[string]interface{}{
\u00a0\u00a0			"metadata": map[string]interface{}{"creationTimestamp": nil, "labels": map[string]interface{}{"app": string("vendor-controller-pod")}},
\u00a0\u00a0			"spec": map[string]interface{}{
\u00a0\u00a0				"affinity": map[string]interface{}{"podAntiAffinity": map[string]interface{}{"preferredDuringSchedulingIgnoredDuringExecution": []interface{}{map[string]interface{}{"podAffinityTerm": map[string]interface{}{"labelSelector": map[string]interface{}{"matchExpressions": []interface{}{map[string]interface{}{"key": string("app"), "operator": string("In"), "values": []interface{}{string("vendor-controller-pod")}}}}, "topologyKey": string("kubernetes.io/hostname")}, "weight": int64(100)}}}},
\u00a0\u00a0				"containers": []interface{}{
\u00a0\u00a0					map[string]interface{}{
\u00a0\u00a0						... // 7 identical entries
\u00a0\u00a0						"terminationMessagePath":   string("/dev/termination-log"),
\u00a0\u00a0						"terminationMessagePolicy": string("File"),
\u00a0\u00a0						"volumeMounts": []interface{}{
\u00a0\u00a0							map[string]interface{}{
\u00a0\u00a0								"mountPath": string("/var/vendor"),
\u00a0\u00a0								"name":      string("nv-share"),
+\u00a0								"readOnly":  bool(false),
\u00a0\u00a0							},
\u00a0\u00a0							map[string]interface{}{"mountPath": string("/run/containerd/containerd.sock"), "name": string("runtime-sock"), "readOnly": bool(true)},
\u00a0\u00a0							map[string]interface{}{"mountPath": string("/host/proc"), "name": string("proc-vol"), "readOnly": bool(true)},
\u00a0\u00a0							... // 2 identical elements
\u00a0\u00a0						},
\u00a0\u00a0					},
\u00a0\u00a0				},
\u00a0\u00a0				"dnsPolicy":     string("ClusterFirst"),
\u00a0\u00a0				"restartPolicy": string("Always"),
\u00a0\u00a0				... // 4 identical entries
\u00a0\u00a0			},
\u00a0\u00a0		},
\u00a0\u00a0	},
\u00a0\u00a0	"status": map[string]interface{}{"availableReplicas": int64(3), "conditions": []interface{}{map[string]interface{}{"lastTransitionTime": string("2021-09-20T09:05:16Z"), "lastUpdateTime": string("2021-09-20T09:05:16Z"), "message": string("Deployment has minimum availability."), "reason": string("MinimumReplicasAvailable"), ...}, map[string]interface{}{"lastTransitionTime": string("2021-09-20T09:03:01Z"), "lastUpdateTime": string("2021-09-20T09:05:16Z"), "message": string(ReplicaSet \"vendor-controller-pod-54d8cd7444\" has successfull...), "reason": string("NewReplicaSetAvailable"), ...}}, "observedGeneration": int64(1), "readyReplicas": int64(3), ...},
\u00a0\u00a0}
"
I0920 14:53:42.467537       1 manage_children.go:255] "Updating" parent="test-system" child="vendor/vendor-controller-pod" reason="Recreate update strategy selected"
E0920 14:53:42.500208       1 controller.go:270] failed to sync testSystem "test-system": can't reconcile children for testSystem /test-system: Service "vendor-svc-controller" is invalid: [spec.ports[2].name: Duplicate value: "cluster-udp-18301", spec.ports[2]: Duplicate value: core.ServicePort{Name:"", Protocol:"UDP", AppProtocol:(*string)(nil), Port:18301, TargetPort:intstr.IntOrString{Type:0, IntVal:0, StrVal:""}, NodePort:0}]
I0920 14:53:42.514056       1 reflector.go:381] pkg/mod/k8s.io/client-go@v0.21.2/tools/cache/reflector.go:167: forcing resync

@nycnewman I do not get the whole context from logs, I would need to know what your controller wants to do, can you explain it ?
Also, which version of metacontroller are you using ? As those logs seems a bit buggy, I think I fixed them few versions ago in 2.0.x, can you update your version and then post logs? They should be much clearer

Please re-open with additional information


Add release note and changelog

Codecov Report

Merging #121 into release-0.2 will increase coverage by 0.01%.
The diff coverage is n/a.

@@                Coverage Diff                @@
##             release-0.2     #121      +/-   ##
=================================================
+ Coverage           39.6%   39.62%   +0.01%
+ Complexity           600      599       -1
=================================================
  Files                140      140
  Lines               4421     4422       +1
  Branches             321      324       +3
=================================================
+ Hits                1751     1752       +1
- Misses              2536     2542       +6
+ Partials             134      128       -6

Impacted Files
Coverage Δ
Complexity Δ

...rc/main/java/com/webank/wecross/resource/Path.java
65.51% <0%> (-3.45%)
11% <0%> (-1%)

.../wecross/stub/jdchain/JDChainContractResource.java
0% <0%> (ø)
0% <0%> (ø)
:arrow_down:

...java/com/webank/wecross/peer/PeerInfoCallback.java
68.42% <0%> (+5.26%)
3% <0%> (ø)
:arrow_down:

.../java/com/webank/wecross/peer/PeerSeqCallback.java
68.42% <0%> (+5.26%)
3% <0%> (ø)
:arrow_down:

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 0665b16...b653f6d. Read the comment docs.


Remove templating utility

This is a clean-up PR to remove any templating-related utility from huggingface_hub.
These methods/objects have been added ~6 months and have never been promoted or documented anywhere. I think it's safe to delete them without prior notice. At that point, some models were served with TGI (most of them), others with transformers. Since TGI-served models have a /v1/chat/completion, we didn't and don't need to do client-side rendering. However, for transformers-backed models we had to implement client-side rendering to be on-par feature-wise.
Now that all conversational text-generation models in InferenceAPI are served with TGI (even when it's transformers behind the scenes), we don't use client-side templating at all. This is a clean-up PR to get read of the utilities altogether.
In theory, this is a breaking change. In practice I don't think we should care given the small-ish timeframe (a few versions) and that we never promoted them. Worth mentioning it in the release notes though.

Ahah, don't get too used to it :smile:


More granular config of op modes

Closes: #1518
Description

Default config for mode would look like ->

[mode]

[mode.clients]
enabled = true
refresh = true
misbehaviour = true

[mode.connections]
enabled = false

[mode.channels]
enabled = false

[mode.packets]
enabled = true
clear_interval = 100
clear_on_start = true
filter = false
tx_confirmation = true

strategy and clear_packets_interval options would be removed.
...

TODO (aside from acceptance criteria)

[x] Guide changes.
[x] Fix E2E tests.
[ ] Fix gm related stuff.

For contributor use:

[x] Added a changelog entry, using unclog.
[ ] If applicable: Unit tests written, added test to CI.
[x] Linked to Github issue with discussion and accepted design OR link to spec that describes this work.
[x] Updated relevant documentation (docs/) and code comments.
[ ] Re-reviewed Files changed in the Github PR explorer.

@greg-szabo we would appreciate your quick look here, at the gm related changes.

Looks good to me. The only thing missing is the gm Changelog update but I can deal with that separately in my own PR.

@hu55a1n1 I tried with a config that has:
[mode.packets]
# Whether or not to enable the packet workers. [Required]
enabled = true
# Parametrize the periodic packet clearing feature.
# Interval (in number of blocks) at which pending packets
# should be eagerly cleared. A value of '0' will disable
# periodic packet clearing. [Default: 100]
clear_interval = 10
# Whether or not to clear packets on start. [Default: false]
clear_on_start = true

all other modes disabled.
Create a channel, send some packets then start hermes. The packets are not cleared immediately. Also not cleared on the clear_interval.  If I send a packet after hermes start then everything is back to normal.
Didn't look yet at the code but I think it should be straight forward to fix.
Also  e2e  fails with this  config.

The packets are not cleared immediately. Also not cleared on the clear_interval.

Thanks for catching that @ancazamfir! I think this was a bug in the way packet workers were spawned. I just pushed a possible fix -> 4ec957b


move tire model from example to smarts model

Include tire model suggested in issue #1140. Move the tire_parameters.yaml from example folder to ~/smarts/core/models

 Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.Chuanzheng Wang seems not to be a GitHub user. You need a GitHub account to be able to sign the CLA. If you have already a GitHub account, please add the email address used for this commit to your account.You have signed the CLA already but the status is still pending? Let us recheck it.

I believe there is an out-of date hard-coded reference to this file in ./examples/tools/pybullet_linear_tire_example.py that should be updated. Please also make a note of the move of the file in the CHANGELOG.


Merge /doc/README.md with /doc/contributing/README.md

Hi team!
One of our goals in Ruby Together is of ongoing maintenance of the Bundler docs. To that end, I've already made a few modest changes to the /doc/contributing/README.md doc and of course, to the main Bundler README.
Part of these ongoing maintenance efforts is trying to cut down on places where we have duplicate content. Going through the files we have in /docs/, I realized that the /doc/README.md file and the /doc/contributing/README.md doc serve the same function: guidelines for onboarding potential contributors. The only minor differences between these two files are a link or two that's listed in the /doc/README.md that isn't present in the /doc/contributing/README.md.
(A thing to note is that there are still instances of duplicate content within these folders, but the READMEs make the most sense to start with since contributors will likely look at that content before going into another file.)
What I propose is moving the recently updated /doc/contributing/README.md out of the /contributing/ folder and turning it into the main /doc/README.md file. Should we want to keep a link or two currently listed in the /doc/README, we can easily add it into the updated file.
I'm assigning myself to this issue for now but would absolutely appreciate feedback from the team if anyone has any suggestions!
cc @indirect @hmistry @colby-swandale

Quick feedback:

It's hard to judge which links are common and which are missing between the 2 documents. Maybe if you can spell that out more, it'd be easier to comment on to answer your question.
Regarding merging them, generally I'm for it. My knee-jerk reaction says the /doc/Readme is more encompassing than /doc/contributing/readme... so maybe transfer missing things upwards?
The Readme's in each /contributing, /documentation, /development folders seem to serve a purpose in the event some one navigates to that folder through files and not through readme guides. So knee-jerk reaction is those readme's should stay and explain the content in that folder and direct users to the higher level if they are looking for a different category like dev or documentation.
With that said, there's something really bothering me about this whole division of contributing, development, and documentation. I finally understand what - it's that the last 2 are a subset of contributing and not having this hierarchy is causing some overlaps between the sections because you can't talk of contributing without dev or documentation. What if we create a different hierarchy like:

Contributing (or /doc?):
- Overview and general stuff e.g. getting started
- Issues stuff
- Development stuff
- Documentation stuff
- Getting help and community

What do you think?

I think merging is a good idea! My hope is that eventually the main readme will explain what this is, and direct end users to the docs site at bundler.io so they can learn about bundler, and redirect interested contributors to /doc/README.md where we will have internally-facing documentation. This seems like a good step in that direction.

@hmistry great ideas! So we should definitely maintain READMEs in all of those folders, we just need to be more clear about what content should be in them, and always link back to the main Contributor Guidelines from each in case users want/need to access it. I'll keep that in mind when coming up with an outline!
@indirect good to know! I'll start brainstorming an outline for what all of this could potentially look like and will add it in a gist :).

@rubymorillo Actually on second thought, I don't know if there's much value in having readme's in each of those folders, as long as there's a good well explained one in the base folder linking to them. Maybe it just needs a link back??
Let's see what you come up with and what makes sense for the 2 types of users (gem developers and gem users seeking help) because there's a cost to maintaining all these readme's too. Perhaps @indirect's vision of directing some things to the website will help simplify things.

@hmistry @indirect I haven't made much headway with this lately because of school, but looking at both files, I'm open to @hmistry's suggestion that we make the /doc/contributing/README.md the main README, replacing /doc/README.md.
If we do this, should I also delete a README in the Contributing folder, or should we turn that README into a "Table of Contents" that basically lists out the different files in the Contributing folder, with a sentence-long description?

ping @hmistry @indirect let me know if y'all have any thoughts; if needed, we can table this discussion for now


Finalize afni_proc.py settings

@handwerkerd do you have any recommendations for running afni_proc.py on multi-echo data? Is there a way to ensure that the outputs are roughly similar to BIDS format?
Here's a copy from the help (feel free to edit as you wish):
#!/bin/tcsh

# --------------------------------------------------
# note fixed top-level directories
set data_root = /main/location/of/all/data

set input_root = $data_root/scanner_data
set output_root = $data_root/subject_analysis

# --------------------------------------------------
# get a list of subjects, or just use one (consider $argv)
cd $input root
set subjects = ( subj* )
cd -

# or perhaps just process one subject?
set subjects = ( subj_017 )

# --------------------------------------------------
# process all subjects
foreach subj_id ( $subjects )

  # --------------------------------------------------
  # note input and output directories
  set subj_indir = $input_root/$subj_id
  set subj_outdir = $output_root/$subj_id

  # --------------------------------------------------
  # if output dir exists, this subject has already been processed
  if ( -d $subj_outdir ) then
     echo "** results dir already exists, skipping subject $subj_id"
     continue
  endif

  # --------------------------------------------------
  # otherwise create the output directory, write an afni_proc.py
  # command to it, and fire it up
  mkdir -p $subj_outdir
  cd $subj_outdir

  # create a run.afni_proc script in this directory
  cat > run.afni_proc << EOF

  # notes:
  #   - consider different named inputs (rather than OutBrick)
  #   - verify how many time points to remove at start (using 5)
  #   - note which template space is preferable (using MNI)
  #   - consider non-linear alignment via -tlrc_NL_warp
  #   - choose blur size (using FWHM = 4 mm)
  #   - choose basis function (using BLOCK(2,1), for example)
  #   - assuming 4 CPUs for linear regression
  #   - afni_proc.py will actually run the proc script (-execute)
  afni_proc.py -subj_id $subj_id                          \
      -blocks tshift align tlrc volreg blur mask regress  \
      -copy_anat $subj_indir/anat+orig                    \
      -dsets                                              \
          $subj_indir/epi_r1+orig                         \
          $subj_indir/epi_r2+orig                         \
          $subj_indir/epi_r3+orig                         \
      -tcat_remove_first_trs 5                            \
      -align_opts_aea -cost lpc+ZZ                        \
      -tlrc_base MNI152_2009_template.nii.gz              \
      -tlrc_NL_warp                                       \
      -volreg_align_to MIN_OUTLIER                        \
      -volreg_align_e2a                                   \
      -volreg_tlrc_warp                                   \
      -blur_size 4.0                                      \
      -regress_motion_per_run                             \
      -regress_censor_motion 0.3                          \
      -regress_reml_exec -regress_3dD_stop                \
      -regress_stim_times                                 \
          $stim_dir/houses.txt                            \
          $stim_dir/faces.txt                             \
          $stim_dir/doughnuts.txt                         \
          $stim_dir/pizza.txt                             \
      -regress_stim_labels                                \
          house face nuts za                              \
      -regress_basis 'BLOCK(2,1)'                         \
      -regress_opts_3dD                                   \
          -jobs 4                                         \
          -gltsym 'SYM: house -face' -glt_label 1 H-F     \
          -gltsym 'SYM: nuts -za'    -glt_label 2 N-Z     \
      -regress_est_blur_errts                             \
      -blocks tshift align tlrc volreg mask combine blur scale regress \
      -dsets_me_echo   epi_run*_echo_01.nii                            \
      -dsets_me_echo   epi_run*_echo_02.nii                            \
      -dsets_me_echo   epi_run*_echo_03.nii                            \
      -echo_times      15 30.5 41                                      \
      -mask_epi_anat   yes                                             \
      -combine_method  OC
      -execute

EOF
# EOF terminates the 'cat > run.afni_proc' command, above
# (it must not be indented in the script)

  # now run the analysis (generate proc and execute)
  tcsh run.afni_proc

# end loop over subjects
end

If you use you the example you copied with -combine_method  OC then it would unnecessary calculate a T2* map and the optimally combined time series, but it would give you close to what you want.
For the -blocks option, you'd also want to remove everything after combine. That is replace -blocks tshift align tlrc volreg mask combine blur scale regress with -blocks tshift align tlrc volreg mask combine With the shorter version, some useful quality control outputs wouldn't be given, but that may or may not be an issue depending on how you plan  to use these data. (Also there's something wrong with the command you copied above in that has two -blocks optiosn and both -dsets & -dsets_me_echo This is different from their docs so I'm not sure where you got it from)

@handwerkerd sorry for the noise. I don't know where I copied the incorrect parameters from.
As far as a good repo for a template script goes, what about the Multi-echo masking test dataset (https://openneuro.org/datasets/ds002156)? There's only one subject, so it's small.
The inputs can be:
sub-23638/ses-01/anat/sub-23638_ses-01_acq-mpragePURE_run-1_T1w.nii.gz
sub-23638/ses-01/func/sub-23638_ses-01_task-rest_run-1_echo-1_bold.nii.gz
sub-23638/ses-01/func/sub-23638_ses-01_task-rest_run-1_echo-2_bold.nii.gz
sub-23638/ses-01/func/sub-23638_ses-01_task-rest_run-1_echo-3_bold.nii.gz
sub-23638/ses-01/func/sub-23638_ses-01_task-rest_run-1_echo-4_bold.nii.gz

The echo times are 15.1, 28.7, 42.3, and 55.9.
I'm hoping that afni_proc can be used to produce (1) minimally-preprocessed echo-wise data to run tedana on, (2) a brain mask in the echo-wise images' space for tedana, and (3) optimally-combined data in standard space, which I could denoise using the tedana results. What do you think?

Howdy-
We actually do have a mapping of afni_proc.py outputs to current BIDS-derivatives naming; we just haven't had time to implement that as an option yet.  Hopefully soon after the Bootcamp...
For multiecho FMRI data, we do have a fair number of afni_proc.py examples in the APMULTI demo, which is downloadable for resting state FMRI with:
@Install_APMULTI_Demo1_rest

https://afni.nimh.nih.gov/pub/dist/OHBM2022/OHBM2022_tayloretal_apmulti.pdf
@tsalo : it sounds like you want just the datasets output by using OC or tedana, then?  Or with further regression processing?  Are the pbcombine datasets what you would like, at present?
--pt

@mrneont that's awesome! I mainly want these AFNI derivatives to be useful for testing tedana, so the primary output I'm interested in is minimally-preprocessed individual echoes, along with some way to either transform outputs from running tedana separately on those echoes to standard space or optimally combined data in standard space that can be denoised using the results from running tedana separately. I'd love to have regressors that could be used for regression (e.g., motion parameters), but not denoised data.
@handwerkerd if possible, I'd love to have the echo-wise outputs in native space (per our recommendations in the tedana docs) and optimally combined outputs in standard space. Maybe MNI152NLin6Asym, since that's the one I'll use for fMRIPrep?

When afni_proc aligns to a template it does a single spatial transformation for both motion correction and alignment. (Probably time to revisit that recommendation ME-ICA/tedana#990 ).
Do get what you want, I can write one afni_proc with and one without spatial alignment, or I can just run with spatial alignment and use a stand-along AFNI command to create volumes for each echo that aren't aligned to the template.
AFNI includes a bunch of MNI templates, but I'm not sure which one matches MNI152NLin6Asym. Can you point me to the template volumes fMRIPrep uses so I can make sure to align to the exact same one?

Do get what you want, I can write one afni_proc with and one without spatial alignment, or I can just run with spatial alignment and use a stand-along AFNI command to create volumes for each echo that aren't aligned to the template.

That would be great, thank you!

AFNI includes a bunch of MNI templates, but I'm not sure which one matches MNI152NLin6Asym. Can you point me to the template volumes fMRIPrep uses so I can make sure to align to the exact same one?

fMRIPrep grabs its templates from templateflow (https://www.templateflow.org/browse/). The template is under the tpl-MNI152NLin6Asym folder. It's the file tpl-MNI152NLin6Asym_res-02_T1w.nii.gz.

AFNI does not need to have a template in the distribution to use it for template alignment.  If there is one you like, just download and give it to afni_proc.py with the -tlrc_base option.
Yes, you can give afni_proc.py the echoes and just do the steps prior to 'combine', but really, it does not hurt to add 'combine' and 'regress' blocks.  That would lead to a much more detailed QC report, and it won't change the datasets that you would want to use without those blocks.  The cost is just extra disk space.  But whatever you prefer is fine.
-rick

From: Taylor Salo @.>
Sent: Tuesday, October 24, 2023 2:38 PM
To: ME-ICA/open-multi-echo-data @.>
Cc: Reynolds, Richard C. (NIH/NIMH) [E] @.>; Mention @.>
Subject: [EXTERNAL] Re: [ME-ICA/open-multi-echo-data] Finalize afni_proc.py settings (Issue #29)
Do get what you want, I can write one afni_proc with and one without spatial alignment, or I can just run with spatial alignment and use a stand-along AFNI command to create volumes for each echo that aren't aligned to the template.
That would be great, thank you!
AFNI includes a bunch of MNI templates, but I'm not sure which one matches MNI152NLin6Asym. Can you point me to the template volumes fMRIPrep uses so I can make sure to align to the exact same one?
fMRIPrep grabs its templates from templateflow (https://www.templateflow.org/browse/). The template is under the tpl-MNI152NLin6Asym folder. It's the file tpl-MNI152NLin6Asym_res-02_T1w.nii.gz.
—
Reply to this email directly, view it on GitHubhttps://github.com/ME-ICA/open-multi-echo-data/issues/29#issuecomment-1777814180, or unsubscribehttps://github.com/notifications/unsubscribe-auth/ACKLXXNOUENLMS2KLAXGB23YBADKLAVCNFSM6AAAAAA6KHEHB6VHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMYTONZXHAYTIMJYGA.
You are receiving this because you were mentioned.Message ID: @.***>
CAUTION: This email originated from outside of the organization. Do not click links or open attachments unless you recognize the sender and are confident the content is safe.

Here is a sample script for the above dataset. I have a version that runs regress to get a bunch of quality control outputs. This really might be useful, but, for this run something was going wrong with the MNI alignment. My best guess is that either the template image or the original data has something that diverges from the NIFTI standard and makes AFNI unhappy. I can talk more to @afni-rickr to check/confirm the problem isn't on AFNI's side, but the following should work fine for your current plans.
sbjID=sub-23638
ses=ses-01
task=rest_run-1
echo_times=(15.1 28.7 42.3 55.9)
rootdir=~/code/meica/data_testing/Multi-echo_masking_test_dataset/${sbjID}/${ses}
anat=anat/${sbjID}_${ses}_acq-mpragePURE_run-1_T1w.nii.gz

# The data had several non-steady state volumes at the beginning.
# This will be used to remove the first four
remove_first_trs=4

# template from here: https://www.templateflow.org/browse/ in tpl-MNI152NLin6Asym
# Using the T1 that was already skull stripped
template=../../template/tpl-MNI152NLin6Asym_res-02_desc-brain_T1w.nii.gz

# You probably want to put files elsewhere, but fine for this demo
cd $rootdir

# Runs AFNI proc in native space
# The pre-processed runs to input into tedana are called pb03.${sbjID}.r01.e0?.volreg+orig.HEAD
afni_proc.py -subj_id ${sbjID} \
   -blocks despike tshift align volreg mask combine tlrc \
   -dsets_me_run  ./func/${sbjID}_${ses}_task-${task}_echo-1_bold.nii.gz \
       ./func/${sbjID}_${ses}_task-${task}_echo-2_bold.nii.gz \
       ./func/${sbjID}_${ses}_task-${task}_echo-3_bold.nii.gz \
       ./func/${sbjID}_${ses}_task-${task}_echo-4_bold.nii.gz \
   -tlrc_base $template \
   -echo_times $echo_times \
   -reg_echo 2 \
   -copy_anat $anat \
   -anat_has_skull yes \
   -mask_epi_anat yes \
   -align_unifize_epi local \
   -volreg_align_e2a \
   -tcat_remove_first_trs $remove_first_trs \
   -execute

# The above afni_proc calculates an alignment to template space, but doesn't use it
# The following will apply the transform to write out the echo data in template space
# The new files are called pb03a.${sbjID}.r01.e01.volreg+tlrc.HEAD (lousy naming, acknowledged)
cd ${rootdir}/${sbjID}.results
echo_list=(01 02 03 04)
for eind in ${echo_list[@]}; do
    3dAllineate -base ../$template    \
                   -input pb03.${sbjID}.r01.e${eind}.volreg+orig.HEAD                 \
                   -1Dmatrix_apply warp.anat.Xat.1D                    \
                   -mast_dxyz 3.5                                             \
                   -prefix pb03a.${sbjID}.r01.e${eind}.volreg+tlrc.HEAD
done

Hi @handwerkerd.  To get the EPI into standard space (without the extra resampling at the end), use:
-blocks despike tshift align tlrc volreg mask combine regress
It needs the tlrc block before volreg in order to concatenate the transformations in the volreg block.  And I just threw the 'regress' block in there for QC.
I will try to get this data and try the command locally.

Hi @handwerkerd.  The script worked, at least at a quick glance.  I did use the blocks from above
-blocks despike tshift align tlrc volreg mask combine regress
and to actually warp the EPI into standard space requires the -volreg_tlrc_warp option.

Thanks so much @afni-rickr @handwerkerd @mrneont! Our server is down at the moment, but I will try the updated command on one of the example datasets soon.


Updating to serde-yaml 0.9

Hi, I am currently trying to update the package of the serde-yaml crate in Debian.
to 0.9.x I tried bumping the dependency in the treediff crate but the build fails with
error[E0004]: non-exhaustive patterns: serde_yaml::Value::Tagged(_) not covered
--> src/value/serde_yaml.rs:14:15
|
14 |         match *self {
|               ^^^^^ pattern serde_yaml::Value::Tagged(_) not covered
|
I would appreciate it if you can take a look and determine an appropriate way to handle
the new enum variant.

Thanks for reporting.
Unfortunately I have to declare this library to be in maintenance mode so all fixes and improvements have to be contributed. Right now, I really don't have time nor motivation, as none of my crates still use this library.
It looks like the main consumer of this library is json-patch, and I suggest to open an issue them so they contribute a fix, take over this crate, or cut the dependency to this crate in some other way.
Thanks for your help.


source env.sh | "env.sh"; no such file or directory

Hello. On Linux.
$ source env.sh
bash: env.sh: No such file or directory
$ ls
CMakeLists.txt   Makefile   run_all_tests.py  src                   thirdparty
install_deps.sh  README.md  run_tests.py      summarise_results.py

Thanks for reporting the issue. The env.sh file was a leftover from a different environment I was uing. I've updated the README now.


TWAP for Gnosis middleware updates

https://www.notion.so/volumefi/EPIC-09-29-23-Stables-Offramp-to-Euros-Gnosis-Bot-b1dc5977ed6340d09d3f55855f96db58?pvs=4#ff667394b54b4402a3fc0f4ce36e2fbc
Done when

[ ] API for FE to submit bot is available
[ ] twap bot is triggered by backend script
[ ] offramp bot can be triggered by backend script
[ ] twap and offramp bot are combined in one repo and one record for the bot-info api

@verabehr seems pretty straightforward no questions at this time.


How to create a platform rule for BouncyCastle?

My project layout basically follows gradle-project-setup-howto, but I replaced the old plugins dev.jacomet.logging-capabilities and org.gradlex.java-ecosystem-capabilities with this new one: org.gradlex.jvm-dependency-conflict-resolution.
I created a BouncyCastlePlatformRule to use in my platform project that looks like this:
@CacheableRule
abstract class BouncyCastlePlatformRule : ComponentMetadataRule {
    companion object {
        const val BOUNCY_CASTLE_PLATFORM = "org.bouncycastle:bcprov-jdk15to18"
    }

    override fun execute(context: ComponentMetadataContext) {
        val version = context.details.id.version
        context.details.allVariants {
            withDependencyConstraints {
                add("org.bouncycastle:bcpg-jdk15to18:$version")
                add("org.bouncycastle:bcpkix-jdk15to18:$version")
                add("org.bouncycastle:bcprov-jdk15to18:$version")
                add("org.bouncycastle:bcutil-jdk15to18:$version")
            }
        }
    }
}

With the plugin disabled this seems to work fine, but then I am not getting the transformation from the jdk15on to jdk15to18, so not all versions align correctly. With the plugin enabled I am getting this error:

Module 'org.bouncycastle:bcprov-jdk15to18' has been rejected:
Cannot select module with conflict on capability 'org.gradlex:bouncycastle-bcprov:1.78.1' also provided by
[org.bouncycastle:bcprov-jdk15to18:1.78.1(platform-compile), org.bouncycastle:bcprov-jdk15to18:1.78.1(compile)]

I tried to resolve this by adding a resolutionStrategy the way the documentation suggested, but it didn't work. What am I doing wrong?
Thanks,
Peter

I am not completely sure why you do not get an(other) error when you do not apply the plugin, but I think the problem is that you use bcprov-jdk15to18 both as a normal component (Jar) and a platform. This is not really supported out of the box in Gradle's dependency setup for Java projects. But the capability conflict detection is a bit inconsequential if there are no explicit capability definitions. That's probably the reason why you do not get the error without the plugin.
The pattern of turning an existing "component" into a platform only works well if you use something that is not also a component (a Jar) that you use already.
Looking at the example, I see that I also did that with org.apache.poi:poi. I have to revisit that. I will probably run into the same problem if I update the example to use org.gradlex.jvm-dependency-conflict-resolution.
What I did for other libraries in the example, is to use the "parent POM" of the corresponding library (which sometimes already is a kind of platform). Unfortunately, in this case there is no parent you can use. This is a limitation of the pattern. What you can do is use something for BOUNCY_CASTLE_PLATFORM that you do not use at all - maybe BOUNCY_CASTLE_PLATFORM = "org.bouncycastle:bcprov-ext-jdk18on"
Note: I am happy to see that you successfully use this setup. Thanks for the feedback. 😄
This pattern with the platform rules however, is one thing I am not so sure about anymore. I stopped using it in real™ projects. I plan to update the gradle-project-setup-howto repo and I am not sure if I will keep it in there. But I have to look at it in more detail again.
Hope this solves your issue for now. I'll comment here again once I found the time to update the gradle-project-setup-howto example.

Hi @jjohannes,
Thanks for your quick response!

What I did for other libraries in the example, is to use the "parent POM" of the corresponding library (which sometimes already is a kind of platform). Unfortunately, in this case there is no parent you can use. This is a limitation of the pattern. What you can do is use something for BOUNCY_CASTLE_PLATFORM that you do not use at all - maybe BOUNCY_CASTLE_PLATFORM = "org.bouncycastle:bcprov-ext-jdk18on"

Unfortunately this didn't work, apparently because it provides the same capability. I got a similar error as above:
Could not determine the dependencies of task ':app:compileJava'.
> Could not resolve all task dependencies for configuration ':app:compileClasspath'.
   > Could not resolve org.bouncycastle:bcprov-ext-jdk18on:1.78.1.
     Required by:
         project :app > project :platform
      > Module 'org.bouncycastle:bcprov-ext-jdk18on' has been rejected:
           Cannot select module with conflict on capability 'org.gradlex:bouncycastle-bcprov:1.78.1' also provided by [org.bouncycastle:bcprov-ext-jdk18on:1.78.1(compile), org.bouncycastle:bcprov-ext-jdk18on:1.78.1(platform-compile)]
   > Could not resolve org.bouncycastle:bcprov-jdk15to18:1.78.1.
     Required by:
         project :app > org.bouncycastle:bcpkix-jdk15to18:1.78.1
         project :app > org.bouncycastle:bcutil-jdk15to18:1.78.1
      > Module 'org.bouncycastle:bcprov-ext-jdk18on' has been rejected:
           Cannot select module with conflict on capability 'org.gradlex:bouncycastle-bcprov:1.78.1' also provided by [org.bouncycastle:bcprov-ext-jdk18on:1.78.1(compile), org.bouncycastle:bcprov-ext-jdk18on:1.78.1(platform-compile)]

Nevertheless, this was helpful, because next I tried BOUNCY_CASTLE_PLATFORM = "org.bouncycastle:bcmail-jdk18on" and that worked fine. So, thanks for pointing me in the right direction. :smile:

Looking at the example, I see that I also did that with org.apache.poi:poi. I have to revisit that. I will probably run into the same problem if I update the example to use org.gradlex.jvm-dependency-conflict-resolution.

Actually I wanted to ask about this, (although this would be more suited for the gradle-project-setup-howto project), but the poi rule doesn't seem to be doing anything, because the dependency graph (under the platform) looks like this:
|    +--- org.apache.poi:poi:5.2.3
|    |    +--- commons-codec:commons-codec:1.15
|    |    +--- org.apache.commons:commons-collections4:4.4
|    |    +--- org.apache.commons:commons-math3:3.6.1
|    |    +--- commons-io:commons-io:2.11.0 -> 2.13.0
|    |    +--- com.zaxxer:SparseBitSet:1.2
|    |    \--- org.apache.logging.log4j:log4j-api:2.18.0 -> 2.20.0
|    |         \--- org.apache.logging.log4j:log4j-bom:2.20.0
|    |              +--- org.apache.logging.log4j:log4j-api:2.20.0 (c)
|    |              +--- org.apache.logging.log4j:log4j-core:2.20.0 (c)
|    |              \--- org.apache.logging.log4j:log4j-jcl:2.20.0 -> org.slf4j:jcl-over-slf4j:2.0.7 (c)

This is just what's in the pom with nothing added or removed. Unlike org.apache.httpcomponents:httpcomponents-client for example, where I only see a list of constraints that were added by the rule.

Note: I am happy to see that you successfully use this setup. Thanks for the feedback. 😄

It is not a complete success yet, but I am getting there. :smile: First I had to build the whole project from scratch, one file at a time, so I can try and (at least somewhat) understand the structure, because it is way over my head. Then I moved in the actual source code and now I am trying to put all the dependencies into the platform project, migrate my existing rules, etc. But thanks for providing this framework, I think it will be great, once I complete it. :laughing:

This pattern with the platform rules however, is one thing I am not so sure about anymore. I stopped using it in real™ projects. I plan to update the gradle-project-setup-howto repo and I am not sure if I will keep it in there. But I have to look at it in more detail again.

Great, and I was thinking that I was modernizing my project. Now you're telling me that I am using outdated, "legacy" technology. :joy::joy::joy:

Hope this solves your issue for now. I'll comment here again once I found the time to update the gradle-project-setup-howto example.

Looking forward to the updates. Until then I'll continue working with this dinosaur. 😂

@mqware would you mind opening an issue over at https://github.com/jjohannes/gradle-project-setup-howto with your latest comment as description (you can copy it over as it is) and close the issue here.
Then we can continue the discussion there, once I get to update that project.
And no worries, it's still in a very good state right now from my point of view. Just some aspects are evolving. 😃

@jjohannes Yeah, I guess I should've opened this issue at the other project in the first place. Sorry about that.


Fix get rocksdb ops tcl test case

fix #658

As commented in https://github.com/apache/incubator-kvrocks/issues/658#issuecomment-1166219636, seems our current ops comparison is not so determined since it depends on the server cron to record metrics, also ops will be changed by the time slot. I think we can change the assert condition to guarantee those ops metrics can't be zero. How do you think?

I think we can change the assert condition to guarantee those ops metrics can't be zero.

Yes, this operation is the metric from rocksdb, which should return as correct as possible.

I think we can change the assert condition to guarantee those ops metrics can't be zero.

Yes, this operation is the metric from rocksdb, which should return as correct as possible.
And how about using put ops compare to other ops?

For those ops metrics would be affected by other test cases if they have many get/put/seek operations, coz our metrics calculate range is 16s. Can see: https://github.com/apache/incubator-kvrocks/blob/0b2de8ab6f661d90a279a0c11096755d7733b11c/src/stats.cc#L108
I think it's ok to check ops > 0 only for current implementation, we should export those metrics counter if want to check them more precisely.


vite:define can't process std-env

Describe the bug
std-env contains some environment-agnostic utilities (see source).
The current vite:define plugin can't process this (see compiled library), and there seems to be no way to opt-out of processing a file with the define plugin.
Linked upstream issue: https://github.com/nuxt/nuxt/issues/24793
Reproduction
https://stackblitz.com/edit/vitejs-vite-ndari4
Steps to reproduce
npm run dev (which will run the build command)
System Info
StackBlitz

Used Package Manager
npm
Logs
No response
Validations

[X] Follow our Code of Conduct
[X] Read the Contributing Guidelines.
[X] Read the docs.
[X] Check that there isn't already an issue that reports the same bug to avoid creating a duplicate.
[X] Make sure this is a Vite issue and not a framework-specific issue. For example, if it's a Vue SFC related bug, it should likely be reported to vuejs/core instead.
[X] Check that this is a concrete bug. For Q&A open a GitHub Discussion or join our Discord Chat Server.
[X] The provided reproduction is a minimal reproducible example of the bug.

It looks like esbuild's bug. I was testing<EMAIL_ADDRESS>on esbuild playground with define picked from:
https://github.com/vitejs/vite/blob/5684fcd8d27110d098b3e1c19d851f44251588f1/packages/vite/src/node/plugins/define.ts#L19-L26
And I found that applying { define: { "globalThis.process.env": "{}" } } to the source code globalThis.process?.env[o] triggers a panic.
Here are playground links:

std-env
minimal repro

This should be fixed in esbuild v0.19.10 https://github.com/evanw/esbuild/releases/tag/v0.19.10
I confirmed vite build succeeds on stackblitz via package.json "overrides": { "esbuild": "0.19.10" }
https://stackblitz.com/edit/vitejs-vite-21ssdn?file=package.json

@hi-ogawa Thanks for investigating and the fix 💚


IE11 issue

I'm developing a game with Phaser and, when testing in IE11, I get a constant flickering between the stage's background colour and black. I also don't get any interactions from buttons in Phaser.
While no errors are thrown, there is a warning in the console:
EBGL11135: getContext: Context attribute premultipliedAlpha:false is not currently supported
I can confirm that if I remove the premultipliedAlpha option from the webgl context options in Pixi (src/pixi/renderers/webgl/WebGLRenderer.js line 150), the buttons and interactions do then work in Phaser. However, the flickering continues.
I think this may be a graphics card specific issue.
The PIXI examples on the GoodBoy website seem to use version 1.5.2 and the problem is not evident there. Are there any using version 2 that I could test against?
There are no issues if I render in canvas mode.
Technical details:
Phaser version: v2.1.3 "Ravinda" - Built: Thu Oct 23 2014 12:33:04
PIXI version v2.0.0
Windows 8.1 with Internet Explorer 11.0.9600.17416 - IE compatibility mode set to Edge.
Graphics: NVIDIA GeForce GT 640M

It happens on Windows Phone too

closing this for now as I'm pretty sure this has been fixed in v3. Let me know if im wrong! Cheers! :+1:

i have the same problem here: http://codepen.io/spleen666/pen/ZGYPbW - looks fine in chrome & FF -

Have you tried passing { transparent: true } to autoDetectRenderer, so that premultipliedAlpha is true on context creation?

Just had this bug in IE11 with PIXI 4.5.1 even when forcing the CanvasRenderer, but @englercj 's suggestion using transparent: true seems to fix the issue.


Change in Column Name not picked up

in wuffle-config.js, I renamed Next to To Do.
On restart, all issues in that column did not appear.  When I checked they were still under the Next Column in the storedump.json and did not appear at all, as a column rename is not picked up to ensure the column exists on restart
To fix the issue I had to remove the label on each issues and re add to get it to appear correctly

Not sure how to circumvent this issue. A few options:

Do not support renaming in populated boards
Recognize column renamings and move items on re-start (that would require to persist the current configuration within the storedump)
Provide a way to update the storedump before restarting the app

Any thoughts?

Hmm maybe check if the column is valid/exists on background sync and if not remove it and get valid column for label

Shipped with v0.27.0.


msconvert/pwiz update

update ProteoWizard to a recent version
streamline the filters by dividing them into sections: "Data Processing", "Inclusion/Exclusion Filters", and "Output Encoding Settings"
add functional tests for almost all filters

I kept msconvert and msconvert_raw as separate tools but factored out more of their redundant XML via macros; the only difference should be whether they are run on Windows or Linux, and whether they accept vendor formats as input.
I haven't tested msconvert_raw on Windows yet (I haven't even added the Windows package yet). In fact, because it will double the amount of binary data to download, we may want to make these two separate tools (i.e. separate .shed.yml). That way the user can download just the one they need.

@chambm this is an awesome cleanup! Thanks a lot!
I wouldn't split this up into 2 directories, I think I would like to see plenemo demulitplexing here. I can patch this in as soon as the gets merged.

I liked to review this at the Galaxy-P meeting on Friday with the grant principal investigators.
I think this is a good approach factoring out common elements from msconvert.xml and msconvert_raw.xml  It will be good to have a tool_dependency for the linux binary.   Is it even possible to do so for the Windows code?   I have presumed that the Windows side of this would have to be set up manually by an admin.
We would definitely want to bump the tool version numbers.  I can anticipate our researchers complaining of broken workflows unless we can retain the current versions.
Including the wiff format for msconvert_raw.xml will be important at Minnesota.

@chambm @bgruening  @jmchilton @iracooke
The new tool form layout was well received at Galaxy-P project meeting.

Let's have tool versions reflect proteowizard version: 3.0.0 to start with?

I think we should break this into 2 tool repositories:

msconvert - refactored, but geared toward Windows deployment with vendor libs, requires admin to setup Windows and pulsar

msconvert_public - includes tool_dependencies.xml and , can be automatically installed on *nix platforms

github layout:
msconvert/
.shed.yml
COPYING
msconvert_macros.xml
msconvert_wrapper.py
test-data/
msconvert/
msconvert.xml (With vendor formats)
msconvert_wrapper.py -> ../msconvert_wrapper.py
msconvert_macros.xml -> ../msconvert_macros.xml
test-data  -> ../test-data
msconvert_public/
msconvert.xml (No vendor formats)
msconvert_wrapper.py -> ../msconvert_wrapper.py
msconvert_macros.xml -> ../msconvert_macros.xml
test-data  -> ../test-data
tool_dependencies.xml
msconvert_wrapper.py
I would still use the msconvert_wrapper.py inorder to abstract the differences for executing on a *nix host vs Windows.
Many of the flag options could be passed to msconvert_wrapper.py as args after '--' rather than options, simplifying the msconvert_wrapper.py options:
msconvert_wrapper.py --input="dataset_111.dat" --input_name="my.mzML" --fromextension=mzml --toextension=mgf --output="dataset_222.dat" -- --64 --mz64 --inten32

Fully agree!
For windows you need to install your deps manually.

I have not had time to check out Matt's changes but I definitely agree with the idea of splitting into two repositories and having the linux one with tool_dependencies.

@chambm   Can you provide me with a copy of Rpal_01.pepXML.gz so I can try testing the mzRefine filter?   Thanks.

@jj-umn Added to repo. It was supposed to be there already, but it .gz files are .git-ignored, so I had to override that.

@bgruening What do you think about @jj-umn 's suggested repo layout? Still want to do the multiplexing with Planemo?
I don't understand the names "msconvert" vs. "msconvert_public"; "msconvert_windows" vs. "msconvert_linux" makes more sense to me. Of course we're not strictly limited to Linux, but how many BSD-based Galaxy hosts are there?
What does the msconvert python wrapper provide? If it's just symbolic link abstraction, I don't think it's too critical. Anyway, doesn't that require an elevated command prompt, or a non-elevated prompt where the user has been given explicit SYMLINK privileges and is NOT an administrator user?

@chambm   Yes, "msconvert_public" is an awful name.  I wanted to keep the msconvert as the windows version for historical consistency.   How about something like "msconvert_x" for uniX-derived systems eXcluding the windows-only vendor libs?

@jj-umn Unless I'm missing something, the current version has msconvert_raw as the Windows version; msconvert is the non-Windows version. I think msconvert_x makes sense, but not intuitively. It has to be explained. the windows/linux dichotomy is clearer, but could also be _win/_nix.

:+1: for _win/_nix

@chambm do you plan to work on this further?

Yes, but it will have to wait a few more weeks. Just had a baby a couple weeks ago and working on a master's thesis. :)

Wonderful new @chambm - enjoy! Work can wait!


Question about DB locking

Hello,
I run a few fairly large validator keysets for both eth and gnosis right now and am looking at Web3Signer as a way to help ease some of the scaling issues that come with localized slashing DB at my scale. When I say large validator keysets I am talking about keyset sizes north of the 10K range.
Ideally, I want to move all my keys to Web3Signer running in an HA cluster with shared backend DB cluster that is also HA. This removes a lot of complexity out of my validator setup as they don't have to keep local slashing DBs on a per validator basis.
This brings me to my question.
A quick glance of the code, and I do mean quick, tells me there are two ways the DB is locked. Per my understanding when a new key is added/removed/validator activated the entire DB is locked (probably wrong about this but that is my assumption).
Secondly, under normal block proposal/attestation process, again per my quick glance, the code seems to only lock the rows of the specific validatorID involved, not the entire DB. Thus, multiple keys can be attesting/proposing at once and there is no lock contention across the the DB but only on a per validator key basis.
To put it more simply, the lock for block proposal/attestations is per validator key, not the entire DB. Where as the lock when adding/removing/activating a validator is across the entire DB.
Finally, has the team done any load testing to see how Web3Signer scales up in regards to key sizes?
Thanks and looking forward to being corrected in regard to my assumptions about the DB locking in the signer.

Hi @beegmon,
There are two distinct cases for locking.
In the normal block and attestation signing we have database lock that is specific the validator id and the type of data being signed i.e. block or attestation. So multiple keys can be attesting/proposing at once so long as they are not for the same validator id and operation.
For the other case for importing or deleting a key using the key manager API we also use database locking. In this case it's not as fine grained in that we lock the database for both attestations and blocks for a particular validator id. This is not database wide lock it still specific the validator id.
We haven't done any load testing against large key sizes. This is something that we are working on though and currently in the process of setting a test with 10,000 keys.

Thanks for the info and very much appreciated.


Oracle db:schema:dump results in invalid :limit for Date columns

create_table "authors", :force => true do |t|
  t.datetime "created_at",    :limit => 7
  ......

DEBUG jruby.Submissions debug:110 -   SQL (2450.0ms)  CREATE TABLE authors (id NUMBER(38) NOT NULL PRIMARY
KEY, submission_id NUMBER(38), given_name varchar2(4000), surname varchar2(4000), email varchar2(4000), affiliation
varchar2(4000), series NUMBER(38), created_at DATE(7), updated_at DATE(7))
DEBUG jruby.Submissions log:206 - ActiveRecord::JDBCError: ORA-00907: missing right parenthesis
: CREATE TABLE authors (id NUMBER(38) NOT NULL PRIMARY KEY, submission_id NUMBER(38), given_name
varchar2(4000), surname varchar2(4000), email varchar2(4000), affiliation varchar2(4000), series NUMBER(38), created_at
DATE(7), updated_at DATE(7))

DATE columns shouldn't have any limit, right?

DATE(7) made things bomb for me. This patch made it work. With it, I can dump and import my schema successfully on Oracle Database 11g Enterprise Edition Release <IP_ADDRESS>.0
https://github.com/lenny/activerecord-jdbc-adapter/tree/issue-128


Fling with FlexibleSpaceWithImageWithViewPagerTab2Activity

Hello,
first of all thanks for your work to create this cool library. I have a problem regarding Fling with FlexibleSpaceWithImageWithViewPagerTab2Activity. I dont know if its related to the TouchInterceptionFrameLayout or the Methods for recognizing the MotionEvents.
Scrolling when holding down the Finger on Screen is smooth and works as expected. But when i try to Fling (hold down Finger, Scroll fast up or down and lift Finger immediatly, the Scrolling stops abrupt.
Thanks for your Help

I have tha same priblem.

@borgwald Hi, sorry for my late reply.
As you pointed out, it is related to TouchInterceptionFrameLayout.
You commented on the issue #129, but is this issue different from that?

To be honest, i dont know if issue #129 is the same. I commented that i have a similar issue and decided to post it as new issue afterwards.
Finally i managed to implement a Viewpager with Tabs and Parallax header with your library by using a heavily modified ViewPagerTabActivity.

@borgwald can you send me your code cause I have the same issue.
Thank you in advance

Is there a solution for the flinging issue?
When I fling and the actionbar can be scrolled, it stops the flinging and might not even show/hide the actionbar.


Allow limiting what interface to manage with wifi-connect

Users might have multiple wifi adapters / interfaces, that they want to reserve for different purposes. Would be useful to be able to limit wifi-connect to one or some subset of interfaces to check and to use for control interface.

[gelbal] This issue has attached support thread https://jel.ly.fish/#/support-thread~cc952684-c25c-4432-bf91-816a027a2f6c

This is already available through -i, --portal-interface, so I am closing the issue.


Adding support for Azure SQL DB Transparent Data Encryption with Azur…

Description
The changes include the newly generated hydra clients with support for the Azure SQL DB feature Transparent Data Encryption with Azure Key Vault integration. Tests are included.
The pull request to the corresponding hydra spec changes is here: https://github.com/Azure/hydra-specs-pr/pull/1366

This checklist is used to make sure that common guidelines for a pull request are followed.

[x] I have read the contribution guidelines.
[x] The pull request does not introduce breaking changes.

General Guidelines

[x] Title of the pull request is clear and informative.
[x] There are a small number of commits, each of which have an informative message. This means that previously merged commits do not appear in the history of the PR. For more information on cleaning up the commits in your PR, see this page.

Testing Guidelines

[x] Pull request includes test coverage for the included changes.

SDK Generation Guidelines

[x] If an SDK is being regenerated based on a new swagger spec, a link to the pull request containing these swagger spec changes has been included above.
[x] The generate.cmd file for the SDK has been updated with the version of AutoRest, as well as a link to the swagger spec, used to generate the code.
[x] The project.json and AssemblyInfo.cs files have been updated with the new version of the SDK.

Can one of the admins verify this patch?

Hi @mihymel, I'm your friendly neighborhood Azure Pull Request Bot (You can call me AZPRBOT). Thanks for your contribution!

It looks like you're working at Microsoft (mihymel). If you're full-time, we DON'T require a contribution license agreement.

If you are a vendor, DO please sign the electronic contribution license agreement. It will take 2 minutes and there's no faxing! https://cla.azure.com.

TTYL, AZPRBOT;

LGTM.

@akromm Can you review?

@azuresdkci add to whitelist

@akromm Wow, that was fast!

@mihymel Please include a link to the PR in hydra-specs-pr for this change

I modified the initial description to include a link the the hydra-specs-pr PR. Let me know if I should include the link somewhere else as well.

@mihymel I don't see the hydra-specs-pr link.  There are several modeling issues in this PR, so hydra-specs-pr changes will likely be necessary.

@markcowl The hydra-specs-pr PR is here https://github.com/Azure/hydra-specs-pr/pull/1366

@markcowl  Have you had the chance to look at the hydra-specs-pr changes here https://github.com/Azure/hydra-specs-pr/pull/1366 ? Let me know if you have any feedback.

@mihymel can you please pull in the latest changes from master?

LGTM once last changes from master have been pulled in

@cormacpayne I rebased my fork to the latest from master.


Installation fails

Hi there, congrats on the package!
I'm reviewing your JOSS submission, so expect more issues from me as I make my way through the checklist :)
https://github.com/openjournals/joss-reviews/issues/5598
When I try to install MacroModelling.jl, some Python compatibility issues pop up.
I strongly suggest you use PythonCall.jl + CondaPkg.jl to manage your Python dependencies.
As the following bug suggests, PyCall is less reliable and reproducible.

(@v1.9) pkg> activate --temp
  Activating new project at `/tmp/jl_ZNvdrc`

(jl_ZNvdrc) pkg> add MacroModelling
...
Precompiling project...
  ✗ MacroModelling
  0 dependencies successfully precompiled in 2 seconds. 196 already precompiled.
  1 dependency errored. To see a full report either run `import Pkg; Pkg.precompile()` or load the package

julia> using MacroModelling
[ Info: Precompiling MacroModelling [687ffad2-3618-405e-ac50-e0f7b9c75e44]
ERROR: LoadError: InitError: Failed to import required Python module sympy.

For automated sympy installation, try configuring PyCall to use the Conda.jl package's Python "Miniconda" distribution within Julia. Relaunch Julia and run:
    ENV["PYTHON"]=""
    Pkg.build("PyCall")
before trying again.

Note that Conda.jl can use custom conda environment. Read more about `CONDA_JL_HOME` configuration in Conda.jl documentation:
    https://github.com/JuliaPy/Conda.jl

To install sympy using /home/guillaume/mambaforge/bin/conda, you can run the following command from your system shell:
    /home/guillaume/mambaforge/bin/conda install sympy

The pyimport exception was: PyError (PyImport_ImportModule

The Python package sympy could not be imported by pyimport. Usually this means
that you did not install sympy in the Python version being used by PyCall.

PyCall is currently configured to use the Python version at:

/home/guillaume/mambaforge/bin/python3

and you should use whatever mechanism you usually use (apt-get, pip, conda,
etcetera) to install the Python package containing the sympy module.

One alternative is to re-configure PyCall to use a different Python
version on your system: set ENV["PYTHON"] to the path/name of the python
executable you want to use, run Pkg.build("PyCall"), and re-launch Julia.

Another alternative is to configure PyCall to use a Julia-specific Python
distribution via the Conda.jl package (which installs a private Anaconda
Python distribution), which has the advantage that packages can be installed
and kept up-to-date via Julia.  As explained in the PyCall documentation,
set ENV["PYTHON"]="", run Pkg.build("PyCall"), and re-launch Julia. Then,
To install the sympy module, you can use `pyimport_conda("sympy", PKG)`,
where PKG is the Anaconda package that contains the module sympy,
or alternatively you can use the Conda package directly (via
`using Conda` followed by `Conda.add` etcetera).

) <class 'ModuleNotFoundError'>
ModuleNotFoundError("No module named 'sympy'")

this one is about sympy (python package) not being there. essentially you need to make sure julia talks to python (SymPy.jl relies on PyCall.jl and Conda.jl) and has sympy installed in the python environment linked to julia. In a previous version I tried to automatise this with CondaPkg but it had no effect in my case. I will try again with the latest version.

essentially you need to make sure julia talks to python (SymPy.jl relies on PyCall.jl and Conda.jl) and has sympy installed in the python environment linked to julia.

I figured as much, but I tried installing it the naive way by just following the instructions in the README, which didn't mention anything about setting up Python :)

In a previous version I tried to automatise this with CondaPkg but it had no effect in my case. I will try again with the latest version.

The main advantage of CondaPkg is that it dispenses the user from having to fight with Python themselves. I've used it successfully several times, happy to help if needed

I added CondaPkg and sympy as a python dependency. it worked on the Julia linux docker image out of the box. thx for the hint.

This seems trickier than i thought. SymPy.jl relies on PyCall->Conda
I understand this setup does not guarantee automatic installation of the sympy python package but using PythonCall->CondaPkg would. let me check whether importing it using pythoncall ensures the same functionality as SymPy.jl

I got it to work with PythonCall as a backend and tested it in a separate branch. The issue is I don't get PythonCall to work with PrecompileTools. Do you have any experience with this?
It would be a petty sacrificing some speed for convenience.
On the PythonCall website it says during precompilation you must not interact with python...

and I got that fixed now as well. I'm not relying on python during recompilation after all.
have a look at the latest version. it should run out of the box. it does in the CI runs at least.
and thanks for the suggestion to use PythonCall that should make it easier for many users to get this up and running

Awesome! I'll check it out and finish my review next week

https://github.com/jverzani/SymPyCall.jl
Might be interesting

Yeah, I implemented an adapted version of their code in the latest version of MacroModelling. It works with CondaPkg now and the installation should work out of the box.
I asked the SymPyCall authors to register their package so that I can use that instead my hacky way.

Should have known it was not a coincidence 😎

Installation is working


[UNDERTOW-688] Make all methods on SessionListener default / no-op so  implementations can choose which ones they are interested in.

retest this please

I had been holding off on this until I decided what to do with JDK8 in 1.4.x, we have decided to require JDK8 so this is ok


How do I interpret the output of license_finder?

I have been running licence_finder in a virtualenv after I installed a tool called TMD with a bunch of dependencies (installed libraries).
When I run the license_finder I get the output:
Dependencies that need approval:
TMD, "", unknown

I assume the first entry TMD means a package (in this case the tool itself), the next entry is the version (none here), and the third entry unknown means what?
I thought that tool would find me a license I can use for the tool given the licenses of the dependencies? Maybe this is not what the tool does?

and the third entry unknown means what?

License.
A license of value unknown indicates that LicenseFinder was not able to detect it automatically, refer to this for more information.

@exilvm Yes there is no license yet for "TMD". I want to know what licenses are possible given the dependencies "TMD" relies on.
Is that possible to do with that tool? Maybe I have the completely wrong tool?
Does license_finder just list all licenses?

Hi @alex4200 Im not sure I fully understand your use case but what License Finder does is look through your code for package manager files (go.mod, package.json, build.gradle, etc) If we support you package manager, it will execute logic to find the dependencies installed via one of those files and then output the license for each if it finds one.
In your case, it clearly detected a package manager and inside of the relevant file, TMD is listed. I am not sure what manager you are using so I'm not sure what you are actually doing but the key thing here is that license finder does not assign licences. It will simply report if a given dependency has a license specified in some way.
Hope this helps!