AttributeError when running on a web server

Hi,

i have a code that works pretty well from command line but when launching by Apache web server via PHP, and Racket subprocess i got this error in the serer logs:

(Traceback (most recent call last):   File "/opt/homebrew/var/www/drive/cut_1D.py", line 59, in <module>     from_VTK = fb.from_VTK(data_path)                ^^^^^^^^^^^ AttributeError: module 'fibo' has no attribute 'from_VTK')

the original Python cut_1D.py code looks like that:

# before launch set : export PYTHONPATH=.:fibo
# python3.11 cut_1D.py data ./BepiColombo-Mio_MSO-orbit_1min_short.txt output
# added Damien Mattei

import numpy as np
import matplotlib.pyplot as plt
import fibo as fb
import sys

#from scipy.ndimage.filters import gaussian_filter as gf
# above is deprecated and will be removed
from scipy.ndimage import gaussian_filter as gf

from scipy.interpolate import RegularGridInterpolator

######################################################################
# Here you put hard-coded input parameters:
#  -) tars = list of fields/scalars to cut along the trajectory
#  -) cycle_min, cycle_max = limits of simulation cycle to cut
#  -) word = char string to name output file
######################################################################
tars = ['B','rhoe0']
cycle_min = 5000
cycle_max  = 8000
word = 'Mio'

#######################################################################
# Here you the paths to 3 files using sys
#######################################################################
data_path = sys.argv[1] # here you give path to run
traj_file = sys.argv[2] # here you give a trajectory in MSO coord
save_path = sys.argv[3] # here you give path to save extracted traj

#######################################################################
# Here you define two routines to change coordinates 
# MSO means Mercury-centered Solar Orbital, ie the frame to define a 
# spacecraft trajectory
#######################################################################
def coordinate_box_to_MSO(x,y,z):
    x_mso = -(x - xc)/R
    y_mso = -(y - yc)/R
    z_mso =  (z - zc)/R
    return x_mso, y_mso, z_mso
def coordinate_MSO_to_box(x,y,z):
    x_box = -(x*R - xc)
    y_box = -(y*R - yc)
    z_box =  (z*R + zc)
    return x_box, y_box, z_box

#######################################################################
# Here you load simulation parameters from file SimulationData.txt
# using routine in fibo/mod_from.py
#######################################################################
print()
print('Loading simulation parameters (SimulationData.txt)')
print()

from_VTK = fb.from_VTK(data_path)
from_VTK.get_meta(silent=False)
x = np.linspace(0,from_VTK.meta['xl'],from_VTK.meta['nx'])
y = np.linspace(0,from_VTK.meta['yl'],from_VTK.meta['ny'])
z = np.linspace(0,from_VTK.meta['zl'],from_VTK.meta['nz'])
nx,ny,nz = from_VTK.meta['nnn']
xc = from_VTK.meta['xc']
yc = from_VTK.meta['yc']
zc = from_VTK.meta['zc']+from_VTK.meta['Doff']
R = from_VTK.meta['R']

#######################################################################
# Here you open .txt with spacecraft trajectory and compute some stuff
#######################################################################
print()
print('Open .txt with spacecraft trajectory and compute some stuff')
print()

tt, xx, yy, zz = np.loadtxt(traj_file,unpack=True)
d = np.sqrt(xx**2+yy**2+zz**2)
i_CA = np.where(d==min(d))
tt = (tt-tt[i_CA])
Vx_array = []
Vy_array = []
Vz_array = []
xx1_box, yy1_box, zz1_box = coordinate_MSO_to_box(xx,yy,zz) # doit etre la trajectoire du spacecraft

#######################################################################
# Here you loop on the times of the simulations and on the tars to load
# the simulation data (the 3D cubes on data written in vtk), this is 
# done using the routines get_vect and get_scal in fibo/mod_from.py
#######################################################################

print()
print('loop on the times of the simulations and on the tars')
print()

print('from_VTK.meta[\'segcycles\']=',from_VTK.meta['segcycles'])
print()

