diff --git a/examples/000_build_executable/000_build_executable.py b/examples/000_build_executable/000_build_executable.py
deleted file mode 100644
index d160494..0000000
--- a/examples/000_build_executable/000_build_executable.py
+++ /dev/null
@@ -1,4 +0,0 @@
-import xboinc as xb
-
-source_files = xb.generate_executable_source()
-
diff --git a/examples/000_build_executable/001mac_compile_executable.sh b/examples/000_build_executable/001mac_compile_executable.sh
deleted file mode 100644
index 3899404..0000000
--- a/examples/000_build_executable/001mac_compile_executable.sh
+++ /dev/null
@@ -1 +0,0 @@
-clang main.c -o xboinc_executable
diff --git a/examples/000_build_executable/001msys2_compile_executable.sh b/examples/000_build_executable/001msys2_compile_executable.sh
deleted file mode 100755
index 6fe9c0f..0000000
--- a/examples/000_build_executable/001msys2_compile_executable.sh
+++ /dev/null
@@ -1 +0,0 @@
-gcc main.c -o xboinc_executable -lm
diff --git a/examples/001_simple_line/001_build_input.py b/examples/001_simple_line/001_build_input.py
deleted file mode 100644
index 28d3d15..0000000
--- a/examples/001_simple_line/001_build_input.py
+++ /dev/null
@@ -1,13 +0,0 @@
-import xtrack as xt
-import xpart as xp
-import xboinc as xb
-
-# Simulation input
-num_turns = 10
-line = xt.Line(elements=[
- xt.Drift(length=1.0), xt.Multipole(knl=[1e-6]), xt.Drift(length=1.0)])
-particles = xp.Particles(mass0=xp.PROTON_MASS_EV, p0c=7e12, x=[1e-3,2e-3,3e-3])
-
-# Assemble data structure
-xb.build_input_file(line=line, particles=particles, num_turns=num_turns,
- name='xboinc_input.bin')
\ No newline at end of file
diff --git a/examples/001_simple_line/002_run_executable.sh b/examples/001_simple_line/002_run_executable.sh
deleted file mode 100755
index ad355a8..0000000
--- a/examples/001_simple_line/002_run_executable.sh
+++ /dev/null
@@ -1 +0,0 @@
-../000_build_executable/xboinc_executable
diff --git a/examples/001_simple_line/003_read_output.py b/examples/001_simple_line/003_read_output.py
deleted file mode 100644
index 2529e77..0000000
--- a/examples/001_simple_line/003_read_output.py
+++ /dev/null
@@ -1,16 +0,0 @@
-import numpy as np
-
-import xboinc as xb
-
-# Read output
-filename = 'sim_state_out.bin'
-sim_state = xb.read_output_file(filename)
-
-# Look at particles state
-particles = sim_state.particles
-
-assert np.all(particles.s == 20)
-assert np.all(particles.at_turn == 10)
-assert sim_state.i_turn == 10
-
-print('All checks passed!')
\ No newline at end of file
diff --git a/examples/002_lhc/001_build_input.py b/examples/002_lhc/001_build_input.py
deleted file mode 100644
index 6e0f5cf..0000000
--- a/examples/002_lhc/001_build_input.py
+++ /dev/null
@@ -1,25 +0,0 @@
-import json
-import numpy as np
-
-import xtrack as xt
-import xpart as xp
-import xboinc as xb
-
-filename = xt._pkg_root.parent.joinpath(
- 'test_data/lhc_with_bb/line_and_particle.json')
-
-with open(filename, 'r') as fid:
- input_data = json.load(fid)
-
-# We add some particles
-input_data['particle']['x'] += np.linspace(0, 1e-3, 10)
-
-# Simulation input
-num_turns = 1000
-line = xt.Line.from_dict(input_data['line'])
-particles = xp.Particles.from_dict(input_data['particle'])
-
-# Assemble data structure
-xb.build_input_file(
- line=line, particles=particles, num_turns=num_turns, checkpoint_every=100,
- name='xboinc_input.bin')
diff --git a/examples/002_lhc/002_run_executable.sh b/examples/002_lhc/002_run_executable.sh
deleted file mode 100755
index ad355a8..0000000
--- a/examples/002_lhc/002_run_executable.sh
+++ /dev/null
@@ -1 +0,0 @@
-../000_build_executable/xboinc_executable
diff --git a/examples/002_lhc/003_read_output.py b/examples/002_lhc/003_read_output.py
deleted file mode 100644
index 7af5833..0000000
--- a/examples/002_lhc/003_read_output.py
+++ /dev/null
@@ -1,16 +0,0 @@
-import numpy as np
-
-import xboinc as xb
-
-# Read output
-filename = 'sim_state_out.bin'
-sim_state = xb.read_output_file(filename)
-
-# Look at particles state
-particles = sim_state.particles
-
-assert np.allclose(particles.s, 0, rtol=1e-6, atol=0)
-assert np.all(particles.at_turn == 1000)
-assert sim_state.i_turn == 1000
-
-print('All checks passed!')
diff --git a/examples/002_lhc/mac_input/xboinc_input.bin b/examples/002_lhc/mac_input/xboinc_input.bin
deleted file mode 100644
index 3cf0dec..0000000
Binary files a/examples/002_lhc/mac_input/xboinc_input.bin and /dev/null differ
diff --git a/examples/002_lhc/windows_output/sim_state_out.bin b/examples/002_lhc/windows_output/sim_state_out.bin
deleted file mode 100644
index df90d81..0000000
Binary files a/examples/002_lhc/windows_output/sim_state_out.bin and /dev/null differ
diff --git a/examples/003_boinc/000_build_executable.py b/examples/003_boinc/000_build_executable.py
deleted file mode 100644
index d160494..0000000
--- a/examples/003_boinc/000_build_executable.py
+++ /dev/null
@@ -1,4 +0,0 @@
-import xboinc as xb
-
-source_files = xb.generate_executable_source()
-
diff --git a/examples/003_boinc/002_read_output.py b/examples/003_boinc/002_read_output.py
deleted file mode 100644
index 311edc5..0000000
--- a/examples/003_boinc/002_read_output.py
+++ /dev/null
@@ -1,16 +0,0 @@
-import numpy as np
-
-import xboinc as xb
-
-# Read output
-filename = 'out'
-sim_state = xb.read_output_file(filename)
-
-# Look at particles state
-particles = sim_state.particles
-
-assert np.allclose(particles.s, 2.665888e+04*1000, rtol=1e-6, atol=0)
-assert np.all(particles.at_turn == 1000)
-assert sim_state.i_turn == 1000
-
-print('All checks passed!')
diff --git a/examples/003_boinc/Makefile b/examples/003_boinc/Makefile
deleted file mode 100644
index 1501f17..0000000
--- a/examples/003_boinc/Makefile
+++ /dev/null
@@ -1,89 +0,0 @@
-# This should work on Linux. Modify as needed for other platforms.
-
-BOINC_SOURCE_API_DIR = $(BOINC_DIR)/api
-BOINC_SOURCE_LIB_DIR = $(BOINC_DIR)/lib
-BOINC_SOURCE_ZIP_DIR = $(BOINC_DIR)/zip
-FREETYPE_DIR = /usr/include/freetype2
-
-BOINC_API_DIR = $(BOINC_SOURCE_API_DIR)
-BOINC_LIB_DIR = $(BOINC_SOURCE_LIB_DIR)
-BOINC_ZIP_DIR = $(BOINC_SOURCE_ZIP_DIR)
-
-#MAKEFILE_LDFLAGS = -lpthread libstdc++.a
-MAKEFILE_LDFLAGS = -lpthread libstdc++.a -static
-MAKEFILE_STDLIB = libstdc++.a
-
-CXXFLAGS += -g \
- -Wall -W -Wshadow -Wpointer-arith -Wcast-qual -Wcast-align -Wwrite-strings -fno-common \
- -DAPP_GRAPHICS \
- -I$(BOINC_DIR) \
- -I$(BOINC_SOURCE_API_DIR) \
- -I$(BOINC_SOURCE_LIB_DIR) \
- -I$(BOINC_SOURCE_ZIP_DIR) \
- -I$(FREETYPE_DIR) \
- -L$(BOINC_API_DIR) \
- -L$(BOINC_LIB_DIR) \
- -L/usr/X11R6/lib \
- -L.
-
-# to get the graphics app to compile you may need to install some packages
-# e.g. ftgl-devel.x86_64
-#
-# You may have to change the paths for your system.
-
-LIBGLUT = -lglut
-LIBGLU = -lGLU
-LIBGL= -lGL
-LIBUI = -lX11 -lXmu
-LIBFTGL = -lftgl
-LIBJPEG = -ljpeg
-
-ifdef BUILD_WITH_VCPKG
- BUILD_DIR = $(BOINC_DIR)/3rdParty/linux
- VCPKG_DIR ?= $(BUILD_DIR)/vcpkg/installed/x64-linux
-
- CXXFLAGS += \
- -I$(VCPKG_DIR)/include \
- -L$(VCPKG_DIR)/lib
-
- LIBUI = -lX11 -lXmu -lXrandr -lXxf86vm -lXi
- LIBFTGL = -lftgl -lfreetype -lpng -lbz2 -lbrotlidec-static -lbrotlienc-static -lbrotlicommon-static -lz
-endif
-
-ifdef BUILD_WITH_MINGW
- LIBGLUT = -lfreeglut_static
- LIBGLU = -lglu32
- LIBGL= -lopengl32
- LIBUI = -lgdi32 -lwinmm
- LIBFTGL = -lftgl -lfreetype -lpng -lbz2 -lbrotlidec-static -lbrotlienc-static -lbrotlicommon-static -lz
-endif
-
-PROGS = xtrack
-# make this optional so compile doesn't break on systems without OpenGL
-
-$(info All PROGS=$(PROGS))
-
-all: $(PROGS)
-
-libstdc++.a:
- ln -s `$(CXX) -print-file-name=libstdc++.a`
-
-ttfont.cpp:
- ln -s ../../api/ttfont.cpp .
-
-clean: distclean
-
-distclean:
- /bin/rm -f $(PROGS) $(addsuffix .exe, $(PROGS)) *.o libstdc++.a ttfont.cpp
-
-install: xtrack
-
-# specify library paths explicitly (rather than -l)
-# because otherwise you might get a version in /usr/lib etc.
-
-xtrack: xtrack.o $(MAKEFILE_STDLIB) $(BOINC_API_DIR)/libboinc_api.a $(BOINC_LIB_DIR)/libboinc.a
- $(CXX) $(CXXFLAGS) $(CPPFLAGS) $(LDFLAGS) -o xtrack xtrack.o \
- -o xboinc_executable -lm \
- -lboinc_api -lboinc $(MAKEFILE_LDFLAGS) \
- $(STDCPPTC)
-
diff --git a/examples/003_boinc/cleanall.sh b/examples/003_boinc/cleanall.sh
deleted file mode 100644
index a0accb9..0000000
--- a/examples/003_boinc/cleanall.sh
+++ /dev/null
@@ -1,11 +0,0 @@
-rm boinc_finish_called
-rm checkpoint.bin
-rm libstdc++.a
-rm main.c
-rm out
-rm sim_config.h
-rm stderr.txt
-rm xboinc_executable.exe
-rm xboinc_input.bin
-rm xtrack.o
-rm xtrack_tracker.h
diff --git a/examples/003_boinc/client_state_save.xml b/examples/003_boinc/client_state_save.xml
deleted file mode 100644
index fa0c036..0000000
--- a/examples/003_boinc/client_state_save.xml
+++ /dev/null
@@ -1,68 +0,0 @@
-
-
- 1e9
- 2e9
- 2e9
- 1e11
- 1e11
-
-
- http://test.test
- test_project
-
-
-
- test_app
- test_app
-
-
-
- xboinc_executable
-
- 1
-
-
- input.bin
- 1
-
-
- output.bin
-
- 1e7
-
-
-
-
-
-
- test_app
- 6.3.0
-
- xboinc_executable
-
-
-
-
-
- test_wu
- test_app
-
- input.bin
- xboinc_input.bin
-
-
-
-
- test_result
- test_wu
- 2
- 2e9
-
- output.bin
- out
-
-
-
-3
-
-
diff --git a/examples/003_boinc/xtrack.cpp b/examples/003_boinc/xtrack.cpp
deleted file mode 100644
index 8229ed7..0000000
--- a/examples/003_boinc/xtrack.cpp
+++ /dev/null
@@ -1,298 +0,0 @@
-// This file is part of BOINC.
-// http://boinc.berkeley.edu
-// Copyright (C) 2008 University of California
-//
-// BOINC is free software; you can redistribute it and/or modify it
-// under the terms of the GNU Lesser General Public License
-// as published by the Free Software Foundation,
-// either version 3 of the License, or (at your option) any later version.
-//
-// BOINC is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-// See the GNU Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public License
-// along with BOINC. If not, see .
-
-// command line options
-// --cpu_time N: use about N CPU seconds after copying files
-// --critical_section: run most of the time in a critical section
-// --early_exit: exit(10) after 30 chars
-// --early_crash: crash after 30 chars
-// --run_slow: sleep 1 second after each character
-// --trickle_up: sent a trickle-up message
-// --trickle_down: receive a trickle-up message
-// --network_usage: tell the client we used some network
-
-#include
-#ifndef NULL
- #define NULL 0
-#endif
-#include
-
-#include "xtrack_tracker.h"
-#include "sim_config.h"
-
-#ifdef _WIN32
-#include "boinc_win.h"
-#else
-#include "config.h"
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#endif
-
-#include "str_util.h"
-#include "util.h"
-#include "filesys.h"
-#include "boinc_api.h"
-#include "mfile.h"
-#include "graphics2.h"
-#include "xtrack.h"
-
-#include
-
-#ifdef APP_GRAPHICS
-UC_SHMEM* shmem;
-#endif
-
-using std::string;
-
-#define CHECKPOINT_FILE "checkpoint.bin"
-#define INPUT_FILENAME "xboinc_input.bin"
-#define OUTPUT_FILENAME "out"
-
-bool run_slow = false;
-bool early_exit = false;
-bool early_crash = false;
-bool early_sleep = false;
-bool trickle_up = false;
-bool trickle_down = false;
-bool critical_section = false; // run most of the time in a critical section
-bool report_fraction_done = true;
-bool network_usage = false;
-double cpu_time = 20, comp_result;
-
-int8_t* file_to_buffer(FILE* sim_fid, int8_t* buf_in){
-
- //FILE *sim_fid;
- int8_t *buf;
-
- // Get buffer
- //sim_fid = fopen(filename, "rb");
- if (!sim_fid){
- return NULL;
- }
- fseek(sim_fid, 0L, SEEK_END);
- unsigned long filesize = ftell(sim_fid);
- fseek(sim_fid, 0L, SEEK_SET);
- if (buf_in){
- printf("Reusing buffer\n");
- buf = buf_in;
- }
- else{
- buf = (int8_t*)malloc(filesize*sizeof(int8_t));
- }
- fread(buf, sizeof(int8_t), filesize, sim_fid);
- fclose(sim_fid);
-
- return (buf);
-}
-
-int do_checkpoint(SimConfig sim_config, SimStateData sim_state) {
-
- int retval;
- FILE *chkp_fid;
- char resolved_name[512], buf[256];
-
- boinc_resolve_filename(CHECKPOINT_FILE, resolved_name, sizeof(resolved_name));
-
- chkp_fid = boinc_fopen(resolved_name, "wb");
- if (!chkp_fid) {
- fprintf(stderr,
- "%s Couldn't find checkpoint file, name %s.\n",
- boinc_msg_prefix(buf, sizeof(buf)), resolved_name);
- return 1;
- }
-
- printf("Checkpointing turn %d!\n", (int) SimStateData_get_i_turn(sim_state));
-
- fwrite(SimConfig_getp_sim_state(sim_config), sizeof(int8_t), SimConfig_get_sim_state_size(sim_config), chkp_fid);
-
- fclose(chkp_fid);
-
- return 0;
-}
-
-
-int main(int argc, char **argv) {
- int i;
- int c, nchars = 0, retval, n;
- double fsize, fd;
- char input_path[512], output_path[512], chkpt_path[512], buf[256];
- FILE* out;
- FILE* state, *infile;
-
- for (i=0; i 0 && SimStateData_get_i_turn(sim_state) % checkpoint_every == 0) ){
- retval = do_checkpoint(sim_config, sim_state);
- if (retval) {
- fprintf(stderr, "%s APP: xtrack checkpoint failed %d\n", boinc_msg_prefix(buf, sizeof(buf)));
- exit(retval);
- }
- boinc_checkpoint_completed();
- }
-
- if (report_fraction_done) {
- fd = (int)SimStateData_get_i_turn(sim_state) / (int)num_turns;
- if (cpu_time) fd /= 2;
- boinc_fraction_done(fd);
- }
-
- }
-
- // Quick check
- //for (int ii=0; ii("example_app"),
- const_cast("sample trickle message")
- );
- }
-
- if (trickle_down) {
- boinc_sleep(10);
- retval = boinc_receive_trickle_down(buf, sizeof(buf));
- if (!retval) {
- fprintf(stderr, "Got trickle-down message: %s\n", buf);
- }
- }
-
-
- boinc_fraction_done(1);
-
- boinc_finish(0);
-}
-
diff --git a/examples/003_boinc/xtrack.h b/examples/003_boinc/xtrack.h
deleted file mode 100644
index 6aff662..0000000
--- a/examples/003_boinc/xtrack.h
+++ /dev/null
@@ -1,40 +0,0 @@
-// This file is part of BOINC.
-// http://boinc.berkeley.edu
-// Copyright (C) 2008 University of California
-//
-// BOINC is free software; you can redistribute it and/or modify it
-// under the terms of the GNU Lesser General Public License
-// as published by the Free Software Foundation,
-// either version 3 of the License, or (at your option) any later version.
-//
-// BOINC is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-// See the GNU Lesser General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public License
-// along with BOINC. If not, see .
-
-#include "boinc_api.h"
-
-struct UC_SHMEM {
- double update_time;
- double fraction_done;
- double cpu_time;
- BOINC_STATUS status;
- int countdown;
- // graphics app sets this to 5 repeatedly,
- // main program decrements it once/sec.
- // If it's zero, don't bother updating shmem
-};
-
-#ifdef _WIN32
-
-extern "C" {
-
-__declspec( dllimport ) char* xtrack_dll_version();
-
-};
-
-#endif
-
diff --git a/examples/004_submissions/001_sub_noloop.py b/examples/004_submissions/001_sub_noloop.py
deleted file mode 100644
index cb8dceb..0000000
--- a/examples/004_submissions/001_sub_noloop.py
+++ /dev/null
@@ -1,51 +0,0 @@
-import json
-import glob
-import tarfile
-import itertools
-
-import numpy as np
-
-import xtrack as xt
-import xpart as xp
-import xboinc as xb
-
-eos = ''
-user = 'ddicroce' # this should be read from a config json in the eos written by the boinc server
-name = 'test_noloop'
-
-filename = xt._pkg_root.parent.joinpath(
- 'test_data/lhc_with_bb/line_and_particle.json')
-
-with open(filename, 'r') as fid:
- input_data = json.load(fid)
-
-
-# loop or anything that user wishes
-nparticles = 6000 # approximate number of particles to be generated
-ndims = 2
-dim_names = ['x', 'y']
-particles_per_dim = int(round(nparticles ** (1.0/ndims)))
-coords = list(itertools.product(*[np.linspace(0, 1e-3, particles_per_dim) for i in range(ndims)]))
-
-for dim_name in dim_names:
- input_data['particle'][dim_name] = []
-
-for coord in coords:
- for i, dim_name in enumerate(dim_names):
- input_data['particle'][dim_name].append(coord[i])
-
-for dim_name in dim_names:
- input_data['particle'][dim_name] = np.array(input_data['particle'][dim_name])[:nparticles]
-
-print('# particles:', len(input_data['particle'][dim_names[-1]]), ' | ', particles_per_dim, ' per dimension') # real number of particles
-
-# Simulation input
-num_turns = 1000
-line = xt.Line.from_dict(input_data['line'])
-particles = xp.Particles.from_dict(input_data['particle'])
-
-job_name = name
-xb.prepare_job(name=name, user=user, job_name=job_name, num_turns=num_turns, line=line, particles=particles, checkpoint_every=100)
-
-#xb.prepare_study(name=name)
-xb.submit_study(name=name, eosdir=eosdir)
diff --git a/examples/004_submissions/002_submission.py b/examples/004_submissions/002_submission.py
deleted file mode 100644
index ca2ee61..0000000
--- a/examples/004_submissions/002_submission.py
+++ /dev/null
@@ -1,56 +0,0 @@
-import os
-import json
-import glob
-import tarfile
-import itertools
-
-import numpy as np
-
-import xtrack as xt
-import xpart as xp
-import xboinc as xb
-
-import os, subprocess
-from pathlib import Path
-from time import sleep
-import random
-
-user = 'ddicroce' # this should be read from a config json in the eos written by the boinc server
-name = 'test' # study name
-
-filename = xt._pkg_root.parent.joinpath(
- 'test_data/lhc_with_bb/line_and_particle.json')
-
-with open(filename, 'r') as fid:
- input_data = json.load(fid)
-
-
-# loop or anything that user wishes
-nparticles = 6000 # approximate number of particles to be generated
-ndims = 2
-dim_names = ['x', 'y']
-particles_per_dim = int(round(nparticles ** (1.0/ndims)))
-coords = list(itertools.product(*[np.linspace(0, 1e-3, particles_per_dim) for i in range(ndims)]))
-
-particles_per_sub = 1000
-line = xt.Line.from_dict(input_data['line'])
-
-with xb.SubmitJobs(username=user, studyname=name) as job:
- for i in range(0, len(coords), particles_per_sub):
- job_id = job_id = i // particles_per_sub
- job_name = f'{name}_{job_id}'
- for j, dim_name in enumerate(dim_names):
- input_data['particle'][dim_name] = []
- for coord in coords[i:i+particles_per_sub]:
- for j, dim_name in enumerate(dim_names):
- input_data['particle'][dim_name].append(coord[j])
- for dim_name in dim_names:
- input_data['particle'][dim_name] = np.array(input_data['particle'][dim_name])
-
- # Simulation input
- num_turns = 1000
- particles = xp.Particles.from_dict(input_data['particle'])
-
- job.add(job_name=job_name, num_turns=num_turns, line=line, particles=particles,
- checkpoint_every=100)
-
diff --git a/examples/register.py b/examples/register.py
new file mode 100644
index 0000000..5e7464d
--- /dev/null
+++ b/examples/register.py
@@ -0,0 +1,8 @@
+# copyright ############################### #
+# This file is part of the Xboinc Package. #
+# Copyright (c) CERN, 2023. #
+########################################### #
+
+import xboinc as xb
+
+xb.register('sixtadm','/afs/cern.ch/user/s/sixtadm/public/test_xboinc')
diff --git a/examples/running/lossmap.py b/examples/running/lossmap.py
new file mode 100644
index 0000000..1854b49
--- /dev/null
+++ b/examples/running/lossmap.py
@@ -0,0 +1,47 @@
+# copyright ############################### #
+# This file is part of the Xboinc Package. #
+# Copyright (c) CERN, 2023. #
+########################################### #
+
+import subprocess
+from pathlib import Path
+import numpy as np
+
+import xtrack as xt
+import xpart as xp
+import xcoll as xc
+import xboinc as xb
+
+
+# Create simulation input
+num_turns = 20
+num_particles = 5000
+line = xt.Line.from_json(xc._pkg_root.parent / 'examples' / 'machines' / f'lhc_run3_b1.json')
+coll_manager = xc.CollimatorManager.from_yaml(xc._pkg_root.parent / 'examples' / 'colldb' / f'lhc_run3.yaml', line=line, beam=1)
+coll_manager.install_everest_collimators()
+coll_manager.build_tracker()
+coll_manager.set_openings()
+part = coll_manager.generate_pencil_on_collimator('tcp.c6l7.b1', num_particles=num_particles)
+coll_manager.enable_scattering()
+xb.SimConfig.build(line=line, particles=part, num_turns=num_turns, filename='xboinc_input.bin', checkpoint_every=5)
+
+
+# Run xboinc
+cmd = subprocess.run(['uname', '-ms'], stdout=subprocess.PIPE)
+architecture = cmd.stdout.decode('UTF-8').strip().lower().replace(' ','-')
+exec_file = list(Path.cwd().glob(f'xboinc_{xb.app_version}-{architecture}'))
+if len(exec_file)==0 or not exec_file[0].exists():
+ raise ValueError("No executable found")
+exec_file = exec_file[0]
+cmd = subprocess.run(exec_file)
+if cmd.returncode != 0:
+ raise RuntimeError(f"Tracking failed.")
+
+
+# Read output
+filename = 'sim_state_out.bin'
+sim_state = xb.SimState.from_binary(filename)
+part = sim_state.particles
+_ = coll_manager.lossmap(part, file=Path(path_out,f'lossmap_B1H.json'))
+summary = coll_manager.summary(part, file=Path(path_out,f'coll_summary_B1H.out'))
+print(summary)
diff --git a/examples/running/simple_line.py b/examples/running/simple_line.py
new file mode 100644
index 0000000..098530b
--- /dev/null
+++ b/examples/running/simple_line.py
@@ -0,0 +1,40 @@
+import subprocess
+from pathlib import Path
+import numpy as np
+
+import xtrack as xt
+import xpart as xp
+import xboinc as xb
+
+
+# Create simulation input
+num_turns = 200
+line = xt.Line(elements=[
+ xt.Drift(length=1.0), xt.Multipole(knl=[1e-6]), xt.Drift(length=1.0)])
+particles = xp.Particles(mass0=xp.PROTON_MASS_EV, p0c=7e12, x=[1e-6,2e-6,3e-6])
+xb.SimConfig.build(line=line, particles=particles, num_turns=num_turns,
+ filename='xboinc_input.bin')
+
+
+# Run xboinc
+cmd = subprocess.run(['uname', '-ms'], stdout=subprocess.PIPE)
+architecture = cmd.stdout.decode('UTF-8').strip().lower().replace(' ','-')
+exec_file = list(Path.cwd().glob(f'xboinc_{xb.app_version}-{architecture}'))
+if len(exec_file)==0 or not exec_file[0].exists():
+ raise ValueError("No executable found")
+exec_file = exec_file[0]
+cmd = subprocess.run(exec_file)
+if cmd.returncode != 0:
+ raise RuntimeError(f"Tracking failed.")
+
+
+# Read output
+filename = 'sim_state_out.bin'
+sim_state = xb.SimState.from_binary(filename)
+particles = sim_state.particles
+
+assert np.all(particles.s == 0)
+assert np.all(particles.at_turn == num_turns)
+assert sim_state.i_turn == num_turns
+
+print('All checks passed!')
diff --git a/examples/running/xboinc_0.1-linux-x86_64 b/examples/running/xboinc_0.1-linux-x86_64
new file mode 100755
index 0000000..adc8adf
Binary files /dev/null and b/examples/running/xboinc_0.1-linux-x86_64 differ
diff --git a/examples/submission.py b/examples/submission.py
new file mode 100644
index 0000000..9e57a55
--- /dev/null
+++ b/examples/submission.py
@@ -0,0 +1,32 @@
+# copyright ############################### #
+# This file is part of the Xboinc Package. #
+# Copyright (c) CERN, 2023. #
+########################################### #
+
+
+import numpy as np
+
+import xtrack as xt
+import xpart as xp
+import xboinc as xb
+
+
+user = 'sixtadm'
+
+
+num_turns = 2000
+num_particles = 1e6
+line = xt.Line(elements=[
+ xt.Drift(length=1.0), xt.Multipole(knl=[1e-6]), xt.Drift(length=1.0)])
+
+particles_per_sub = 1000
+
+studyname = "example_study"
+
+with xb.SubmitJobs(user=user, study=studyname) as job:
+ for i in range(int(num_particles/particles_per_sub)):
+ particles = xp.Particles(x=np.random.normal(0, 0.0001, particles_per_sub),
+ y=np.random.normal(0, 0.0001, particles_per_sub))
+ job.add(job_name=f'{studyname}_{i}', num_turns=num_turns, line=line, particles=particles,
+ checkpoint_every=100)
+
diff --git a/pyproject.toml b/pyproject.toml
index 5f46306..13f28bc 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -5,7 +5,7 @@
[tool.poetry]
name = "xboinc"
-version = "0.1.2"
+version = "0.1.3"
description = "Xsuite BOINC interface"
homepage = "https://github.com/xsuite/xboinc"
repository = "https://github.com/xsuite/xboinc"
diff --git a/tests/test_compilation_and_running.py b/tests/test_compilation_and_running.py
new file mode 100644
index 0000000..b81fa67
--- /dev/null
+++ b/tests/test_compilation_and_running.py
@@ -0,0 +1,159 @@
+# copyright ############################### #
+# This file is part of the Xboinc Package. #
+# Copyright (c) CERN, 2023. #
+########################################### #
+
+import subprocess
+import json
+import numpy as np
+from pathlib import Path
+import os
+import time
+import filecmp
+
+import xtrack as xt
+import xcoll as xc
+import xboinc as xb
+
+
+line_file = xc._pkg_root.parent / 'tests' / 'data' / 'sequence_lhc_run3_b1.json'
+num_turns = 1000
+
+
+def test_compilation():
+ source_files = xb.generate_executable_source()
+ assert Path(Path.cwd() / "main.c").exists()
+ assert Path(Path.cwd() / "sim_config.h").exists()
+ assert Path(Path.cwd() / "xtrack_tracker.h").exists()
+
+ xb.generate_executable()
+ exec_file = list(Path.cwd().glob(f'xboinc_{xb.app_version}-*'))
+ assert len(exec_file) == 1
+ assert exec_file[0].exists()
+ assert os.access(exec_file[0], os.X_OK)
+
+
+def test_generate_input():
+ # Simulation input
+ line = xt.Line.from_json(line_file)
+ line.build_tracker()
+ x_norm = np.linspace(-.5, .5, 50)
+ delta = np.linspace(-1.e-5, 1.e-5, 50)
+ part = line.build_particles(x_norm=x_norm, delta=delta, nemitt_x=3.5e-6, nemitt_y=3.5e-6)
+
+ # Assemble data structure
+ xb.SimConfig.build(line=line, particles=part, num_turns=num_turns, checkpoint_every=10,
+ filename='xboinc_input.bin')
+
+ input_file = Path.cwd() / "xboinc_input.bin"
+ assert input_file.exists()
+
+
+def test_track():
+ # If no executable is present, make one
+ exec_file = list(Path.cwd().glob(f'xboinc_{xb.app_version}-*'))
+ if len(exec_file)==0 or not exec_file[0].exists():
+ xb.generate_executable()
+ exec_file = exec_file[0]
+
+ # If no input file is present, make one
+ input_file = Path.cwd() / 'xboinc_input.bin'
+ if not input_file.exists():
+ test_generate_input()
+
+ # run xboinc tracker
+ t1 = time.time()
+ cmd = subprocess.run([exec_file])
+ print(round(time.time() - t1, 1))
+ if cmd.returncode != 0:
+ raise RuntimeError(f"Tracking failed.")
+
+ # Read output
+ output_file = Path.cwd() / 'sim_state_out.bin'
+ assert output_file.exists()
+ sim_state = xb.SimState.from_binary(output_file)
+
+ # Look at particles state
+ part_xboinc = sim_state.particles
+ assert np.allclose(part_xboinc.s, 0, rtol=1e-6, atol=0), "Unexpected s"
+ assert np.all(part_xboinc.at_turn == num_turns), "Unexpected survivals (particles)"
+ assert sim_state.i_turn == num_turns, "Unexpecteds survival (sim_state)"
+
+ # Rename file for comparison in next test
+ output_file.rename(output_file.parent / f'{output_file.name}_2')
+
+
+def test_checkpoint():
+ # If no executable is present, make one
+ exec_file = list(Path.cwd().glob(f'xboinc_{xb.app_version}-*'))
+ if len(exec_file)==0 or not exec_file[0].exists():
+ xb.generate_executable()
+ exec_file = exec_file[0]
+
+ # If no input file is present, make one
+ input_file = Path.cwd() / 'xboinc_input.bin'
+ if not input_file.exists():
+ test_generate_input()
+
+ # If previous output file not present, we need to regenerate it (to be able to compare)
+ output_file = Path.cwd() / 'sim_state_out.bin_2'
+ if not output_file.exists():
+ test_track()
+
+ # run xboinc tracker and interrupt halfway
+ interrupted = False
+ timeout = 25
+ print(f"Will interrupt after {timeout}s.")
+ try:
+ cmd = subprocess.run(exec_file, timeout=timeout)
+ except subprocess.TimeoutExpired:
+ interrupted = True
+ print("Interrupted calculation. Now trying to continue.")
+ checkpoint_file = Path.cwd() / 'checkpoint.bin'
+ assert checkpoint_file.exists()
+ if not interrupted:
+ raise ValueError("Timeout was too short. Adapt the test 'test_checkpoint'.")
+
+ # Now continue tracking (without timeout)
+ cmd = subprocess.run(exec_file)
+ if cmd.returncode != 0:
+ raise RuntimeError(f"Tracking failed.")
+
+ # Compare file to previous result
+ output_file = Path.cwd() / 'sim_state_out.bin'
+ assert output_file.exists()
+ assert filecmp.cmp(output_file, output_file.parent / f'{output_file.name}_2', shallow=False)
+
+
+def test_vs_xtrack():
+ # If no output is present, make one
+ output_file = Path.cwd() / 'sim_state_out.bin'
+ if not output_file.exists():
+ test_track()
+ sim_state = xb.SimState.from_binary(output_file)
+ part_xboinc = sim_state.particles
+
+ # Testing results with xtrack
+ line = xt.Line.from_json(line_file)
+ line.build_tracker()
+ x_norm = np.linspace(-.5, .5, 50)
+ delta = np.linspace(-1.e-5, 1.e-5, 50)
+ part = line.build_particles(x_norm=x_norm, delta=delta, nemitt_x=3.5e-6, nemitt_y=3.5e-6)
+ line.track(part, num_turns=num_turns)
+
+ assert np.array_equal(part.at_turn, part_xboinc.at_turn), "Fail to match xtrack: survivals are not equal"
+ assert np.array_equal(part.x, part_xboinc.x), "Fail to match xtrack: x are not equal"
+ assert np.array_equal(part.y, part_xboinc.y), "Fail to match xtrack: y are not equal"
+ assert np.array_equal(part.zeta, part_xboinc.zeta), "Fail to match xtrack: zeta are not equal"
+ assert np.array_equal(part.px, part_xboinc.px), "Fail to match xtrack: px are not equal"
+ assert np.array_equal(part.py, part_xboinc.py), "Fail to match xtrack: py are not equal"
+ assert np.array_equal(part.delta, part_xboinc.delta), "Fail to match xtrack: delta are not equal"
+
+
+def test_clean():
+ input_files = list(Path.cwd().glob('xboinc_input.bin*'))
+ output_files = list(Path.cwd().glob('sim_state_out.bin*'))
+ exec_files = list(Path.cwd().glob(f'xboinc_{xb.app_version}-*'))
+ for file in [*input_files, *output_files, *exec_files]:
+ if file.exists():
+ file.unlink()
diff --git a/tests/test_generation.py b/tests/test_generation.py
deleted file mode 100644
index a279cc6..0000000
--- a/tests/test_generation.py
+++ /dev/null
@@ -1,21 +0,0 @@
-import subprocess
-import json
-import numpy as np
-from pathlib import Path
-import os
-
-import xtrack as xt
-import xpart as xp
-import xboinc as xb
-
-
-def test_compilation():
- source_files = xb.generate_executable_source()
- assert Path(Path.cwd() / "main.c").exists()
- assert Path(Path.cwd() / "sim_config.h").exists()
- assert Path(Path.cwd() / "xtrack_tracker.h").exists()
-
- xb.generate_executable()
- exec_file = Path.cwd() / "xboinc_executable"
- assert exec_file.exists()
- assert os.access(exec_file, os.X_OK)
diff --git a/tests/test_track.py b/tests/test_track.py
deleted file mode 100644
index 2b7cc32..0000000
--- a/tests/test_track.py
+++ /dev/null
@@ -1,97 +0,0 @@
-import subprocess
-import json
-import numpy as np
-from pathlib import Path
-import os
-
-import xtrack as xt
-import xpart as xp
-import xboinc as xb
-
-
-test_line = xt._pkg_root.parent / 'test_data' / 'lhc_with_bb' / 'line_and_particle.json'
-num_turns = 1000
-
-
-def test_generate_input():
- with test_line.open('r') as fid:
- input_data = json.load(fid)
-
- # We add some particles
- input_data['particle']['x'] += np.linspace(0, 1e-3, 10)
-
- # Simulation input
- line = xt.Line.from_dict(input_data['line'])
- particles = xp.Particles.from_dict(input_data['particle'])
-
- # Assemble data structure
- xb.build_input_file(line=line, particles=particles, num_turns=num_turns, checkpoint_every=100,
- name='xboinc_input.bin')
-
- input_file = Path.cwd() / "xboinc_input.bin"
- assert input_file.exists()
-
-
-def test_track():
- # If no executable is present, make one
- exec_file = Path.cwd() / "xboinc_executable"
- if not exec_file.exists():
- xb.generate_executable()
-
- # If no input file is present, make one
- input_file = Path.cwd() / 'xboinc_input.bin'
- if not input_file.exists():
- test_generate_input()
-
- # run xboinc tracker
- cmd = subprocess.run([exec_file], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
- if cmd.returncode != 0:
- stderr = cmd.stderr.decode('UTF-8').strip().split('\n')
- raise RuntimeError(f"Tracking failed. Stderr:\n {stderr}")
-
- # Read output
- output_file = Path.cwd() / 'sim_state_out.bin'
- assert output_file.exists()
- sim_state = xb.read_output_file(output_file)
-
- # Look at particles state
- particles_xboinc = sim_state.particles
-
- assert np.allclose(particles_xboinc.s, 0, rtol=1e-6, atol=0), "Unexpected s"
- assert np.all(particles_xboinc.at_turn == num_turns), "Unexpected survivals (particles)"
- assert sim_state.i_turn == num_turns, "Unexpecteds survival (sim_state)"
-
-
-def test_vs_xtrack():
- # If no output is present, make one
- output_file = Path.cwd() / 'sim_state_out.bin'
- if not output_file.exists():
- test_track()
- sim_state = xb.read_output_file(output_file)
- particles_xboinc = sim_state.particles
-
- # Testing results with xtrack
- with test_line.open('r') as fid:
- input_data = json.load(fid)
- input_data['particle']['x'] += np.linspace(0, 1e-3, 10)
- line_xtrack = xt.Line.from_dict(input_data['line'])
- particles = xp.Particles.from_dict(input_data['particle'])
- line_xtrack.build_tracker()
- line_xtrack.track(particles, num_turns=num_turns)
-
- assert np.array_equal(particles.at_turn, particles_xboinc.at_turn), "Fail to match xtrack: survivals are not equal"
- assert np.array_equal(particles.x, particles_xboinc.x), "Fail to match xtrack: x are not equal"
- assert np.array_equal(particles.y, particles_xboinc.y), "Fail to match xtrack: y are not equal"
- assert np.array_equal(particles.zeta, particles_xboinc.zeta), "Fail to match xtrack: zeta are not equal"
- assert np.array_equal(particles.px, particles_xboinc.px), "Fail to match xtrack: px are not equal"
- assert np.array_equal(particles.py, particles_xboinc.py), "Fail to match xtrack: py are not equal"
- assert np.array_equal(particles.delta, particles_xboinc.delta), "Fail to match xtrack: delta are not equal"
-
-
-def test_clean():
- input_file = Path.cwd() / "xboinc_input.bin"
- output_file = Path.cwd() / 'sim_state_out.bin'
- exec_file = Path.cwd() / "xboinc_executable"
- for file in [input_file, output_file, exec_file]:
- if file.exists():
- file.unlink()
diff --git a/tests/test_user.py b/tests/test_user.py
new file mode 100644
index 0000000..21220b2
--- /dev/null
+++ b/tests/test_user.py
@@ -0,0 +1,35 @@
+# copyright ############################### #
+# This file is part of the Xboinc Package. #
+# Copyright (c) CERN, 2023. #
+########################################### #
+
+from pathlib import Path
+import json
+import pytest
+
+import xboinc as xb
+
+user = 'sixtadm'
+folder_afs = Path('/afs/cern.ch/user/s/sixtadm/public/test_xboinc').resolve()
+folder_eos = Path('/afs/cern.ch/user/s/sixtadm/eos_sixtadm/test_xboinc').resolve()
+
+user_data_file = xb._pkg_root / 'user_data.json'
+
+
+def test_remove():
+ xb.user.remove_user(user)
+ with user_data_file.open('r') as fid:
+ userdict = json.load(fid)
+ assert user not in userdict.keys()
+
+
+def test_register():
+ xb.register(user, folder_afs)
+ assert xb.user.get_folder(user) == folder_afs
+ assert xb.user.get_domain(user) == 'afs'
+ assert xb.user.get_user_data(user)['folder'] == folder_afs.as_posix()
+ assert xb.user.get_user_data(user)['domain'] == 'afs'
+ assert xb.server.eos.eos_exists(xb.server.paths.dropdir / f"register_{user}.json")
+
+ with pytest.raises(NotImplementedError):
+ xb.register(user, folder_eos)
diff --git a/tests/test_user_submission.py b/tests/test_user_submission.py
new file mode 100644
index 0000000..413cb79
--- /dev/null
+++ b/tests/test_user_submission.py
@@ -0,0 +1,54 @@
+# copyright ############################### #
+# This file is part of the Xboinc Package. #
+# Copyright (c) CERN, 2023. #
+########################################### #
+
+import tarfile
+import numpy as np
+import pandas as pd
+
+import xtrack as xt
+import xpart as xp
+import xboinc as xb
+
+
+user = 'sixtadm'
+
+
+def test_submission():
+ num_turns = 2000
+ num_particles = 1e6
+ line = xt.Line(elements=[
+ xt.Drift(length=1.0), xt.Multipole(knl=[1e-6]), xt.Drift(length=1.0)])
+
+ particles_per_sub = 1000
+
+ studyname = "test_study"
+ num_jobs = int(num_particles/particles_per_sub)
+
+ with xb.SubmitJobs(user=user, study=studyname) as job:
+ for i in range(num_jobs):
+ particles = xp.Particles(x=np.random.normal(0, 0.0001, particles_per_sub),
+ y=np.random.normal(0, 0.0001, particles_per_sub))
+ job.add(job_name=f'{studyname}_{i}', num_turns=num_turns, line=line, particles=particles,
+ checkpoint_every=100)
+
+ now = pd.Timestamp.now().timestamp()
+ tarfiles = list(xb.user.get_folder(user).glob(f'{studyname}__*'))
+ assert len(tarfiles) > 0
+ # Look for the tar that is just generated
+ for tar in tarfiles:
+ ts = tar.name.split('__')[-1].split('.')[0].replace('_','T').replace('-', ':').replace(':', '-', 2)
+ if abs(now - pd.Timestamp(ts).timestamp()) < 60:
+ break
+ assert tar.exists() and tar.stat().st_size!=0
+ tar_contents = tarfile.open(tar)
+ members = tar_contents.getmembers()
+ assert len(members) == 2*num_jobs
+ assert np.all([member.size > 8 for member in members])
+ member_names = [member.name for member in members]
+ assert len(member_names) == 2*num_jobs
+ assert np.all([member[:len(user)+2] == f'{user}__' for member in member_names])
+ assert len([member for member in member_names if member[-5:]=='.json']) == num_jobs
+ assert len([member for member in member_names if member[-4:]=='.bin']) == num_jobs
+ tar.unlink()
diff --git a/tests/test_version.py b/tests/test_version.py
index 97df0b0..3a779dc 100644
--- a/tests/test_version.py
+++ b/tests/test_version.py
@@ -1,5 +1,20 @@
+# copyright ############################### #
+# This file is part of the Xboinc Package. #
+# Copyright (c) CERN, 2023. #
+########################################### #
+
+import pytest
from xboinc import __version__
+from xboinc.simulation_io import SimVersion
+from xboinc.simulation_io.version import _version_to_int, _int_to_version
def test_version():
- assert __version__ == '0.1.2'
+ assert __version__ == '0.1.3'
+def test_sim_ver():
+ simver = SimVersion()
+ simver.assert_version()
+ print(_int_to_version(simver.xboinc_version))
+ with pytest.raises(Exception):
+ simver.xboinc_version = _version_to_int('0.0.0')
+ simver.assert_version()
diff --git a/xboinc/executable/main.c b/xboinc/executable/main.c
index 6a346dc..2835f6b 100644
--- a/xboinc/executable/main.c
+++ b/xboinc/executable/main.c
@@ -90,10 +90,12 @@ int main(){
}
int64_t step_turns;
- if (checkpoint_every>0){
+ if (checkpoint_every > 0){
step_turns = checkpoint_every;
+ printf("Checkpointing every %d turns\n", (int) step_turns);
} else {
- step_turns = num_elements;
+ step_turns = num_turns;
+ printf("Not checkpointing\n");
}
while (current_turn < num_turns){
@@ -119,7 +121,7 @@ int main(){
SimStateData_set_i_turn(sim_state, SimStateData_get_i_turn(sim_state) + step_turns);
current_turn = SimStateData_get_i_turn(sim_state);
- if (checkpoint_every>0){
+ if (checkpoint_every > 0){
if (current_turn < num_turns){
printf("Checkpointing turn %d\n", (int) current_turn);
FILE *chkp_fid;
@@ -146,10 +148,11 @@ int main(){
fclose(out_fid);
// Remove checkpoint
- if (remove("./checkpoint.bin") != 0){
- printf("Error: could not remove checkpoint file\n");
- return -1; // error
+ if (checkpoint_every > 0 && checkpoint_every < num_turns){
+ if (remove("./checkpoint.bin") != 0){
+ printf("Error: could not remove checkpoint file\n");
+ return -1; // error
+ }
}
-
return 0;
}
diff --git a/xboinc/general.py b/xboinc/general.py
index 15ba19c..4b0394d 100644
--- a/xboinc/general.py
+++ b/xboinc/general.py
@@ -12,7 +12,7 @@
# Do not change
# ==========================================================================================
-__version__ = '0.1.2'
+__version__ = '0.1.3'
# These are the xsuite modules that are used by boinc and the versions they are tied to.
# This will be automatically updated from the active environment when making a minor release.
diff --git a/xboinc/register.py b/xboinc/register.py
index 713620c..9067968 100644
--- a/xboinc/register.py
+++ b/xboinc/register.py
@@ -10,7 +10,7 @@
from .user import update_user_data
from .server import server_account
from .server.paths import dropdir
-from .server.eos import eos_exists, eos_rm, cp_to_eos
+from .server.eos import eos_exists, eos_rm, cp_to_eos, xrdcp_installed
from .server.afs import afs_add_acl
@@ -50,7 +50,7 @@ def register(user, folder):
_set_rights(folder, data['domain'])
except Exception as e:
user_file.unlink()
- raise Exception(e)
+ raise e
if eos_exists(dropdir / user_file.name):
eos_rm(dropdir / user_file.name)
print("Replaced existing registration file on server dropdir.")
diff --git a/xboinc/server/afs.py b/xboinc/server/afs.py
index d00daec..dcbded2 100644
--- a/xboinc/server/afs.py
+++ b/xboinc/server/afs.py
@@ -5,6 +5,8 @@
import subprocess
from pathlib import Path
+from time import sleep
+import random
from .tools import log_debug, log_info, log_error
diff --git a/xboinc/simulation_io/input.py b/xboinc/simulation_io/input.py
index cb7e653..0d3722b 100644
--- a/xboinc/simulation_io/input.py
+++ b/xboinc/simulation_io/input.py
@@ -30,6 +30,8 @@ def build(cls, *, num_turns, line, particles, checkpoint_every=-1, filename=None
simbuf = xo.ContextCpu().new_buffer()
sim_config = cls(_buffer=simbuf)
default_tracker = _default_tracker
+ line.discard_tracker()
+ # TODO: check that line does not contain non-supported elements
line.build_tracker(_context=simbuf.context, _buffer=simbuf,
track_kernel=default_tracker.track_kernel)
if _default_config_hash not in line.tracker._tracker_data_cache:
diff --git a/xboinc/submit.py b/xboinc/submit.py
index dc45d95..3f5ce47 100644
--- a/xboinc/submit.py
+++ b/xboinc/submit.py
@@ -10,13 +10,11 @@
from .user import get_domain, get_folder
from .server.eos import mv_from_eos, mv_to_eos, xrdcp_installed
+from .server.afs import mv_from_afs, mv_to_afs
from .server.tools import timestamp
from .simulation_io import SimConfig, app_version
-eosdir = '/eos/user/d/ddicroce/xboinc/'
-
-
class SubmitJobs:
def __init__(self, user, study):
@@ -25,14 +23,14 @@ def __init__(self, user, study):
self._username = user
self._domain = get_domain(user)
if self._domain=='eos' and not xrdcp_installed():
- raise ValueError("Error: xrdcp is not installed on your system. Cannot submit.")
+ raise ValueError("Error: xrdcp is not installed on your system. Cannot submit to EOS.")
self._target = get_folder(user)
self._studyname = study
self._submitfile = f"{self._studyname}__{timestamp()}.tar.gz"
self._json_files = []
self._bin_files = []
self._temp = tempfile.TemporaryDirectory()
- self._tempdir = Path(temp.name).resolve()
+ self._tempdir = Path(self._temp.name).resolve()
self._tempdir.mkdir(parents=True, exist_ok=True)
def __enter__(self, *args, **kwargs):
diff --git a/xboinc/user.py b/xboinc/user.py
index c02ff35..009ddb3 100644
--- a/xboinc/user.py
+++ b/xboinc/user.py
@@ -36,3 +36,12 @@ def get_folder(user):
def get_domain(user):
return get_user_data(user)['domain']
+
+def remove_user(user):
+ with user_data_file.open('r') as fid:
+ userdict = json.load(fid)
+ if user in userdict:
+ userdict.pop(user)
+ with user_data_file.open('w') as fid:
+ json.dump(userdict, fid)
+