The hardware of the ATTPC DAQ consist of one workstation (two network cards at least, one could be SFP+ network card), one $$\mu$$TCA crate. Inside the $$\mu$$TCA crate, a MTH module (must have a fiber port and an ethernet port), a power module and a series of Cobo boards are installed.
Get electronics power supply
The power supply should provide 5 V low voltage. The supply module we are using is Mpod-mini and the power cable from the power module to ASAD card is a half-customized, which is 4 Molex connector (9-pin Dsub to wires: part number 83421-9044) connected to a regular 37-pin Dsub connector. The power cable mapping is shown below. (also the AI file)
Test GET electronics with internal pulsers
1. run GetController and open test recorded as test
the configurations are listed below,
ECC: 127.0.0.1: 46002
DAQ: 192.168.50.1:46005
Target: 192.168.40.81:46001
Hardware: hardwareDescription_fullCoBoStandAlone.xcfg
Conditions: configure-pulser.xcfg
Data: /home/daq/DAQ/example_pulser/data
where 192.168.50.1 is the network card connecting to the data port of the Cobo, 192.168.40.81 is the ip of the control part of Cobo
2. open the vmplayer and turn on windows 10. Open the Winner Power Supply application (making sure the usb channel of the power supply is connected to Windows 10, not ubuntu)
The output of the power supply is set to be 3.6 V.
3. Open one terminal, type getEccServer
Open another terminal, type GetEccController
Also in the configure-pulser.xcfg file, the Setup->Node->Instance[*]->Asad[?]->Control->isActive needs to be set correctly for connected AsAd. If not the program will not run.
then, simply sequentially click Load Hw, Configure, and Start. When finish click stop and reset.
4. To view the offline data, you can use cobo-frame-viewer .
Upgrade Cobo firmware
I tried below according to the instructions, but it does not work !!!!!!!!!!!!!!!!!!!!!!!
The latest Cobo firmware is firmware250.bit
according to Shebli, the following procedure is used for upgrading the install the Xillinx cable driver
Notes on Xilinx Tools ¶
These notes have been taken during install on Ubuntu 10.04 LTS . Since Xilinx supports RHEL things might be easier on SL6.
Update Ubuntu 10.04 LTS
As this version of Ubuntu is not supported anymore,apt-get won’t work. A few things need to be changed.
sudo sed -i -re 's/([a-z]{2}\.)?archive.ubuntu.com|security.ubuntu.com/old-releases.ubuntu.com/g' /etc/apt/sources.list
sudo apt-get update
Xilinx Tools Install On Linux
- Download Xilinx_ISE_DS_Lin_12.4_M.81d.2.0.tar (for version 12.4) from Xilinx web site (need to have developer login).
- Untar downloaded file (typically in /opt using a sudo account).
- cd to extracted directory and type sudo ./xsetup and follow instructions. Choose no to acquire licence because it is a will be setup through environment variables (see further).
USB Drivers for Xilinx JTAG Cable
- Install libusb-dev and libftdi-dev using your package manager.
- Install fxload using your package manager.
- Download Xilinx cable USB driver sources.
- Compile sources typing make
- Install the library produced libusb-driver.so (typically by copying it to /usr/lib).
- Put the following line in a new file “libusb-driver.rules” in /etc/udev/rules.d/:
ACTION=="add", SUBSYSTEMS=="usb", ATTRS{idVendor}=="03fd", MODE="666"
- If your cable does not have the ID 03fd:0008 in the output of lsusb command, the initial firmware has not been loaded (loading it changes the product-ID from another value to 8). To load the firmware follow these steps:
- Make sure you have installed the libusb-dev and fxload packages.
- If you have no /etc/udev/rules.d/xusbdfwu.rules file, copy it from /path/to/ISE/bin/lin/xusbdfwu.rules to /etc/udev/rules.d/xusbdfwu.rules.
- If your Linux distro is not too old (e.g. > Ubuntu 9.10), you are probably running a fairly recent version of udev, so you’ll need to adapt the rules file accordingly, using the following command:
sed -i -e 's/TEMPNODE/tempnode/' -e 's/SYSFS/ATTRS/g' -e 's/BUS/SUBSYSTEMS/' /etc/udev/rules.d/xusbdfwu.rules
- Copy the files /path/to/ISE/bin/lin/xusb*.hex to /usr/share/.
- Restart the udev daemon using the following command and re-plug the USB cable:
service udev restart
The LED on the XIlinx cable should be GREEN. Also, the lsusb command should list (among other USB devices) the Xilinx cable with its ID finishing with digit 8. Typically:
% lsusb | grep Xilinx
Bus 001 Device 003: ID 03fd:0008 Xilinx, Inc.
^
This digit should be set to '8'
Set Up Xilinx Environment variables
This is the typical env variables that you must add to your .bashrc (you should adapt it to your case of course), including the LM_LICENSE_FILE variable referring to the licence server:
if [ ! $XILINX ]; then
export LM_LICENSE_FILE=2100@dappcq227:1717@irfupcj44:$LM_LICENSE_FILE
export XILINX_INSTALL=/opt/Xilinx/12.4/ISE_DS
source $XILINX_INSTALL/settings64.sh
export LD_LIBRARY_PATH=/usr/lib:$LD_LIBRARY_PATH:/opt/Xilinx/usb-driver
export LMC_HOME=$XILINX_INSTALL/ISE/smartmodel:$LMC_HOME
export XIL_IMPACT_USE_LIBUSB=1
export PRINTER=irfulpy90
fi
Installing GET software
sudo apt-get install subversion g++ automake autoconf libtool pkg-config libboost-all-dev libreadline-dev libncurses-dev libqt4-dev libqwt-dev libqwtplot3d-qt4-dev zeroc-ice zeroc-icee gsoap liblog4cxx10-dev libmysqlclient-dev
RELEASE=20170928 DEST=/tmp/20170928 source ./download_get_components.sh
SRC=/tmp/20170928 PREFIX=/usr/local source ./install_get_components.sh
The 20170928 is the release date, which you can find in https://dsm-trac.cea.fr/get/wiki/Releases.
Run Cobo with internal pulser
After decompressing the tarball:
– open a terminal and, from the config subdirectory, run getEccServer
– open a terminal and, from the data directory, run dataRouter (GetController must not be running as dataRouter uses the same port)
– open a terminal and, from the config subdirectory, run getEccClient
– from the prompt of getEccClient, execute “exec init_and_start.ecc”
DataFactory.py
The file read in two SQLite databases, the data file and the map file.
In the ADCdf table, each of the entry is the signal trace for each of the 253 channel of the chamber.
The first preliminary filter is that for each signal trace, there are two threshold, 1. must be larger than the 20% of the larget amplitude; 2 must be larger than 20. Each of the time bin must be larger than both of the threshold.
A list of positions are extract from the traces (R,z), R is radial of the centroid of the pad , z is the number of the time bin.
The four quadrants are used to construct two images using each opposite pairs. The overlapping score (a overlapping on the edge (y=0 or 300) yield larger score than a overlapping in the center (y=150) ) is calculated to determine the direction of aligning the two images.
A enlarged reconstructed image is presented below
Besides that, as the image is fully contaminated by noisy data and disconnected points. The prepossessing steps consist GaussianBlur, threshold, erode and dilate.
__init__(self,data_path,map_path): initialization of DataFactory
data_path (str): the relative path to the data file
map_path (str): the relative path to the ATTPC map file
this module loads the ADC table into pandas spreadsheet. Then the function iterate through all channels to see at which time bin the signal amplitude is above threshold and store all the filtered signals into t3.
ConstructImage(self,EID):
EID (int): the EventID of the event for constructing the image
This function takes the spreadsheet t3 from __init__ function, and then produce an image using the positions for each “EventID”.
VertexAnalyzor.py
The overall functions should be used in the sequence below
Each of the functions calls sub functions in the flow presented in the graph below
An example of the original image is shown below,
FilterBackground(image): as the image is messy, this function take the connected convexHull to clean up everything outside this hull.
image (numpy 2d uint8 array): the original image
GetEventPositions(pic,debug_mode=0, center_width = 12, quadrant_thresh=100, center_thresh=300, err_thresh =12, spread_thresh=6 ): get all the three tip points and also the vertex point
pic (numpy 2d uint8 array): the original image
debug_mode (bool): plot some debug features, this should be turned off in batch mode
center_width (float): not used for now
quadrant_thresh (float): threshold for number of pixel in the reaction product part
center_thresh (float): threshold for the beam part
err_thresh (float): threshold for average distance to the fit
spread_thresh (float): threshold for x,y spread out
AveDist(x,y,k,b): calculate the average distance from (x,y) to a straight line with (k,b) parameters.
x (numpy float array): the x positions
y (numpy float array): the y positions
k (float): the slope of the line
b (float): the y-intercept of the line
return (float): average distance from (x,y) to the line (k,b)
r2(x,y,k,b): just to calculate the r2 score of the fitting
parameters are the same to function above
return (float): r2 score
VertexPos(fits,y0): using all fitting results and the y position from the right most tip point to estimate the vertex position
The function divide the calculation to 2 scenarios. 1. you have 2 or 3 fitted lines, then you just pick the parameters of the first two lines for the calculation. 2. if you have only 1 line and this one will not be you center line (because of previous fitting condition), you assume the center line is straight on y0.
fits ([int,float,float,float]*3): fit results for three parts of the image
return (float,float): (x,y)
tbjcfit(xs,ys): use SVD to calculate the least square DISTANCE (not y) fitting
xs (numpy float array): the x positions
ys (numpy float array): the y positions
return (int,float,float,float):(number of pixels, k,b,average distance)
GetFit(image_, part_thresh=60, err_thresh =1.2,spread_thresh=6): this function extract the x,y positions of each pixel above 0 value. Then fit the x,y points using tbjcfit. The results will be filtered through a few conditions to see if the fitting is good, like if the average distance from the points to the line is within the err_thresh and if the scattered positions does give a reasonable line shape distribution.
image_ (numpy 2d uint8 array): the part of the image you want to obtain a line fitting
part_thresh (float): if the number of pixels in the image is large enough for a fitting
err_thresh (float):the average distance to the fitting line of all the points
spread_thresh (float):the threshold for requiring a spread out distributed data on either x or y axis
return (numpy 2d uint8 array): a copy of filtered image
GetLineInfo(p1,p2, L_thre = -5): calculate the length and angle between two points
p1 (float,float): the tip point
p2 (float,float): the vertex point
L_thre = -5: not used for now
GetEventInfo(points,p0): calculate the length and angle for between each pair of the tip point and the vertex point
points ((float,float)*3): the positions of the tip points
p0 (float,float): the position of the vertex point
return ((float,float)*3,float): (theta,length) for each pair, and the reaction range
Distance(contours,n1,n2): calculate the minimum distance between two contour
contours [numpy.array (n,1,2)]:all the contours
n1 (int): index of the first contour
n2 (int): index of the second contour
return (float): the minimum distance
Groups(contours): combine all adjacent contours
contours [numpy.array (n,1,2)]:all the contours
return ((float)*n, (float)*n): grouped contours
convexHull(thresh, debug_mode = 0): calculated the convexHull using the largest grouped contour
thresh (numpy 2d uint8 array): image after preliminary processing
return ((float,float)*n): the hull points
MaxEnclosedTriangle(hull): calculate the maximum enclosed triangle using the hull points
hull ((float,float)*n): the hull points
return (int, int, int): index of the hull points to form the maximum enclosed triangle
TipFinder(thresh, debug_mode = 0): return the position of the tip on the maximum enclosed triangle
thresh (numpy 2d uint8 array): image after preliminary processing
return ((float,float)*3): the position of the tip on the maximum enclosed triangle
tbjcATTPCanalyzor
Since most of the analysis work happens in the python code, it deserves a independent post for explaining all the code. So far the code will only works for two body reaction and regular kinematics, where both reaction products are forward focused.
DataFactory.py recontruct a 2D image using signal traces from each of the 253 channels and perform a first-order cleanup in this image
VertexAnalyzor.py contains functions to extract line features from the 2D image.
The package so far is producing reasonable results, which can be observed in the theta1 vs theta2 plot of the two reaction products.
tbjcATTPCroot Installation Instructions
Finally, I think I should write a instruction of using my code.
The code is basically divided into two parts. The C++ convertor, which is inherited from Yassid’s ATTPCroot and python analysis code. Between those two, there is also a python script converting the root tree data files into SQLite.
The convertor and all other pyhton code needs to be installed differently.
Convertor :
The C++ part of the convertor converts a Raw binary data file to a Root tree file; then you need the python convertor to convert the Root tree file to a SQLite database.
Installation Requirements: Root>6.xx, Boost, CMake, Linux environment, Python (Anaconda 2.x is recommended)
Installation steps:
### C++ part ###
to build:
mkdir build
cd build
cmake ..
### python part ###
### download the Anaconda 2.x https://www.anaconda.com/download/#linux
bash Anaconda-2.x.x-Linux-x86[_64].sh
How to run:
There are two ways of running the program.
- single process: in the main folder, (the build/example will only run in the main folder)
./build/example <root file name> <Binary file name> ## this convert binary data to root tree file
python tbjcConvertor/Convertor_sqlite.py <root file name> <SQLite database name> ## this convert the root tree file to SQLite database
- multi process:
python mult.py
Tested System:
Ubuntu 16.04.1 LTS
Red Hat Enterprise Linux Server release 7.4 (Maipo)
Multiprocess:
The C++ code is a single thread and process program, which can be paralleled (multiprocess) through the multi.py
In multi.py, there are three variables need to be changed, all of the variables are RELATIVE DIRECTORY
parentPath: the relative directory of the parent folder of the DATA FOLDERS of the raw binary
SQLpath: where you want to store all your converted SQLite databases
paths: all the data folders you want to convert
Analysis Part:
Ideally, the analysis part of the C++ code should be working, including ATHoughTask, ATPSATask, ATAnalysisTask and ATPhiRecoTask. However, it is not commonly used in my analysis work.
What’s different?
As mentioned in the ReadMe file, the FairRoot part and the Root TCloneArray, is completely faked. The fake classes only provide basic functions of iterating tasks and storing temporary variables. However, from my observation, all the analysis tasks should be functioning.
Analysis program :
Though most of the programs are unfinished works, but they should give good insights of what the data look like.
The most complete program is the VertexAnalyzer, which reconstruct the
Requirements:
besides built-in Anaconda packages, you will also need opencv2 and seaborn (mainly for visualizing, when debug option is on)
conda install -c menpo opencv
conda install seaborn
Tested System:
Ubuntu 16.04.1 LTS
Red Hat Enterprise Linux Server release 7.4 (Maipo)
Running:
under the main folder, run for the multi-process mode
python Multi.py
or run the jupyter notebook interactive mode
jupyter notebook
the Multi.py will produce a text file contains a list of ranges for reaction length.