for seg in from_VTK.meta['segcycles']:
    print()
    print('seg=',seg)
    print()
    if cycle_min<=seg<=cycle_max :
        print('LOAD->',seg)
        for tar in tars:

            print()
            print('tar=',tar)
            print()
            
            # open txt output file
            file_out = open(save_path+'/trajectory-near_'+word+'_'+tar+'_'+str(seg)+'.txt','w')
            file_out.write('#index\t X_MSO\t Y_MSO\t Z_MSO\t Vx\t Vy\t Vz\n')

            # check if tar is a scalar (a bit hard-coded, can be changed)
            if (('rho' in tar) or ('T' in tar)):
                scalar=True
            else:
                scalar=False

            # load data using fibo/mod_from.py
            # and interpolate onto the box grid
            if (scalar==False):
                Vect = from_VTK.get_vect(from_VTK.meta['name']+'_'+tar+'_'+str(seg),seg,fibo_obj=None,tar_var=tar,silent=True)
                fx  = RegularGridInterpolator((x,y,z), Vect[0])
                fy  = RegularGridInterpolator((x,y,z), Vect[1])
                fz  = RegularGridInterpolator((x,y,z), Vect[2])
            elif (scalar==True):
                Vect = from_VTK.get_scal(from_VTK.meta['name']+'_'+tar+'_'+str(seg),seg,fibo_obj=None,tar_var=tar,silent=True)
                fx = RegularGridInterpolator((x,y,z), Vect)

            # loop on trajectory points
            for ii in range(0,len(xx)):

                # print()
                # print('ii=',ii)
                # print()

                # if the traj. point is inside the box
                if((xx1_box[ii]>0)*(yy1_box[ii]>0)*(zz1_box[ii]>0)*(xx1_box[ii]<max(x))*(yy1_box[ii]<max(y))*(zz1_box[ii]<max(z))):

                    # interp field to traj. point
                    point = np.array([[xx1_box[ii],yy1_box[ii],zz1_box[ii]],[0,0,0]])
                    Vx_array.append(fx(point)[0])
                    if (scalar==False):
                        Vy_array.append(fy(point)[0])
                        Vz_array.append(fz(point)[0])
                    elif (scalar==True):
                        Vy_array.append(np.nan)
                        Vz_array.append(np.nan)

                # else point out of the box
                else:
                    Vx_array.append(np.nan)
                    Vy_array.append(np.nan)
                    Vz_array.append(np.nan)

                # write on output file
                file_out.write('%f\t%f\t%f\t%f\t%f\t%f\t%f\n'%(tt[ii],xx[ii],yy[ii],zz[ii],-Vx_array[ii],-Vy_array[ii],Vz_array[ii]))

            # close txt output file
            file_out.close()


problem is at line 59 but in command line the code used to ran prefectly, i suppose some environment variable missing…

mode deeply the python source code is in fibo subdir init.py:

#! /bin/env python
# coding: utf8

#---------------------------------------------------------------------------------------
#-(1)-----21.12.18----FDP:S,F-----------------------------------------------------------
#-(2)-----30.12.18----FDP:S,J,R---------------------------------------------------------
#-(3)-----02.04.19----FDP:S,P,L---------------------------------------------------------
#-(4)-----04.04.19----FDP:S,J,L---------------------------------------------------------
#---------------------------------------------------------------------------------------
#-(alpha)-19.07.19----FDP:S,J,L---------------------------------------------------------
#-(beta0)-12.11.19----FDP:S,F-----------------------------------------------------------
#-(beta1)-19.11.19----FDP:S-------------------------------------------------------------
#-(beta2)-25.11.19----FDP:S,L-----------------------------------------------------------
#-(beta3)-21.03.20----FDP:S-------------------------------------------------------------
#-(gamma)-03.06.21----FDP:S,J-----------------------------------------------------------
#---------------------------------------------------------------------------------------


from mod_from import  from_VTK
from mod_phybo import phybo


import mod_get
import mod_axis
import mod_extract
import mod_calc
import mod_find
import mod_comp
import mod_draw
import mod_print
import mod_extra


class fibo (mod_get.fibo_get,
            mod_axis.fibo_axis,
            mod_extract.fibo_extract,
            mod_calc.fibo_calc,
            mod_find.fibo_find,
            mod_comp.fibo_comp,
            mod_draw.fibo_draw,
            mod_print.fibo_print,
            mod_extra.fibo_extra):
  """
  fibo is a python object designed to contain your simulation data and perform authomatically simple operations on it 
  all functions are designed for data arrays of the form [nx,ny,nz] (no other indeces, please - this is done to keep routines light and free from for cycles)

  [fibo.data] means [str] in data or [np.ndarray(nx,ny,nz)]
  """
  
  def __init__(self,
      fibo_name):    #name of the set of data on which you work (part of simulation)

    self.fibo_name = str(fibo_name)

    self.data = {}  #dict of  np.ndarray(nx,ny,nz)
    self.pnts = {}  #dict of  np.ndarray(3,points)

    self.meta = {}  #dict of  meta_data - must be copied from the loaders
    self.stat = {}  #dict of  statistical values 

  #------------------------------------------------------------
  def help(self):

    print("Qu'est-ce que c'est que ce bordel ?")

    print('pippo = fb.fibo("pippo")')
    print('dir(fb)')
    print('dir(fb.fibo)')
    print('pippo.data.keys() --> list of data available')
    print('pippo.data["newname"] = pippo.data.pop("oldname")')
    print('np.unravel_index(np.argmax(...),np.shape(...))')

mod_from.py contains from_VTK :

#! /bin/env python

import collections 
import codecs

import numpy as np
import os
import pickle
import matplotlib as mpl
import matplotlib.pyplot as plt
import scipy.ndimage as ndm
import itertools as itt
import struct
import re
import time
import vtk
from vtk.util import numpy_support as VN
from vtk.numpy_interface import dataset_adapter as dsa
from vtk.numpy_interface import algorithms as algs
import xml.etree.ElementTree as ET

