02.2025
This commit is contained in:
@@ -8,5 +8,26 @@
|
||||
"pipeline_type": "processing",
|
||||
"camera_name": "ALBDI-SM-2",
|
||||
"name": "ALBDI-SM-2_sp",
|
||||
"max_frame_rate": 10.1
|
||||
"max_frame_rate": 10.1,
|
||||
"function": "sp_pipolar",
|
||||
"fit": {
|
||||
"delta_height": 50,
|
||||
"bg_range_low": [
|
||||
0,
|
||||
200
|
||||
],
|
||||
"bg_range_high": [
|
||||
840,
|
||||
1040
|
||||
],
|
||||
"peak_search_rel_range": [
|
||||
-1,
|
||||
2
|
||||
],
|
||||
"valley_search_rel_range": [
|
||||
-1,
|
||||
2
|
||||
]
|
||||
},
|
||||
"copy": true
|
||||
}
|
||||
12
configuration/pipeline_config/ALBDI-SM-2_sp_proc.json
Normal file
12
configuration/pipeline_config/ALBDI-SM-2_sp_proc.json
Normal file
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"name": "ALBDI-SM-2_sp_proc",
|
||||
"pipeline_type": "stream",
|
||||
"input_pipeline": "ALBDI-SM-2_sp",
|
||||
"mode": "PUB",
|
||||
"block": false,
|
||||
"function": "epics_forwarder_sp.py",
|
||||
"max_frame_rate": 10.1,
|
||||
"throw_epics_errors": true,
|
||||
"abort_on_timeout": true,
|
||||
"stream_timeout": 60
|
||||
}
|
||||
15
configuration/pipeline_config/ARS05-RCAM-0140_proc2.json
Normal file
15
configuration/pipeline_config/ARS05-RCAM-0140_proc2.json
Normal file
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"image_background_enable": false,
|
||||
"image_background": null,
|
||||
"image_threshold": null,
|
||||
"image_region_of_interest": null,
|
||||
"image_good_region": null,
|
||||
"image_slices": null,
|
||||
"pipeline_type": "processing",
|
||||
"camera_name": "ARS05-RCAM-0140",
|
||||
"function": "proc_sr2",
|
||||
"reload": true,
|
||||
"abort_on_error": false,
|
||||
"name": "ARS05-RCAM-0140_proc2",
|
||||
"no_client_timeout": 0
|
||||
}
|
||||
15
configuration/pipeline_config/ARS05-RCAM-0230_proc2.json
Normal file
15
configuration/pipeline_config/ARS05-RCAM-0230_proc2.json
Normal file
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"image_background_enable": false,
|
||||
"image_background": null,
|
||||
"image_threshold": null,
|
||||
"image_region_of_interest": null,
|
||||
"image_good_region": null,
|
||||
"image_slices": null,
|
||||
"pipeline_type": "processing",
|
||||
"camera_name": "ARS05-RCAM-0230",
|
||||
"function": "proc_sr3",
|
||||
"reload": true,
|
||||
"abort_on_error": false,
|
||||
"name": "ARS05-RCAM-0230_proc2",
|
||||
"no_client_timeout": 0
|
||||
}
|
||||
15
configuration/pipeline_config/ARS05-RCAM-0310_proc2.json
Normal file
15
configuration/pipeline_config/ARS05-RCAM-0310_proc2.json
Normal file
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"image_background_enable": false,
|
||||
"image_background": null,
|
||||
"image_threshold": null,
|
||||
"image_region_of_interest": null,
|
||||
"image_good_region": null,
|
||||
"image_slices": null,
|
||||
"pipeline_type": "processing",
|
||||
"camera_name": "ARS05-RCAM-0310",
|
||||
"function": "proc_sr4",
|
||||
"reload": true,
|
||||
"abort_on_error": false,
|
||||
"name": "ARS05-RCAM-0310_proc2",
|
||||
"no_client_timeout": 0
|
||||
}
|
||||
@@ -7,6 +7,7 @@
|
||||
"ABRTL-DSCR-0440_proc": "ABRTL-DSCR-0440_proc",
|
||||
"ABRTL-DSCR-0680_proc": "ABRTL-DSCR-0680_proc",
|
||||
"ABRTL-DSCR-0870_proc": "ABRTL-DSCR-0870_proc",
|
||||
"ALBDI-SM-2_sp_proc": "ALBDI-SM-2_sp_proc",
|
||||
"ALIDI-SM-3_proc": "ALIDI-SM-3_proc",
|
||||
"ALIDI-SM-4_proc": "ALIDI-SM-4_proc",
|
||||
"ALIDI-SM-5_sp_proc": "ALIDI-SM-5_sp_proc",
|
||||
@@ -15,8 +16,11 @@
|
||||
"ARS05-RCAM-0060_proc": "ARS05-RCAM-0060_proc",
|
||||
"ARS05-RCAM-0060_proc2": "ARS05-RCAM-0060_proc2",
|
||||
"ARS05-RCAM-0140_proc": "ARS05-RCAM-0140_proc",
|
||||
"ARS05-RCAM-0140_proc2": "ARS05-RCAM-0140_proc2",
|
||||
"ARS05-RCAM-0230_proc": "ARS05-RCAM-0230_proc",
|
||||
"ARS05-RCAM-0230_proc2": "ARS05-RCAM-0230_proc2",
|
||||
"ARS05-RCAM-0310_proc": "ARS05-RCAM-0310_proc",
|
||||
"ARS05-RCAM-0310_proc2": "ARS05-RCAM-0310_proc2",
|
||||
"X01DD-FE-CAM1_proc": "X01DD-FE-CAM1_proc",
|
||||
"X08DB-FE-CAM1_proc": "X08DB-FE-CAM1_proc",
|
||||
"emmitance_pipolar": "emmitance_pipolar"
|
||||
|
||||
@@ -8,5 +8,26 @@
|
||||
"pipeline_type": "processing",
|
||||
"camera_name": "source_h5",
|
||||
"name": "source_h5_sp",
|
||||
"max_frame_rate": 10.1
|
||||
"function": "sp_pipolar",
|
||||
"max_frame_rate": 10.1,
|
||||
"fit": {
|
||||
"delta_height": 50,
|
||||
"bg_range_low": [
|
||||
0,
|
||||
200
|
||||
],
|
||||
"bg_range_high": [
|
||||
840,
|
||||
1040
|
||||
],
|
||||
"peak_search_rel_range": [
|
||||
-1,
|
||||
2
|
||||
],
|
||||
"valley_search_rel_range": [
|
||||
-1,
|
||||
2
|
||||
]
|
||||
},
|
||||
"copy": true
|
||||
}
|
||||
@@ -22,8 +22,8 @@ class PpolPeakValley():
|
||||
self.x, self.y = self.ppol_interpol()
|
||||
|
||||
def ppol_interpol(self, plot_flag=False):
|
||||
ipv = [32.97634439, 20.84823973, 15.30617974, 12.12078244, 10.04998987, 8.59541134, 7.517605624, 6.687085031, 6.027635302, 5.491463995, 5.047070496, 4.67284665, 4.353472754, 4.077788974, 3.837472599, 3.439012834, 3.122374348, 2.86497533, 2.651841232, 0.0]
|
||||
sig = [3.7, 5.2, 6.3, 7.3, 8.2, 9.0, 9.7, 10.3, 11.0, 11.6, 12.1, 12.7, 13.2, 13.7, 14.2, 15.2, 16, 16.8, 17.5, 0.0]
|
||||
ipv = [0.0, 32.97634439, 20.84823973, 15.30617974, 12.12078244, 10.04998987, 8.59541134, 7.517605624, 6.687085031, 6.027635302, 5.491463995, 5.047070496, 4.67284665, 4.353472754, 4.077788974, 3.837472599, 3.439012834, 3.122374348, 2.86497533, 2.651841232]
|
||||
sig = [0.0, 3.7, 5.2, 6.3, 7.3, 8.2, 9.0, 9.7, 10.3, 11.0, 11.6, 12.1, 12.7, 13.2, 13.7, 14.2, 15.2, 16, 16.8, 17.5]
|
||||
sig2 = [element * element for element in sig]
|
||||
x = np.linspace(0, 999999, 999999)
|
||||
x = [(1+val)/1000000*max(ipv) for val in x]
|
||||
|
||||
129
configuration/user_scripts/proc_sr2.py
Normal file
129
configuration/user_scripts/proc_sr2.py
Normal file
@@ -0,0 +1,129 @@
|
||||
#########################################################################
|
||||
# The interface to integrate into the pipeline server
|
||||
# The following files are needed to be added to the library:
|
||||
# - CamDataProcess.py
|
||||
# - Config_Param.py
|
||||
# - LocalPV.py
|
||||
# - RecordTemplate.py
|
||||
# - RemotePV.py
|
||||
# - Service_Log.py
|
||||
# - Service_RFStation.py
|
||||
# - Service_Screen.py
|
||||
# - elog.py
|
||||
#
|
||||
# Created by Zheqiao Geng on 29.05.2024
|
||||
#########################################################################
|
||||
import os
|
||||
import time
|
||||
|
||||
from cam_server.pipeline.data_processing import functions, processor
|
||||
from cam_server import utils
|
||||
from logging import getLogger
|
||||
|
||||
from CamDataProcess import *
|
||||
from Service_RFStation import *
|
||||
from Config_Param import *
|
||||
from Service_Log import *
|
||||
|
||||
# ===============================================================
|
||||
# global variables
|
||||
# ===============================================================
|
||||
_logger = getLogger(__name__)
|
||||
initialized = False
|
||||
moduleName = 'ARS05-RCAM-0140'
|
||||
instName = 'SR2'
|
||||
srvRFs = None
|
||||
srvLog = None
|
||||
camPrc = None
|
||||
|
||||
# ===============================================================
|
||||
# init function
|
||||
# ===============================================================
|
||||
def initialize():
|
||||
global srvRFs, srvLog, camPrc, moduleName, instName
|
||||
|
||||
# get the RF station info
|
||||
if instName == 'TS':
|
||||
cav_label = ts_cav_label
|
||||
cpl_label = ts_cpl_label
|
||||
elif instName == 'SR1':
|
||||
cav_label = sr1_cav_label
|
||||
cpl_label = sr1_cpl_label
|
||||
elif instName == 'SR2':
|
||||
cav_label = sr2_cav_label
|
||||
cpl_label = sr2_cpl_label
|
||||
elif instName == 'SR3':
|
||||
cav_label = sr3_cav_label
|
||||
cpl_label = sr3_cpl_label
|
||||
elif instName == 'SR4':
|
||||
cav_label = sr4_cav_label
|
||||
cpl_label = sr4_cpl_label
|
||||
else:
|
||||
cav_label = ''
|
||||
cpl_label = ''
|
||||
|
||||
# define the services
|
||||
srvRFs = Service_RFStation(loc = instName,
|
||||
cav_label = cav_label,
|
||||
cpl_label = cpl_label)
|
||||
srvLog = Service_Log(moduleName, loc = instName)
|
||||
|
||||
# define the jobs
|
||||
camPrc = CamDataProcess(moduleName,
|
||||
instName,
|
||||
srv_scr = None,
|
||||
srv_rfs = srvRFs,
|
||||
srv_log = srvLog,
|
||||
f_path = file_path)
|
||||
|
||||
# connect to all PVs
|
||||
RemotePV.connect()
|
||||
time.sleep(2.0)
|
||||
|
||||
# start the threads
|
||||
camPrc.start()
|
||||
_logger.info('EPICS_CA_ADDR_LIST = ' + str(os.environ.get('EPICS_CA_ADDR_LIST')))
|
||||
_logger.info('Data Path: ' + camPrc.f_path)
|
||||
_logger.info("Initialized")
|
||||
|
||||
# ===============================================================
|
||||
# implement the image processing function (replacing the thread
|
||||
# function "DataRecvProcFunc" in "CamDataProcess.py")
|
||||
# ===============================================================
|
||||
def process_image(image, pulse_id, timestamp, x_axis, y_axis, parameters, bsdata=None):
|
||||
# declare the global variables
|
||||
global camPrc, initialized
|
||||
|
||||
try:
|
||||
# initialization
|
||||
if not initialized:
|
||||
initialize()
|
||||
initialized = True
|
||||
|
||||
# basic process of the image
|
||||
data = { 'timestamp' : utils.timestamp_as_float(timestamp),
|
||||
'width' : len(image[0]),
|
||||
'height' : len(image),
|
||||
'image' : image,
|
||||
'arc_found' : 0}
|
||||
|
||||
# calculate the properties for arc detection
|
||||
x_profile, y_profile = functions.get_x_y_profile(image)
|
||||
min_value, max_value = functions.get_min_max(image)
|
||||
intensity = x_profile.sum()
|
||||
|
||||
data['intensity'] = intensity
|
||||
data['min_value'] = min_value
|
||||
data['max_value'] = max_value
|
||||
data['x_profile'] = x_profile
|
||||
data['y_profile'] = y_profile
|
||||
|
||||
# store to the circular buffer
|
||||
camPrc.receiveImage(data)
|
||||
return data
|
||||
except Exception as e:
|
||||
_logger.warning(str(e))
|
||||
return None
|
||||
|
||||
|
||||
|
||||
129
configuration/user_scripts/proc_sr3.py
Normal file
129
configuration/user_scripts/proc_sr3.py
Normal file
@@ -0,0 +1,129 @@
|
||||
#########################################################################
|
||||
# The interface to integrate into the pipeline server
|
||||
# The following files are needed to be added to the library:
|
||||
# - CamDataProcess.py
|
||||
# - Config_Param.py
|
||||
# - LocalPV.py
|
||||
# - RecordTemplate.py
|
||||
# - RemotePV.py
|
||||
# - Service_Log.py
|
||||
# - Service_RFStation.py
|
||||
# - Service_Screen.py
|
||||
# - elog.py
|
||||
#
|
||||
# Created by Zheqiao Geng on 29.05.2024
|
||||
#########################################################################
|
||||
import os
|
||||
import time
|
||||
|
||||
from cam_server.pipeline.data_processing import functions, processor
|
||||
from cam_server import utils
|
||||
from logging import getLogger
|
||||
|
||||
from CamDataProcess import *
|
||||
from Service_RFStation import *
|
||||
from Config_Param import *
|
||||
from Service_Log import *
|
||||
|
||||
# ===============================================================
|
||||
# global variables
|
||||
# ===============================================================
|
||||
_logger = getLogger(__name__)
|
||||
initialized = False
|
||||
moduleName = 'ARS05-RCAM-0230'
|
||||
instName = 'SR3'
|
||||
srvRFs = None
|
||||
srvLog = None
|
||||
camPrc = None
|
||||
|
||||
# ===============================================================
|
||||
# init function
|
||||
# ===============================================================
|
||||
def initialize():
|
||||
global srvRFs, srvLog, camPrc, moduleName, instName
|
||||
|
||||
# get the RF station info
|
||||
if instName == 'TS':
|
||||
cav_label = ts_cav_label
|
||||
cpl_label = ts_cpl_label
|
||||
elif instName == 'SR1':
|
||||
cav_label = sr1_cav_label
|
||||
cpl_label = sr1_cpl_label
|
||||
elif instName == 'SR2':
|
||||
cav_label = sr2_cav_label
|
||||
cpl_label = sr2_cpl_label
|
||||
elif instName == 'SR3':
|
||||
cav_label = sr3_cav_label
|
||||
cpl_label = sr3_cpl_label
|
||||
elif instName == 'SR4':
|
||||
cav_label = sr4_cav_label
|
||||
cpl_label = sr4_cpl_label
|
||||
else:
|
||||
cav_label = ''
|
||||
cpl_label = ''
|
||||
|
||||
# define the services
|
||||
srvRFs = Service_RFStation(loc = instName,
|
||||
cav_label = cav_label,
|
||||
cpl_label = cpl_label)
|
||||
srvLog = Service_Log(moduleName, loc = instName)
|
||||
|
||||
# define the jobs
|
||||
camPrc = CamDataProcess(moduleName,
|
||||
instName,
|
||||
srv_scr = None,
|
||||
srv_rfs = srvRFs,
|
||||
srv_log = srvLog,
|
||||
f_path = file_path)
|
||||
|
||||
# connect to all PVs
|
||||
RemotePV.connect()
|
||||
time.sleep(2.0)
|
||||
|
||||
# start the threads
|
||||
camPrc.start()
|
||||
_logger.info('EPICS_CA_ADDR_LIST = ' + str(os.environ.get('EPICS_CA_ADDR_LIST')))
|
||||
_logger.info('Data Path: ' + camPrc.f_path)
|
||||
_logger.info("Initialized")
|
||||
|
||||
# ===============================================================
|
||||
# implement the image processing function (replacing the thread
|
||||
# function "DataRecvProcFunc" in "CamDataProcess.py")
|
||||
# ===============================================================
|
||||
def process_image(image, pulse_id, timestamp, x_axis, y_axis, parameters, bsdata=None):
|
||||
# declare the global variables
|
||||
global camPrc, initialized
|
||||
|
||||
try:
|
||||
# initialization
|
||||
if not initialized:
|
||||
initialize()
|
||||
initialized = True
|
||||
|
||||
# basic process of the image
|
||||
data = { 'timestamp' : utils.timestamp_as_float(timestamp),
|
||||
'width' : len(image[0]),
|
||||
'height' : len(image),
|
||||
'image' : image,
|
||||
'arc_found' : 0}
|
||||
|
||||
# calculate the properties for arc detection
|
||||
x_profile, y_profile = functions.get_x_y_profile(image)
|
||||
min_value, max_value = functions.get_min_max(image)
|
||||
intensity = x_profile.sum()
|
||||
|
||||
data['intensity'] = intensity
|
||||
data['min_value'] = min_value
|
||||
data['max_value'] = max_value
|
||||
data['x_profile'] = x_profile
|
||||
data['y_profile'] = y_profile
|
||||
|
||||
# store to the circular buffer
|
||||
camPrc.receiveImage(data)
|
||||
return data
|
||||
except Exception as e:
|
||||
_logger.warning(str(e))
|
||||
return None
|
||||
|
||||
|
||||
|
||||
129
configuration/user_scripts/proc_sr4.py
Normal file
129
configuration/user_scripts/proc_sr4.py
Normal file
@@ -0,0 +1,129 @@
|
||||
#########################################################################
|
||||
# The interface to integrate into the pipeline server
|
||||
# The following files are needed to be added to the library:
|
||||
# - CamDataProcess.py
|
||||
# - Config_Param.py
|
||||
# - LocalPV.py
|
||||
# - RecordTemplate.py
|
||||
# - RemotePV.py
|
||||
# - Service_Log.py
|
||||
# - Service_RFStation.py
|
||||
# - Service_Screen.py
|
||||
# - elog.py
|
||||
#
|
||||
# Created by Zheqiao Geng on 29.05.2024
|
||||
#########################################################################
|
||||
import os
|
||||
import time
|
||||
|
||||
from cam_server.pipeline.data_processing import functions, processor
|
||||
from cam_server import utils
|
||||
from logging import getLogger
|
||||
|
||||
from CamDataProcess import *
|
||||
from Service_RFStation import *
|
||||
from Config_Param import *
|
||||
from Service_Log import *
|
||||
|
||||
# ===============================================================
|
||||
# global variables
|
||||
# ===============================================================
|
||||
_logger = getLogger(__name__)
|
||||
initialized = False
|
||||
moduleName = 'ARS05-RCAM-0310'
|
||||
instName = 'SR4'
|
||||
srvRFs = None
|
||||
srvLog = None
|
||||
camPrc = None
|
||||
|
||||
# ===============================================================
|
||||
# init function
|
||||
# ===============================================================
|
||||
def initialize():
|
||||
global srvRFs, srvLog, camPrc, moduleName, instName
|
||||
|
||||
# get the RF station info
|
||||
if instName == 'TS':
|
||||
cav_label = ts_cav_label
|
||||
cpl_label = ts_cpl_label
|
||||
elif instName == 'SR1':
|
||||
cav_label = sr1_cav_label
|
||||
cpl_label = sr1_cpl_label
|
||||
elif instName == 'SR2':
|
||||
cav_label = sr2_cav_label
|
||||
cpl_label = sr2_cpl_label
|
||||
elif instName == 'SR3':
|
||||
cav_label = sr3_cav_label
|
||||
cpl_label = sr3_cpl_label
|
||||
elif instName == 'SR4':
|
||||
cav_label = sr4_cav_label
|
||||
cpl_label = sr4_cpl_label
|
||||
else:
|
||||
cav_label = ''
|
||||
cpl_label = ''
|
||||
|
||||
# define the services
|
||||
srvRFs = Service_RFStation(loc = instName,
|
||||
cav_label = cav_label,
|
||||
cpl_label = cpl_label)
|
||||
srvLog = Service_Log(moduleName, loc = instName)
|
||||
|
||||
# define the jobs
|
||||
camPrc = CamDataProcess(moduleName,
|
||||
instName,
|
||||
srv_scr = None,
|
||||
srv_rfs = srvRFs,
|
||||
srv_log = srvLog,
|
||||
f_path = file_path)
|
||||
|
||||
# connect to all PVs
|
||||
RemotePV.connect()
|
||||
time.sleep(2.0)
|
||||
|
||||
# start the threads
|
||||
camPrc.start()
|
||||
_logger.info('EPICS_CA_ADDR_LIST = ' + str(os.environ.get('EPICS_CA_ADDR_LIST')))
|
||||
_logger.info('Data Path: ' + camPrc.f_path)
|
||||
_logger.info("Initialized")
|
||||
|
||||
# ===============================================================
|
||||
# implement the image processing function (replacing the thread
|
||||
# function "DataRecvProcFunc" in "CamDataProcess.py")
|
||||
# ===============================================================
|
||||
def process_image(image, pulse_id, timestamp, x_axis, y_axis, parameters, bsdata=None):
|
||||
# declare the global variables
|
||||
global camPrc, initialized
|
||||
|
||||
try:
|
||||
# initialization
|
||||
if not initialized:
|
||||
initialize()
|
||||
initialized = True
|
||||
|
||||
# basic process of the image
|
||||
data = { 'timestamp' : utils.timestamp_as_float(timestamp),
|
||||
'width' : len(image[0]),
|
||||
'height' : len(image),
|
||||
'image' : image,
|
||||
'arc_found' : 0}
|
||||
|
||||
# calculate the properties for arc detection
|
||||
x_profile, y_profile = functions.get_x_y_profile(image)
|
||||
min_value, max_value = functions.get_min_max(image)
|
||||
intensity = x_profile.sum()
|
||||
|
||||
data['intensity'] = intensity
|
||||
data['min_value'] = min_value
|
||||
data['max_value'] = max_value
|
||||
data['x_profile'] = x_profile
|
||||
data['y_profile'] = y_profile
|
||||
|
||||
# store to the circular buffer
|
||||
camPrc.receiveImage(data)
|
||||
return data
|
||||
except Exception as e:
|
||||
_logger.warning(str(e))
|
||||
return None
|
||||
|
||||
|
||||
|
||||
32
configuration/user_scripts/sp_pipolar.py
Normal file
32
configuration/user_scripts/sp_pipolar.py
Normal file
@@ -0,0 +1,32 @@
|
||||
import sys
|
||||
import os
|
||||
from emittance import calculate_emittance
|
||||
from cam_server.pipeline.data_processing import functions, processor
|
||||
|
||||
def process_image(image, pulse_id, timestamp, x_axis, y_axis, parameters, bsdata=None):
|
||||
ret = processor.process_image(image, pulse_id, timestamp, x_axis, y_axis, parameters, bsdata)
|
||||
|
||||
camera = parameters["camera_name"]
|
||||
emittance = emittance2 = float("NaN")
|
||||
status = "Ok"
|
||||
try:
|
||||
r = calculate_emittance(image, parameters['fit'])
|
||||
if r is not None:
|
||||
emittance,emittance2=r
|
||||
|
||||
except Exception as e:
|
||||
status="Error: "
|
||||
exc_type, exc_obj, exc_tb = sys.exc_info()
|
||||
while exc_tb is not None:
|
||||
fname = os.path.split(exc_tb.tb_frame.f_code.co_filename)[1]
|
||||
status = status + fname + " line " + str(exc_tb.tb_lineno) + ": " + str(e) + " | "
|
||||
exc_tb = exc_tb.tb_next
|
||||
|
||||
ret["emittance"] = emittance
|
||||
ret["emittance2"] = emittance2
|
||||
ret["emittance_status"] = str(status)
|
||||
|
||||
ret["y_fit_standard_deviation_orig"] = ret["y_fit_standard_deviation"]
|
||||
ret["y_fit_standard_deviation"] = emittance
|
||||
|
||||
return ret
|
||||
Reference in New Issue
Block a user