#---------------------------------------------------------------------------------------
#------fill-fibo-objects-from-various-sources-------------------------------------------
#-------or-simply-get-your-data---------------------------------------------------------
#---------------------------------------------------------------------------------------

#---------------------------------------------------------------------------------------
class from_VTK (object):

  def __init__(self, 
      address):
    """ 
    Creates the object to retrieve data from VTK files
    
    Parameters :
      - address      [address] where your data are (folder with segs inside)
    
    """
    self.address = address
    self.meta = {}

  #------------------------------------------------------------
  def get_meta(self,  #counts lines in file and calls the appropriate function to get the meta data
      extra_address = '',
      silent = True):
    """
    ------------------------------------------------------------------------------------
      fills the metadata list 
    ------------------------------------------------------------------------------------
    extra_address = ''      [address] to reach any subfolder where your meta-data are
    silent        = True    [bool] don't you want to see all infos printed on shell?
    ------------------------------------------------------------------------------------
    """
    
    with open(os.path.join(self.address,extra_address,'SimulationData.txt'),'r') as foo:
      line_number = len(foo.readlines())

    if line_number==35 : old_vers=True
    elif line_number>35 : old_vers=False
    
    self.get_meta_A(old_vers,extra_address)

    #---------get-dimensions-of-your-simulation----------

    self.meta['dx'] = self.meta['xl']/self.meta['nx']
    self.meta['dy'] = self.meta['yl']/self.meta['ny']
    self.meta['dz'] = self.meta['zl']/self.meta['nz']

    self.meta['nnn'] = (self.meta['nx'], self.meta['ny'], self.meta['nz'])
    self.meta['lll'] = (self.meta['xl'], self.meta['yl'], self.meta['zl'])
    self.meta['ddd'] = (self.meta['dx'], self.meta['dy'], self.meta['dz']) 

    self.meta['ppp'] = (False, False, False)       # HARD-CODED !!! 

    self.meta['x'] = np.arange(0.,self.meta['xl'],self.meta['dx'])
    try:
        self.meta['y'] = np.arange(0.,self.meta['yl'],self.meta['dy'])
    except:
        self.meta['y'] = np.array([0.])
    try:
        self.meta['z'] = np.arange(0.,self.meta['zl'],self.meta['dz'])
    except:
        self.meta['z'] = np.array([0.])


    #----------get-time-infos-from all-vtk-files----------------- 

    segments = [f for f in os.listdir(self.address) if f.split('.')[-1]=='vtk']
    for i in range(len(segments)):
        if i == 0:
          self.meta['name'] = segments[i].split('_')[0]
        segments[i] = segments[i].split('_')[-1].split('.')[0]
    segments = set(segments)
    segments = map(str, sorted(map(int, segments)))
    self.meta['segcycles']=[]
    self.meta['segtimes']=[]
    for seg in segments:
      self.meta['segcycles'].append(int(seg))
      self.meta['segtimes'].append(float(seg)*self.meta['dt'])
      

    #----------add-informations-on-species-----------------

    species  = []
    for isp in range(0,self.meta['nss']):
      if self.meta['sQOM'][isp]<0  : species.append('e'+str(isp))
      elif self.meta['sQOM'][isp]>0  : species.append('i'+str(isp))

    self.meta['species']  = species

    if self.meta['ny'] == 1:
      self.meta['space_dim'] = '1D'
    elif self.meta['nz'] == 1:
      self.meta['space_dim'] = '2D'
    else:
      self.meta['space_dim'] = '3D'

    #----------print-summary-----------------

    if not silent : 
      print('iPIC3D> cell number               :  ', self.meta['nnn'])
      print('iPIC3D> domain size               :  ', self.meta['lll'])
      print('iPIC3D> mesh spacing              :  ', self.meta['ddd'])
      print('iPIC3D> periodicity               :  ', self.meta['ppp'])
      print('iPIC3D> time step                 :  ', self.meta['dt'])
      print('iPIC3D> species                   :  ', self.meta['species'])
      for i in range(self.meta['nss']):
        print('          '+species[i]+' charge-over-mass           :  ', self.meta['sQOM'][i])

  #------------------------------------------------------------
  def get_meta_A(self,
      old_vers=False,
      extra_address = ''):
    """
    ------------------------------------------------------------------------------------
      extra routine, reads meta data from SimulationData.txt
    ------------------------------------------------------------------------------------
      old_vers      = False   [bool] is your simu older than 11/2021? means that I have changed the simulationdata.txt in ipic3d
      extra_address = ''      [address] to reach any subfolder where your meta-data are
    ------------------------------------------------------------------------------------
    """

    #get mesh infos from SimulationData.txt
    infos = open(os.path.join(self.address,extra_address,'SimulationData.txt'),'r')

    infos.readline() #---------------------------
    infos.readline() #-  Simulation Parameters  -
    infos.readline() #---------------------------
    self.meta['nss'] = int(infos.readline().split('=')[-1]) #number of species
    stag=[]
    sQOM=[]
    for i in range(self.meta['nss']):
      sQOM.append(float(infos.readline().split('=')[-1]))
    self.meta['sQOM'] = sQOM
    infos.readline() #---------------------------
    self.meta['xl'] = float(infos.readline().split('=')[-1]) #box physical dimensions
    self.meta['yl'] = float(infos.readline().split('=')[-1])
    self.meta['zl'] = float(infos.readline().split('=')[-1])
    self.meta['nx'] = int(infos.readline().split('=')[-1]) #box grid dimensions
    self.meta['ny'] = int(infos.readline().split('=')[-1])
    self.meta['nz'] = int(infos.readline().split('=')[-1])
    if not old_vers :
      infos.readline() #---------------------------
      self.meta['XLEN'] = int(infos.readline().split('=')[-1]) # MPI procs grid
      self.meta['YLEN'] = int(infos.readline().split('=')[-1])
      self.meta['ZLEN'] = int(infos.readline().split('=')[-1])
      infos.readline() #---------------------------
      self.meta['xc'] = float(infos.readline().split('=')[-1]) #planet position
      self.meta['yc'] = float(infos.readline().split('=')[-1])
      self.meta['zc'] = float(infos.readline().split('=')[-1])
      self.meta['R'] = float(infos.readline().split('=')[-1]) #planet radius
      self.meta['Doff'] = float(infos.readline().split('=')[-1])
      infos.readline() #---------------------------
      self.meta['SAL'] = int(infos.readline().split('=')[-1])
      self.meta['Nsal'] = int(infos.readline().split('=')[-1])
    infos.readline() #---------------------------
    self.meta['dt'] = float(infos.readline().split('=')[-1]) #timestep
    self.meta['nsteps'] = int(infos.readline().split('=')[-1]) #number of steps
    infos.readline() #---------------------------
    for i in range(self.meta['nss']):
      infos.readline() #rho init species
      infos.readline() #rho inject species
    infos.readline() #current sheet thickness
    self.meta['Bx0'] = float(infos.readline().split('=')[-1]) #Bx0
    self.meta['By0'] = float(infos.readline().split('=')[-1]) #By0
    self.meta['Bz0'] = float(infos.readline().split('=')[-1]) #Bz0
    if not old_vers :
      infos.readline() #---------------------------
      self.meta['Vx0'] = float(infos.readline().split('=')[-1]) #Vx0
      self.meta['Vy0'] = float(infos.readline().split('=')[-1]) #Vy0
      self.meta['Vz0'] = float(infos.readline().split('=')[-1]) #Vz0
      self.meta['vths'] = []
      for i in range(self.meta['nss']):
        self.meta['vths'].append(float(infos.readline().split('=')[-1])) #vth species
    infos.readline() #---------------------------
    infos.readline() #Smooth
    infos.readline() #2D smoothing
    infos.readline() #nvolte ?
    infos.readline() #GMRES error tolerance
    infos.readline() #CG error toletance
    infos.readline() # Mover error tolerance

    infos.readline() #---------------------------
    infos.readline() #Results saved in:
    infos.readline() #Restart saved in:

    infos.readline() #---------------------------
    infos.close()

    # attention il y a plusieurs versions de cette function!!!
  #------------------------------------------------------------
  def get_scal(self,
      tar_file,
      seg,
      fibo_obj = None,  
      tar_var = None,  
      double_y = False,
      silent = True):
    """ 
    Reads scalar from .vtk file
    
    Parameters :
      - tar_file           [str] target file to read (don't include '.vtk')
      - seg                [str] cycle of the simulation
      - fibo_obj = None    [None or fibo] fibo object you want to fill, else returns values 
      - tar_var = None     [None or str] name the.variable will be given
      - double_y = False   [bool] was your file printed twice in y?
      - silent = True      [bool] print status at the end?
    Returns :
      - scal               [fibo_var] 
    
    """  

    #create data vector, fill it!
    data_file = open(os.path.join(self.address,tar_file+'.vtk'),'r', errors='replace')

    if tar_var == None : 
      tar_var = data_file.readline().split()[0]+'%.8i'%int(seg)
    else : 
      tar_var = tar_var+'%.8i'%int(seg)
      data_file.readline()

    data_file.readline()
    data_format = data_file.readline()
    data_structure = data_file.readline().split()[1]
    self.meta['nx'], self.meta['ny'], self.meta['nz'] = map(int, data_file.readline().split()[1:4])
    data_file.readline()
    self.meta['dx'], self.meta['dy'], self.meta['dz'] = map(float, data_file.readline().split()[1:4])
    data_file.readline()
    data_file.readline()  #NB here you have the nx*ny*nz preduct
    data_file.readline()
    data_file.readline()

    data_file.close()

    if double_y : self.meta['ny'] = self.meta['ny']/2 #NB here you divide by two the box in y!

    if data_structure == 'STRUCTURED_POINTS': reader = vtk.vtkStructuredPointsReader() #here you can add other readers in case

    t0 = time.time()
    reader.SetFileName(os.path.join(self.address,tar_file+'.vtk'))
    t1 = time.time()
    print('DEBUG: SetFileName',t1-t0)
    reader.ReadAllScalarsOn()
    t2 = time.time()
    print('DEBUG: ReadAllVectors',t2-t1)
    reader.Update()
    t3 = time.time()
    print('DEBUG: Update',t3-t2)
    vtk_output = reader.GetOutput()
    t4 = time.time()
    print('DEBUG: GetOutput',t4-t3)

    if vtk_output.GetDimensions()[0] != self.meta['nx'] : print('ERROR: wrong number of cells along x (Nx)')
    if vtk_output.GetDimensions()[2] != self.meta['nz'] : print('ERROR: wrong number of cells along z (Nz)')
    if not double_y and vtk_output.GetDimensions()[1] != self.meta['ny'] :  print('ERROR: wrong number of cells along y (Ny) ; double_y=False')
    if double_y and vtk_output.GetDimensions()[1] != self.meta['ny']*2 :    print('ERROR: wrong number of cells along y (Ny) ; double_y=True')
        
    scal = VN.vtk_to_numpy(vtk_output.GetPointData().GetScalars())
    t5 = time.time()
    print('DEBUG: vtk_to_numpy',t5-t4)
    print('reader=',reader)
    print('vtk_output=',vtk_output)
    print('vect=',scal)

    if double_y :     scal = scal.reshape(self.meta['nz'],2*self.meta['ny'],self.meta['nx']).transpose(2,1,0) #recast flatten array to 3D array
    else :            scal = scal.reshape(self.meta['nz'],self.meta['ny'],self.meta['nx']) .transpose(2,1,0)

    if double_y : scal = scal[:,:self.meta['ny'],:]

    if (fibo_obj != None) :
      fibo_obj.data[tar_var] = scal
    else: 
      return scal

    if not silent:
      print('get_scal_from_VTK> data format             :  ', data_format)
      print('get_scal_from_VTK> data structure          :  ', data_structure)
      print('get_scal_from_VTK> grid dimensions         :  ', self.meta['nnn'])
      print('get_scal_from_VTK> grid size               :  ', self.meta['lll'])
      print('get_scal_from_VTK> grid spacing            :  ', self.meta['ddd'])
      if (fibo_obj != None) :
        print('get_scal_from_VTK> created fibo_obj.data['+tar_var+']')



        
  #------------------------------------------------------------
  def get_vect(self,
      tar_file,
      seg,
      fibo_obj = None,
      tar_var = None,
      double_y = False,
      silent=True):
    """ 
    Reads vector from .vtk file
    
    Parameters :
      - tar_file           [str] target file to read (don't include '.vtk')
      - fibo_obj = None    [None or fibo] fibo object you want to fill, else returns values 
      - tar_var = None     [None or str] name the.variable will be given
      - double_y = False   [bool] was your file printed twice in y?
    
    Returns :
      - scal               [fibo_var] 
    
    """

    #create data vector, fill it!
    data_file = open(os.path.join(self.address,tar_file+'.vtk'),'r',errors='replace') # b , binary but bug after

    print("DEBUG: mod_probe : tar_file =",tar_file); # added Damien Mattei
    
    if tar_var == None : 
      tar_var_x,tar_var_y,tar_var_z = data_file.readline().split()[0][1:-1].split(',')
      tar_var_x = tar_var_x+'%.8i'%int(seg)
      tar_var_y = tar_var_y+'%.8i'%int(seg)
      tar_var_z = tar_var_z+'%.8i'%int(seg)
    else : 
      tar_var_x = tar_var+'_x'+'%.8i'%int(seg)
      tar_var_y = tar_var+'_y'+'%.8i'%int(seg)
      tar_var_z = tar_var+'_z'+'%.8i'%int(seg)
      data_file.readline()

    data_file.readline()
    data_format = data_file.readline()
    data_structure = data_file.readline().split()[1]
    self.meta['nx'], self.meta['ny'], self.meta['nz'] = map(int, data_file.readline().split()[1:4])
    data_file.readline() # ici ORIGIN
    self.meta['dx'], self.meta['dy'], self.meta['dz'] = map(float, data_file.readline().split()[1:4])
    data_file.readline()
    data_file.readline()  #NB here you have the nx*ny*nz preduct
    data_file.readline()
   
    data_file.close()

    if double_y : self.meta['ny'] = self.meta['ny']/2  #NB here you divide by two the box in y!

    if data_structure == 'STRUCTURED_POINTS': reader = vtk.vtkStructuredPointsReader() #here you can add other readers in case
  
    t0 = time.time()
    reader.SetFileName(os.path.join(self.address,tar_file+'.vtk'))
    t1 = time.time()
    print('DEBUG: SetFileName',t1-t0)
    reader.ReadAllVectorsOn()
    t2 = time.time()
    print('DEBUG: ReadAllVectors',t2-t1)
    reader.Update()
    t3 = time.time()
    print('DEBUG: Update',t3-t2)
    vtk_output = reader.GetOutput()
    t4 = time.time()
    print('DEBUG: GetOutput',t4-t3)

    if vtk_output.GetDimensions()[0] != self.meta['nx'] : print('ERROR: wrong number of cells along x (Nx)')
    if vtk_output.GetDimensions()[2] != self.meta['nz'] : print('ERROR: wrong number of cells along z (Nz)')
    if not double_y and vtk_output.GetDimensions()[1] != self.meta['ny'] :  print('ERROR: wrong number of cells along y (Ny) ; double_y=False')
    if double_y and vtk_output.GetDimensions()[1] != self.meta['ny']*2 :    print('ERROR: wrong number of cells along y (Ny) ; double_y=True')
        
    vect = VN.vtk_to_numpy(vtk_output.GetPointData().GetArray(tar_var))
    t5 = time.time()
    print('DEBUG: vtk_to_numpy',t5-t4)
    print('reader=',reader)
    print('vtk_output=',vtk_output)
    print('vect=',vect)

    if double_y :
      vect_x = vect[:,0].reshape(self.meta['nz'],self.meta['ny']*2,self.meta['nx']).transpose(2,1,0)
      vect_y = vect[:,1].reshape(self.meta['nz'],self.meta['ny']*2,self.meta['nx']).transpose(2,1,0)
      vect_z = vect[:,2].reshape(self.meta['nz'],self.meta['ny']*2,self.meta['nx']).transpose(2,1,0)
    else :
      vect_x = vect[:,0].reshape(self.meta['nz'],self.meta['ny'],self.meta['nx']).transpose(2,1,0)
      vect_y = vect[:,1].reshape(self.meta['nz'],self.meta['ny'],self.meta['nx']).transpose(2,1,0)
      vect_z = vect[:,2].reshape(self.meta['nz'],self.meta['ny'],self.meta['nx']).transpose(2,1,0)
 
    if double_y : 
      vect_x = vect_x[:,:self.meta['ny'],:]
      vect_y = vect_y[:,:self.meta['ny'],:]
      vect_z = vect_z[:,:self.meta['ny'],:]

    if (fibo_obj != None) :
      fibo_obj.data[tar_var_x] = vect_x
      fibo_obj.data[tar_var_y] = vect_y
      fibo_obj.data[tar_var_z] = vect_z
    else: return np.array([vect_x, vect_y, vect_z])

    if not silent:
      print('get_vect_from_VTK> data format             :  ', data_format)
      print('get_vect_from_VTK> data structure          :  ', data_structure)
      print('get_vect_from_VTK> grid dimensions         :  ', self.meta['nnn'])
      print('get_vect_from_VTK> grid size               :  ', self.meta['lll'])
      print('get_vect_from_VTK> grid spacing            :  ', self.meta['ddd'])
      if (fibo_obj != None) :
        print('get_vect_from_VTK> created fibo_obj.data['+tar_var_x+']') 
        print('get_vect_from_VTK> created fibo_obj.data['+tar_var_y+']') 
        print('get_vect_from_VTK> created fibo_obj.data['+tar_var_z+']') 

#---------------------------------------------------------------------------------------
class from_HDF5 (object):

  def __init__(self, 
      address):
    """ 
    Creates the object to retrieve data from HDF5 files
    
    Parameters :
      - address      [address] where your data are (folder with segs inside)
    
    """
    self.address = address
    self.meta = {}

  #------------------------------------------------------------
  def get_scal(self,
      tar_file,
      seg,
      path,
      fibo_obj = None,  
      tar_var = None,  
      double_y = False,
      silent = True):
    """ 
    Reads scalar from .h5 file
    
    Parameters :
      - tar_file           [str] target file to read (don't include '.h5')
      - seg                [str] cycle of the simulation
      - path               [str] path to field inside hdf5 dictionary               
      - fibo_obj = None    [None or fibo] fibo object you want to fill, else returns values 
      - tar_var = None     [None or str] name the.variable will be given
      - double_y = False   [bool] was your file printed twice in y?
      - silent = True      [bool] print status at the end?
    Returns :
      - scal               [fibo_var]
    
    """  

    #create data vector, fill it!
    data_file = h5.File(os.path.join(self.address,tar_file+'.h5'),'r')

    tar_var = tar_var+'%.8i'%int(seg)

    scal = data_file[path]

    if vtk_output.GetDimensions()[0] != self.meta['nx'] : print('ERROR: wrong number of cells along x (Nx)')
    if vtk_output.GetDimensions()[2] != self.meta['nz'] : print('ERROR: wrong number of cells along z (Nz)')
    if not double_y and vtk_output.GetDimensions()[1] != self.meta['ny'] :  print('ERROR: wrong number of cells along y (Ny) ; double_y=False')
    if double_y and vtk_output.GetDimensions()[1] != self.meta['ny']*2 :    print('ERROR: wrong number of cells along y (Ny) ; double_y=True')
        
    scal = VN.vtk_to_numpy(vtk_output.GetPointData().GetScalars())
    t5 = time.time()
    print('DEBUG: vtk_to_numpy',t5-t4)
    print('reader=',reader)
    print('vtk_output=',vtk_output)
    print('vect=',scal)

    if double_y :     scal = scal.reshape(self.meta['nz'],2*self.meta['ny'],self.meta['nx']).transpose(2,1,0) #recast flatten array to 3D array
    else :            scal = scal.reshape(self.meta['nz'],self.meta['ny'],self.meta['nx']) .transpose(2,1,0)

    if double_y : scal = scal[:,:self.meta['ny'],:]

    if (fibo_obj != None) :
      fibo_obj.data[tar_var] = scal
    else: 
      return scal

    if not silent:
      print('get_scal_from_VTK> data format             :  ', data_format)
      print('get_scal_from_VTK> data structure          :  ', data_structure)
      print('get_scal_from_VTK> grid dimensions         :  ', self.meta['nnn'])
      print('get_scal_from_VTK> grid size               :  ', self.meta['lll'])
      print('get_scal_from_VTK> grid spacing            :  ', self.meta['ddd'])
      if (fibo_obj != None) :
        print('get_scal_from_VTK> created fibo_obj.data['+tar_var+']')



        # attention il y a plusieurs versions de cette function!!! celle dessous ne devrait pas etre lancee
  #------------------------------------------------------------
  def get_vect(self,
      tar_file,
      seg,
      fibo_obj = None,
      tar_var = None,
      double_y = False,
      silent=True):
    """ 
    Reads vector from .vtk file
    
    Parameters :
      - tar_file           [str] target file to read (don't include '.vtk')
      - fibo_obj = None    [None or fibo] fibo object you want to fill, else returns values 
      - tar_var = None     [None or str] name the.variable will be given
      - double_y = False   [bool] was your file printed twice in y?
    
    Returns :
      - scal               [fibo_var] 
    
    """

    #create data vector, fill it!
    data_file = open(os.path.join(self.address,tar_file+'.vtk'),'r')

    if tar_var == None : 
      tar_var_x,tar_var_y,tar_var_z = data_file.readline().split()[0][1:-1].split(',')
      tar_var_x = tar_var_x+'%.8i'%int(seg)
      tar_var_y = tar_var_y+'%.8i'%int(seg)
      tar_var_z = tar_var_z+'%.8i'%int(seg)
    else : 
      tar_var_x = tar_var+'_x'+'%.8i'%int(seg)
      tar_var_y = tar_var+'_y'+'%.8i'%int(seg)
      tar_var_z = tar_var+'_z'+'%.8i'%int(seg)
      data_file.readline()

    data_file.readline()
    data_format = data_file.readline()
    data_structure = data_file.readline().split()[1]
    self.meta['nx'], self.meta['ny'], self.meta['nz'] = map(int, data_file.readline().split()[1:4])
    #data_file.readline()
    self.meta['dx'], self.meta['dy'], self.meta['dz'] = map(float, data_file.readline().split()[1:4])
    data_file.readline()  # vtk version 5.1 ici ORIGIN
    data_file.readline()  #NB here you have the nx*ny*nz preduct
    data_file.readline()
   
    data_file.close()

    if double_y : self.meta['ny'] = self.meta['ny']/2  #NB here you divide by two the box in y!

    if data_structure == 'STRUCTURED_POINTS': reader = vtk.vtkStructuredPointsReader() #here you can add other readers in case
  
    t0 = time.time()
    reader.SetFileName(os.path.join(self.address,tar_file+'.vtk'))
    t1 = time.time()
    print('DEBUG: SetFileName',t1-t0)
    reader.ReadAllVectorsOn()
    t2 = time.time()
    print('DEBUG: ReadAllVectors',t2-t1)
    reader.Update()
    t3 = time.time()
    print('DEBUG: Update',t3-t2)
    vtk_output = reader.GetOutput()
    t4 = time.time()
    print('DEBUG: GetOutput',t4-t3)

    if vtk_output.GetDimensions()[0] != self.meta['nx'] : print('ERROR: wrong number of cells along x (Nx)')
    if vtk_output.GetDimensions()[2] != self.meta['nz'] : print('ERROR: wrong number of cells along z (Nz)')
    if not double_y and vtk_output.GetDimensions()[1] != self.meta['ny'] :  print('ERROR: wrong number of cells along y (Ny) ; double_y=False')
    if double_y and vtk_output.GetDimensions()[1] != self.meta['ny']*2 :    print('ERROR: wrong number of cells along y (Ny) ; double_y=True')
        
    vect = VN.vtk_to_numpy(vtk_output.GetPointData().GetArray(tar_var))
    t5 = time.time()
    print('DEBUG: vtk_to_numpy',t5-t4)
    print('reader=',reader)
    print('vtk_output=',vtk_output)
    print('vect=',vect)

    if double_y :
      vect_x = vect[:,0].reshape(self.meta['nz'],self.meta['ny']*2,self.meta['nx']).transpose(2,1,0)
      vect_y = vect[:,1].reshape(self.meta['nz'],self.meta['ny']*2,self.meta['nx']).transpose(2,1,0)
      vect_z = vect[:,2].reshape(self.meta['nz'],self.meta['ny']*2,self.meta['nx']).transpose(2,1,0)
    else :
      vect_x = vect[:,0].reshape(self.meta['nz'],self.meta['ny'],self.meta['nx']).transpose(2,1,0)
      vect_y = vect[:,1].reshape(self.meta['nz'],self.meta['ny'],self.meta['nx']).transpose(2,1,0)
      vect_z = vect[:,2].reshape(self.meta['nz'],self.meta['ny'],self.meta['nx']).transpose(2,1,0)
 
    if double_y : 
      vect_x = vect_x[:,:self.meta['ny'],:]
      vect_y = vect_y[:,:self.meta['ny'],:]
      vect_z = vect_z[:,:self.meta['ny'],:]

    if (fibo_obj != None) :
      fibo_obj.data[tar_var_x] = vect_x
      fibo_obj.data[tar_var_y] = vect_y
      fibo_obj.data[tar_var_z] = vect_z
    else: return np.array([vect_x, vect_y, vect_z])

    if not silent:
      print('get_vect_from_VTK> data format             :  ', data_format)
      print('get_vect_from_VTK> data structure          :  ', data_structure)
      print('get_vect_from_VTK> grid dimensions         :  ', self.meta['nnn'])
      print('get_vect_from_VTK> grid size               :  ', self.meta['lll'])
      print('get_vect_from_VTK> grid spacing            :  ', self.meta['ddd'])
      if (fibo_obj != None) :
        print('get_vect_from_VTK> created fibo_obj.data['+tar_var_x+']') 
        print('get_vect_from_VTK> created fibo_obj.data['+tar_var_y+']') 
        print('get_vect_from_VTK> created fibo_obj.data['+tar_var_z+']') 


again there is no error on the command line.

note that if i unset PYTHONPATH on command line i got a relative error but not exactly the same:

(base) mattei@MacBook-Pro-Touch-Bar drive % unset PYTHONPATH
(base) mattei@MacBook-Pro-Touch-Bar drive % time python3.11 cut_1D.py data ./BepiColombo-Mio_MSO-orbit_1min_short.txt output 
Traceback (most recent call last):
  File "/Users/mattei/drive/cut_1D.py", line 8, in <module>
    import fibo as fb
  File "/Users/mattei/drive/fibo/__init__.py", line 19, in <module>
    from mod_from import  from_VTK
ModuleNotFoundError: No module named 'mod_from'
python3.11 cut_1D.py data ./BepiColombo-Mio_MSO-orbit_1min_short.txt output  1,81s user 0,45s system 381% cpu 0,591 total

addendum:

Racket code that launch Python process looks like that:

;; setting Python paths
	(define python-path (getenv "PYTHONPATH"))
	(display "interpole-fields : PYTHONPATH=") (display python-path) (newline)
	(when (not python-path)
	      (display "interpole-fields : setting PYTHONPATH") (newline)
	      (putenv "PYTHONPATH" ".:fibo")
	      {python-path <- (getenv "PYTHONPATH")}
	      (display "interpole-fields : PYTHONPATH=") (display python-path) (newline))
	
	(define-values (subby stdout stdin stderr) (subprocess #f #f #f
							       "/usr/bin/env"
							       "/Library/Frameworks/Python.framework/Versions/3.11/bin/python3.11"
							       "cut_1D.py"
							       "../Data" ;"data"
							       "BepiColombo-Mio_MSO-orbit_1min_short.txt"
							       "output"))
	(display "subby=") (display subby) (newline)
	(subprocess-wait subby)
	(define err-lns (port->lines stderr))
	(display err-lns) (newline)
	(define len-err-lns (length err-lns))
	(display "number of lines in stderr=") (display len-err-lns) (newline)

and PHP code look like this:


$this->cmd= "./drive/interpole_fields";


$this->warning .= " SCHEME+ command=".$this->cmd;

......

$message=exec($this->cmd." 0>&1",$outp,$retc); // execute the command line
        // $message=exec($this->cmd." 2>&1",$outp,$retc);		
        $msg = $msg.$message.'['.$retc.']|'; // concatenate return message
	$tmp3=print_r($outp, true);
	file_put_contents('php://stderr', print_r("GeneralReturn  : msg=$msg\n tmp3=$tmp3\n", TRUE));

if i create an other UNIX user and i test in command line i got the same error as web server.

Should be an environment error with Python, as it only works in mine and not others…

the problem was coming that some file code was not readable by the web server and python sub process.

Also there was no python environment created for the web server

python -m venv myvenv

a pity that python reported a different error instead of a read access