Compare commits
No commits in common. "Master" and "NUMEN" have entirely different histories.
16
.gitignore
vendored
|
@ -1,5 +1,6 @@
|
|||
working/Logs
|
||||
|
||||
EventBuilder
|
||||
*.root
|
||||
*.pcm
|
||||
*.d
|
||||
|
@ -7,16 +8,9 @@ working/Logs
|
|||
|
||||
.gdb_history
|
||||
|
||||
data
|
||||
data_raw
|
||||
root_data
|
||||
|
||||
*.in
|
||||
*.out
|
||||
*.txt
|
||||
*.csv
|
||||
*.dat
|
||||
|
||||
Cleopatra/ExtractXSec
|
||||
Cleopatra/ExtractXSecFromText
|
||||
Cleopatra/FindThetaCM
|
||||
|
@ -25,10 +19,4 @@ Cleopatra/Isotope
|
|||
Cleopatra/IsotopeShort
|
||||
Cleopatra/PlotSimulation
|
||||
Cleopatra/PlotTGraphTObjArray
|
||||
Cleopatra/SimAlpha
|
||||
Cleopatra/SimTransfer
|
||||
Cleopatra/SimTransfer_single
|
||||
Cleopatra/Cleopatra
|
||||
|
||||
__pycache__
|
||||
*.DS_Store
|
||||
Cleopatra/Transfer
|
7
.vscode/c_cpp_properties.json
vendored
|
@ -4,9 +4,12 @@
|
|||
"name": "Mac",
|
||||
"includePath": [
|
||||
"${workspaceFolder}/**",
|
||||
"/Applications/root_v6.30.06/include/**"
|
||||
"/Applications/root_v6.28.02/include/**"
|
||||
],
|
||||
"defines": [],
|
||||
"macFrameworkPath": [
|
||||
"/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/System/Library/Frameworks"
|
||||
],
|
||||
"compilerPath": "/usr/bin/g++",
|
||||
"cStandard": "c17",
|
||||
"cppStandard": "c++17",
|
||||
|
@ -29,7 +32,7 @@
|
|||
"name": "WinLinux",
|
||||
"includePath": [
|
||||
"${workspaceFolder}/**",
|
||||
"/home/ryan/root_v6.30.06/include/**"
|
||||
"/home/ryan/Downloads/root/include/**"
|
||||
],
|
||||
"defines": [],
|
||||
"compilerPath": "/usr/bin/gcc",
|
||||
|
|
134
.vscode/settings.json
vendored
|
@ -1,13 +1,129 @@
|
|||
{
|
||||
"files.associations": {
|
||||
"detectorGeo.txt": "shellscript",
|
||||
"reactionConfig.txt": "shellscript",
|
||||
"DWBA": "shellscript",
|
||||
"SimChecker_Config.txt": "fsharp",
|
||||
"*.C": "cpp"
|
||||
"script.C": "cpp",
|
||||
"SOLARIS_Qt6_DAQ.pro": "makefile",
|
||||
"qlineseries": "cpp",
|
||||
"cctype": "cpp",
|
||||
"clocale": "cpp",
|
||||
"cmath": "cpp",
|
||||
"cstdarg": "cpp",
|
||||
"cstddef": "cpp",
|
||||
"cstdio": "cpp",
|
||||
"cstdlib": "cpp",
|
||||
"cstring": "cpp",
|
||||
"ctime": "cpp",
|
||||
"cwchar": "cpp",
|
||||
"cwctype": "cpp",
|
||||
"array": "cpp",
|
||||
"atomic": "cpp",
|
||||
"bit": "cpp",
|
||||
"*.tcc": "cpp",
|
||||
"chrono": "cpp",
|
||||
"codecvt": "cpp",
|
||||
"compare": "cpp",
|
||||
"concepts": "cpp",
|
||||
"condition_variable": "cpp",
|
||||
"cstdint": "cpp",
|
||||
"deque": "cpp",
|
||||
"list": "cpp",
|
||||
"map": "cpp",
|
||||
"string": "cpp",
|
||||
"unordered_map": "cpp",
|
||||
"unordered_set": "cpp",
|
||||
"vector": "cpp",
|
||||
"exception": "cpp",
|
||||
"algorithm": "cpp",
|
||||
"functional": "cpp",
|
||||
"iterator": "cpp",
|
||||
"memory": "cpp",
|
||||
"memory_resource": "cpp",
|
||||
"numeric": "cpp",
|
||||
"optional": "cpp",
|
||||
"random": "cpp",
|
||||
"ratio": "cpp",
|
||||
"string_view": "cpp",
|
||||
"system_error": "cpp",
|
||||
"tuple": "cpp",
|
||||
"type_traits": "cpp",
|
||||
"utility": "cpp",
|
||||
"future": "cpp",
|
||||
"initializer_list": "cpp",
|
||||
"iomanip": "cpp",
|
||||
"iosfwd": "cpp",
|
||||
"iostream": "cpp",
|
||||
"istream": "cpp",
|
||||
"limits": "cpp",
|
||||
"mutex": "cpp",
|
||||
"new": "cpp",
|
||||
"numbers": "cpp",
|
||||
"ostream": "cpp",
|
||||
"semaphore": "cpp",
|
||||
"span": "cpp",
|
||||
"sstream": "cpp",
|
||||
"stdexcept": "cpp",
|
||||
"stop_token": "cpp",
|
||||
"streambuf": "cpp",
|
||||
"thread": "cpp",
|
||||
"cinttypes": "cpp",
|
||||
"typeinfo": "cpp",
|
||||
"variant": "cpp",
|
||||
"qdatetime": "cpp",
|
||||
"fstream": "cpp",
|
||||
"allocator": "cpp",
|
||||
"qsignalmapper": "cpp",
|
||||
"GeneralSort.C": "cpp",
|
||||
"ChainMonitors.C": "cpp",
|
||||
"GeneralSortAgent.C": "cpp",
|
||||
"readRawTrace.C": "cpp",
|
||||
"readTrace.C": "cpp",
|
||||
"Cleopatra.C": "cpp",
|
||||
"alpha.C": "cpp",
|
||||
"DWBA_compare.C": "cpp",
|
||||
"DWBARatio.C": "cpp",
|
||||
"ExtractXSec.C": "cpp",
|
||||
"ExtractXSecFromText.C": "cpp",
|
||||
"FindThetaCM.C": "cpp",
|
||||
"InFileCreator.C": "cpp",
|
||||
"IsotopeShort.C": "cpp",
|
||||
"knockout.C": "cpp",
|
||||
"PlotSimulation.C": "cpp",
|
||||
"PlotTGraphTObjArray.C": "cpp",
|
||||
"transfer_test.C": "cpp",
|
||||
"Transfer.C": "cpp",
|
||||
"Simulation_Helper.C": "cpp",
|
||||
"Check_Simulation.C": "cpp",
|
||||
"AutoFit.C": "cpp",
|
||||
"__hash_table": "cpp",
|
||||
"__split_buffer": "cpp",
|
||||
"__tree": "cpp",
|
||||
"bitset": "cpp",
|
||||
"stack": "cpp",
|
||||
"Monitor.C": "cpp",
|
||||
"DataHoSei.C": "cpp",
|
||||
"Monitors.C": "cpp",
|
||||
"__bit_reference": "cpp",
|
||||
"__bits": "cpp",
|
||||
"__config": "cpp",
|
||||
"__debug": "cpp",
|
||||
"__errc": "cpp",
|
||||
"__locale": "cpp",
|
||||
"__mutex_base": "cpp",
|
||||
"__node_handle": "cpp",
|
||||
"__nullptr": "cpp",
|
||||
"__string": "cpp",
|
||||
"__threading_support": "cpp",
|
||||
"__tuple": "cpp",
|
||||
"complex": "cpp",
|
||||
"forward_list": "cpp",
|
||||
"ios": "cpp",
|
||||
"locale": "cpp",
|
||||
"__verbose_abort": "cpp",
|
||||
"Monitors_Util.C": "cpp",
|
||||
"Monitor_Util.C": "cpp",
|
||||
"script_single.C": "cpp",
|
||||
"script_multi.C": "cpp"
|
||||
},
|
||||
|
||||
"C_Cpp.autoAddFileAssociations": false,
|
||||
|
||||
"better-comments.multilineComments": true,
|
||||
"better-comments.tags" : [
|
||||
{
|
||||
|
@ -20,10 +136,10 @@
|
|||
},
|
||||
{
|
||||
"tag": "?",
|
||||
"color": "#1FE0CB",
|
||||
"color": "#0076FF",
|
||||
"strikethrough": false,
|
||||
"backgroundColor": "transparent",
|
||||
"bold": true,
|
||||
"bold": false,
|
||||
"italic": false
|
||||
},
|
||||
{
|
||||
|
|
|
@ -1,392 +0,0 @@
|
|||
#ifndef ANALYSIS_LIB_H
|
||||
#define ANALYSIS_LIB_H
|
||||
|
||||
#include <cstdio>
|
||||
#include <vector>
|
||||
#include <fstream>
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
|
||||
#include <TMacro.h>
|
||||
#include <TList.h>
|
||||
#include <TFile.h>
|
||||
#include <TMath.h>
|
||||
#include <TObjArray.h>
|
||||
#include <TCutG.h>
|
||||
#include <TGraph.h>
|
||||
|
||||
namespace AnalysisLib {
|
||||
|
||||
//*######################################### Execute Python Script
|
||||
std::vector<std::string> executePythonScript(std::string command) {
|
||||
std::vector<std::string> result;
|
||||
printf("Python : %s \n", command.c_str());
|
||||
FILE* pipe = popen(command.c_str(), "r");
|
||||
if (!pipe) {
|
||||
std::cerr << "Failed to open pipe for command: " << command << std::endl;
|
||||
return result;
|
||||
}
|
||||
|
||||
constexpr int buffer_size = 256;
|
||||
char buffer[buffer_size];
|
||||
|
||||
while (fgets(buffer, buffer_size, pipe) != nullptr) {
|
||||
result.emplace_back(buffer);
|
||||
}
|
||||
|
||||
pclose(pipe);
|
||||
return result;
|
||||
}
|
||||
|
||||
//*######################################### TRAPEZOID
|
||||
TGraph * TrapezoidFilter(TGraph * trace, int baseLineEnd = 80, int riseTime = 10, int flatTop = 20, float decayTime = 2000){
|
||||
///Trapezoid filter https://doi.org/10.1016/0168-9002(94)91652-7
|
||||
|
||||
TGraph * trapezoid = new TGraph();
|
||||
trapezoid->Clear();
|
||||
|
||||
///find baseline;
|
||||
double baseline = 0;
|
||||
for( int i = 0; i < baseLineEnd; i++){
|
||||
baseline += trace->Eval(i);
|
||||
}
|
||||
baseline = baseline*1./baseLineEnd;
|
||||
|
||||
int length = trace->GetN();
|
||||
|
||||
double pn = 0.;
|
||||
double sn = 0.;
|
||||
for( int i = 0; i < length ; i++){
|
||||
|
||||
double dlk = trace->Eval(i) - baseline;
|
||||
if( i - riseTime >= 0 ) dlk -= trace->Eval(i - riseTime) - baseline;
|
||||
if( i - flatTop - riseTime >= 0 ) dlk -= trace->Eval(i - flatTop - riseTime) - baseline;
|
||||
if( i - flatTop - 2*riseTime >= 0) dlk += trace->Eval(i - flatTop - 2*riseTime) - baseline;
|
||||
|
||||
if( i == 0 ){
|
||||
pn = dlk;
|
||||
sn = pn + dlk*decayTime;
|
||||
}else{
|
||||
pn = pn + dlk;
|
||||
sn = sn + pn + dlk*decayTime;
|
||||
}
|
||||
trapezoid->SetPoint(i, i, sn / decayTime / riseTime);
|
||||
}
|
||||
return trapezoid;
|
||||
}
|
||||
|
||||
bool isEmptyOrSpaces(const std::string& str) {
|
||||
if (str.empty()) {
|
||||
return true;
|
||||
}
|
||||
for (char c : str) {
|
||||
if (!std::isspace(c)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
std::vector<std::string> SplitStr(std::string tempLine, std::string splitter, int shift = 0){
|
||||
|
||||
std::vector<std::string> output;
|
||||
|
||||
size_t pos;
|
||||
do{
|
||||
pos = tempLine.find(splitter); /// fine splitter
|
||||
if( pos == 0 ){ ///check if it is splitter again
|
||||
tempLine = tempLine.substr(pos+1);
|
||||
continue;
|
||||
}
|
||||
|
||||
std::string secStr;
|
||||
if( pos == std::string::npos ){
|
||||
secStr = tempLine;
|
||||
}else{
|
||||
secStr = tempLine.substr(0, pos+shift);
|
||||
tempLine = tempLine.substr(pos+shift);
|
||||
}
|
||||
|
||||
///check if secStr is begin with space
|
||||
while( secStr.substr(0, 1) == " ") secStr = secStr.substr(1);
|
||||
|
||||
///check if secStr is end with space
|
||||
while( secStr.back() == ' ') secStr = secStr.substr(0, secStr.size()-1);
|
||||
|
||||
output.push_back(secStr);
|
||||
///printf(" |%s---\n", secStr.c_str());
|
||||
|
||||
}while(pos != std::string::npos );
|
||||
|
||||
return output;
|
||||
};
|
||||
|
||||
//************************************** TCutG
|
||||
|
||||
TObjArray * LoadListOfTCut(TString fileName, TString cutName = "cutList"){
|
||||
|
||||
if( fileName == "" ) return nullptr;
|
||||
|
||||
TObjArray * cutList = nullptr;
|
||||
|
||||
TFile * fCut = new TFile(fileName);
|
||||
bool isCutFileOpen = fCut->IsOpen();
|
||||
if(!isCutFileOpen) {
|
||||
printf( "Failed to open rdt-cutfile 1 : %s\n" , fileName.Data());
|
||||
}else{
|
||||
cutList = (TObjArray *) fCut->FindObjectAny(cutName);
|
||||
|
||||
if( cutList ){
|
||||
int numCut = cutList->GetEntries();
|
||||
printf("=========== found %d cutG in %s \n", numCut, fCut->GetName());
|
||||
|
||||
for(int i = 0; i < numCut ; i++){
|
||||
printf("cut name : %s , VarX: %s, VarY: %s, numPoints: %d \n",
|
||||
cutList->At(i)->GetName(),
|
||||
((TCutG*)cutList->At(i))->GetVarX(),
|
||||
((TCutG*)cutList->At(i))->GetVarY(),
|
||||
((TCutG*)cutList->At(i))->GetN()
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return cutList;
|
||||
}
|
||||
|
||||
TCutG * LoadSingleTCut( TString fileName, TString cutName = "cutEZ"){
|
||||
|
||||
if( fileName == "" ) return nullptr;
|
||||
TCutG * cut = nullptr;
|
||||
|
||||
TFile * fCut = new TFile(fileName);
|
||||
bool isCutFileOpen = fCut->IsOpen();
|
||||
if( !isCutFileOpen) {
|
||||
printf( "Failed to open E-Z cutfile : %s\n" , fileName.Data());
|
||||
}else{
|
||||
cut = (TCutG *) fCut->FindObjectAny(cutName);
|
||||
if( cut != NULL ) {
|
||||
printf("Found EZ cut| name : %s, VarX: %s, VarY: %s, numPoints: %d \n",
|
||||
cut->GetName(),
|
||||
cut->GetVarX(),
|
||||
cut->GetVarY(),
|
||||
cut->GetN()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return cut;
|
||||
}
|
||||
|
||||
|
||||
//************************************** Others
|
||||
std::vector<std::vector<double>> combination(std::vector<double> arr, int r){
|
||||
|
||||
std::vector<std::vector<double>> output;
|
||||
|
||||
int n = arr.size();
|
||||
std::vector<int> v(n);
|
||||
std::fill(v.begin(), v.begin()+r, 1);
|
||||
do {
|
||||
//for( int i = 0; i < n; i++) { printf("%d ", v[i]); }; printf("\n");
|
||||
|
||||
std::vector<double> temp;
|
||||
for (int i = 0; i < n; ++i) {
|
||||
if (v[i]) {
|
||||
//printf("%.1f, ", arr[i]);
|
||||
temp.push_back(arr[i]);
|
||||
}
|
||||
}
|
||||
//printf("\n");
|
||||
|
||||
output.push_back(temp);
|
||||
|
||||
} while (std::prev_permutation(v.begin(), v.end()));
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
double* sumMeanVar(std::vector<double> data){
|
||||
|
||||
int n = data.size();
|
||||
double sum = 0;
|
||||
for( int k = 0; k < n; k++) sum += data[k];
|
||||
double mean = sum/n;
|
||||
double var = 0;
|
||||
for( int k = 0; k < n; k++) var += pow(data[k] - mean,2);
|
||||
|
||||
static double output[3];
|
||||
output[0] = sum;
|
||||
output[1] = mean;
|
||||
output[2] = var;
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
double* fitSlopeIntercept(std::vector<double> dataX, std::vector<double> dataY){
|
||||
|
||||
double * smvY = sumMeanVar(dataY);
|
||||
double sumY = smvY[0];
|
||||
double meanY = smvY[1];
|
||||
|
||||
double * smvX = sumMeanVar(dataX);
|
||||
double sumX = smvX[0];
|
||||
double meanX = smvX[1];
|
||||
double varX = smvX[2];
|
||||
|
||||
int n = dataX.size();
|
||||
double sumXY = 0;
|
||||
for( int j = 0; j < n; j++) sumXY += dataX[j] * dataY[j];
|
||||
|
||||
double slope = ( sumXY - sumX * sumY/n ) / varX;
|
||||
double intercept = meanY - slope * meanX;
|
||||
|
||||
static double output[2];
|
||||
output[0] = slope;
|
||||
output[1] = intercept;
|
||||
|
||||
return output;
|
||||
|
||||
}
|
||||
|
||||
std::vector<std::vector<double>> FindMatchingPair(std::vector<double> enX, std::vector<double> enY){
|
||||
|
||||
//output[0] = fitEnergy;
|
||||
//output[1] = refEnergy;
|
||||
|
||||
int nX = enX.size();
|
||||
int nY = enY.size();
|
||||
|
||||
std::vector<double> fitEnergy;
|
||||
std::vector<double> refEnergy;
|
||||
|
||||
if( nX > nY ){
|
||||
|
||||
std::vector<std::vector<double>> output = combination(enX, nY);
|
||||
|
||||
double * smvY = sumMeanVar(enY);
|
||||
double sumY = smvY[0];
|
||||
double meanY = smvY[1];
|
||||
double varY = smvY[2];
|
||||
|
||||
double optRSquared = 0;
|
||||
double absRSqMinusOne = 1;
|
||||
int maxID = 0;
|
||||
|
||||
for( int k = 0; k < (int) output.size(); k++){
|
||||
|
||||
double * smvX = sumMeanVar(output[k]);
|
||||
double sumX = smvX[0];
|
||||
double meanX = smvX[1];
|
||||
double varX = smvX[2];
|
||||
|
||||
double sumXY = 0;
|
||||
for( int j = 0; j < nY; j++) sumXY += output[k][j] * enY[j];
|
||||
|
||||
double rSq = abs(sumXY - sumX*sumY/nY)/sqrt(varX*varY);
|
||||
|
||||
//for( int j = 0; j < nY ; j++){ printf("%.1f, ", output[k][j]); }; printf("| %.10f\n", rSq);
|
||||
|
||||
if( abs(rSq-1) < absRSqMinusOne ) {
|
||||
absRSqMinusOne = abs(rSq-1);
|
||||
optRSquared = rSq;
|
||||
maxID = k;
|
||||
}
|
||||
}
|
||||
|
||||
fitEnergy = output[maxID];
|
||||
refEnergy = enY;
|
||||
|
||||
printf(" R^2 : %.20f\n", optRSquared);
|
||||
|
||||
//calculation fitting coefficient
|
||||
//double * si = fitSlopeIntercept(fitEnergy, refEnergy);
|
||||
//printf( " y = %.4f x + %.4f\n", si[0], si[1]);
|
||||
|
||||
}else if( nX < nY ){
|
||||
|
||||
std::vector<std::vector<double>> output = combination(enY, nX);
|
||||
|
||||
|
||||
double * smvX = sumMeanVar(enX);
|
||||
double sumX = smvX[0];
|
||||
double meanX = smvX[1];
|
||||
double varX = smvX[2];
|
||||
|
||||
double optRSquared = 0;
|
||||
double absRSqMinusOne = 1;
|
||||
int maxID = 0;
|
||||
|
||||
for( int k = 0; k < (int) output.size(); k++){
|
||||
|
||||
double * smvY = sumMeanVar(output[k]);
|
||||
double sumY = smvY[0];
|
||||
double meanY = smvY[1];
|
||||
double varY = smvY[2];
|
||||
|
||||
double sumXY = 0;
|
||||
for( int j = 0; j < nX; j++) sumXY += output[k][j] * enX[j];
|
||||
|
||||
double rSq = abs(sumXY - sumX*sumY/nX)/sqrt(varX*varY);
|
||||
|
||||
//for( int j = 0; j < nX ; j++){ printf("%.1f, ", output[k][j]); }; printf("| %.10f\n", rSq);
|
||||
|
||||
if( abs(rSq-1) < absRSqMinusOne ) {
|
||||
absRSqMinusOne = abs(rSq-1);
|
||||
optRSquared = rSq;
|
||||
maxID = k;
|
||||
}
|
||||
}
|
||||
|
||||
fitEnergy = enX;
|
||||
refEnergy = output[maxID];
|
||||
printf(" R^2 : %.20f\n", optRSquared);
|
||||
|
||||
}else{
|
||||
fitEnergy = enX;
|
||||
refEnergy = enY;
|
||||
|
||||
//if nX == nY, ther could be cases that only partial enX and enY are matched.
|
||||
|
||||
}
|
||||
|
||||
printf("fitEnergy = ");for( int k = 0; k < (int) fitEnergy.size() ; k++){ printf("%7.2f, ", fitEnergy[k]); }; printf("\n");
|
||||
printf("refEnergy = ");for( int k = 0; k < (int) refEnergy.size() ; k++){ printf("%7.2f, ", refEnergy[k]); }; printf("\n");
|
||||
|
||||
std::vector<std::vector<double>> haha;
|
||||
haha.push_back(fitEnergy);
|
||||
haha.push_back(refEnergy);
|
||||
|
||||
return haha;
|
||||
|
||||
}
|
||||
|
||||
std::string create_range_string(const std::vector<int>& nums) {
|
||||
std::string range_str;
|
||||
int lastNum = nums[0];
|
||||
int rangeStart = lastNum;
|
||||
for (int i = 1; i < (int) nums.size(); i++) {
|
||||
if (nums[i] == lastNum + 1) {
|
||||
lastNum = nums[i];
|
||||
} else {
|
||||
if (rangeStart == lastNum) {
|
||||
range_str += std::to_string(rangeStart) + "_";
|
||||
} else {
|
||||
range_str += std::to_string(rangeStart) + "-" + std::to_string(lastNum) + "_";
|
||||
}
|
||||
rangeStart = lastNum = nums[i];
|
||||
}
|
||||
}
|
||||
// Add the last range
|
||||
if (rangeStart == lastNum) {
|
||||
range_str += std::to_string(rangeStart);
|
||||
} else {
|
||||
range_str += std::to_string(rangeStart) + "-" + std::to_string(lastNum);
|
||||
}
|
||||
return range_str;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,175 +0,0 @@
|
|||
#ifndef Parameters_H
|
||||
#define Parameters_H
|
||||
|
||||
//************************************** Correction parameters;
|
||||
class CorrParas {
|
||||
private:
|
||||
|
||||
int defaultSize;
|
||||
|
||||
public:
|
||||
CorrParas(int defaultSize = 100){
|
||||
is_xn_OK = false;
|
||||
is_xfxne_OK = false;
|
||||
is_e_OK = false;
|
||||
is_xScale_OK = false;
|
||||
is_rdt_OK = false;
|
||||
|
||||
this->defaultSize = defaultSize;
|
||||
};
|
||||
|
||||
void LoadAllCorrections(){
|
||||
LoadXNCorr();
|
||||
LoadXFXN2ECorr();
|
||||
LoadECorr();
|
||||
LoadXScaleCorr();
|
||||
LoadRDTCorr();
|
||||
}
|
||||
|
||||
void CheckCorrParasSize(size_t arraySize, size_t rdtSize){
|
||||
printf("------------ Check Correction parameter sizes\n");
|
||||
|
||||
if( is_xn_OK && xnCorr.size() < arraySize ) {
|
||||
printf(" xnCorr [%zu] < array size %zu. Set xnCorr[1..99] = 1.0 \n", xnCorr.size(), arraySize);
|
||||
for( int i = 0; i < defaultSize; i++ ) xnCorr.push_back(1.0);
|
||||
is_xn_OK = false;
|
||||
}
|
||||
if( is_xfxne_OK && xfxneCorr.size() < arraySize ) {
|
||||
printf(" xfxneCorr [%zu] < array size %zu. Set xfxneCorr[1..99] = (0.0, 1.0) \n", xfxneCorr.size(), arraySize);
|
||||
for( int i = 0; i < defaultSize; i++ ) xfxneCorr.push_back({0.0, 1.0});
|
||||
is_xScale_OK = false;
|
||||
}
|
||||
if( is_e_OK && eCorr.size() < arraySize ) {
|
||||
printf(" eCorr [%zu] < array size %zu. Set eCorr[1..99] = (1.0, 0.0) \n", xnCorr.size(), arraySize);
|
||||
for( int i = 0; i < defaultSize; i++ ) eCorr.push_back({1.0, 0.0});
|
||||
is_e_OK = false;
|
||||
}
|
||||
if( is_xScale_OK && xScale.size() < arraySize ) {
|
||||
printf(" xScale [%zu] < array size %zu. Set xScale[1..99] = 1.0 \n", xScale.size(), arraySize);
|
||||
for( int i = 0; i < defaultSize; i++ ) xScale.push_back(1.0);
|
||||
is_xScale_OK = false;
|
||||
}
|
||||
if( is_rdt_OK && rdtCorr.size() < rdtSize ) {
|
||||
printf(" rdtCorr [%zu] < array size %zu. Set rdtScale[1..99] = (0.0, 1.0) \n", rdtCorr.size(), arraySize);
|
||||
for( int i = 0; i < defaultSize; i++ ) rdtCorr.push_back({0.0, 1.0});
|
||||
is_rdt_OK = false;
|
||||
}
|
||||
|
||||
printf("------------ Done Check Corr. Para. Size.\n");
|
||||
}
|
||||
|
||||
bool is_xn_OK;
|
||||
bool is_xfxne_OK;
|
||||
bool is_e_OK;
|
||||
bool is_xScale_OK;
|
||||
bool is_rdt_OK;
|
||||
|
||||
std::vector<float> xnCorr; //correction of xn to match xf
|
||||
std::vector<std::vector<float>> xfxneCorr; //correction of xn and xf to match e
|
||||
std::vector<std::vector<float>> eCorr; // correction to e, ch -> MeV
|
||||
std::vector<float> xScale; // correction of x to be (0,1)
|
||||
std::vector<std::vector<float>> rdtCorr; // correction of rdt, ch -> MeV
|
||||
|
||||
//~========================================= xf = xn correction
|
||||
void LoadXNCorr(bool verbose = false, const char * fileName = "correction_xf_xn.dat"){
|
||||
printf(" loading xf-xn correction.");
|
||||
xnCorr.clear();
|
||||
std::ifstream file;
|
||||
file.open(fileName);
|
||||
if( file.is_open() ){
|
||||
float a;
|
||||
while( file >> a ) xnCorr.push_back(a);
|
||||
printf(".......... done. size:%zu\n", xnCorr.size());
|
||||
is_xn_OK = true;
|
||||
}else{
|
||||
for( int i = 0; i < defaultSize; i++ ) xnCorr.push_back(1.0);
|
||||
printf(".......... fail. xnCorr[1..99] = 1.0\n");
|
||||
is_xn_OK = false;
|
||||
}
|
||||
file.close();
|
||||
if( verbose ) for(int i = 0; i < (int) xnCorr.size(); i++) printf("%2d | %10.3f\n", i, xnCorr[i]);
|
||||
}
|
||||
|
||||
//~========================================= X-Scale correction
|
||||
void LoadXScaleCorr(bool verbose = false, const char * fileName = "correction_scaleX.dat"){
|
||||
printf(" loading x-Scale correction.");
|
||||
xScale.clear();
|
||||
std::ifstream file;
|
||||
file.open(fileName);
|
||||
if( file.is_open() ){
|
||||
float a;
|
||||
while( file >> a ) xScale.push_back(a);
|
||||
printf("........ done. size:%zu\n", xScale.size());
|
||||
is_xScale_OK = true;
|
||||
}else{
|
||||
for( int i = 0; i < defaultSize; i++ ) xScale.push_back(1.0);
|
||||
printf("........ fail. xScale[1..99] = 1.0\n");
|
||||
is_xScale_OK = false;
|
||||
}
|
||||
file.close();
|
||||
if( verbose ) for(int i = 0; i < (int) xScale.size(); i++) printf("%2d | %10.3f\n", i, xnCorr[i]);
|
||||
}
|
||||
|
||||
//~========================================= e = xf + xn correction
|
||||
void LoadXFXN2ECorr(bool verbose = false, const char * fileName = "correction_xfxn_e.dat"){
|
||||
printf(" loading xf/xn-e correction.");
|
||||
xfxneCorr.clear();
|
||||
std::ifstream file;
|
||||
file.open(fileName);
|
||||
if( file.is_open() ){
|
||||
float a, b;
|
||||
while( file >> a >> b) xfxneCorr.push_back({a, b});
|
||||
printf("........ done. size:%zu\n", xfxneCorr.size());
|
||||
is_xfxne_OK = true;
|
||||
}else{
|
||||
for( int i = 0; i < defaultSize; i++ ) xfxneCorr.push_back({0.0, 1.0});
|
||||
printf("........ fail. xfxneCorr[1..99] = (0.0, 1.0)\n");
|
||||
is_xfxne_OK = false;
|
||||
}
|
||||
file.close();
|
||||
if( verbose ) for(int i = 0; i < (int) xfxneCorr.size(); i++) printf("%2d | %10.3f, %10.3f\n", i, xfxneCorr[i][0], xfxneCorr[i][1]);
|
||||
}
|
||||
|
||||
//~========================================= e correction
|
||||
void LoadECorr(bool verbose = false, const char * fileName = "correction_e.dat"){
|
||||
printf(" loading e correction.");
|
||||
eCorr.clear();
|
||||
std::ifstream file;
|
||||
file.open(fileName);
|
||||
if( file.is_open() ){
|
||||
float a, b;
|
||||
while( file >> a >> b) eCorr.push_back( {a, b} ); // 1/a1, a0 , e' = e * a1 + a0
|
||||
printf(".............. done. size:%zu\n", eCorr.size());
|
||||
is_e_OK = true;
|
||||
}else{
|
||||
for( int i = 0; i < defaultSize; i++ ) eCorr.push_back( {1.0, 0.0} );
|
||||
printf(".............. fail. eCorr[1..99] = (1.0, 0.0) \n");
|
||||
is_e_OK = false;
|
||||
}
|
||||
file.close();
|
||||
if( verbose ) for(int i = 0; i < (int) eCorr.size(); i++) printf("%2d | %10.3f, %10.3f\n", i, eCorr[i][0], eCorr[i][1]);
|
||||
}
|
||||
|
||||
//~========================================= rdt correction
|
||||
void LoadRDTCorr(bool verbose = false, const char * fileName = "correction_rdt.dat"){
|
||||
printf(" loading rdt correction.");
|
||||
rdtCorr.clear();
|
||||
std::ifstream file;
|
||||
file.open(fileName);
|
||||
if( file.is_open() ){
|
||||
float a, b;
|
||||
while( file >> a >> b) rdtCorr.push_back({a, b});
|
||||
printf("............ done. size:%zu\n", rdtCorr.size());
|
||||
is_rdt_OK = true;
|
||||
}else{
|
||||
for( int i = 0; i < defaultSize; i++ ) rdtCorr.push_back( {0.0, 1.0} );
|
||||
printf("............ fail. rdtCorr[1..99] = (0.0, 1.0)\n");
|
||||
is_rdt_OK = false;
|
||||
}
|
||||
file.close();
|
||||
if( verbose ) for(int i = 0; i < (int) rdtCorr.size(); i++) printf("%2d | %10.3f, %10.3f\n", i, rdtCorr[i][0], rdtCorr[i][1]);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
#endif
|
|
@ -1,268 +0,0 @@
|
|||
#ifndef ClassDetGeo_H
|
||||
#define ClassDetGeo_H
|
||||
|
||||
#include <stdio.h> /// for FILE
|
||||
#include <cstdlib>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "TMath.h"
|
||||
#include "TString.h"
|
||||
#include "TMacro.h"
|
||||
|
||||
#include "AnalysisLib.h"
|
||||
|
||||
struct Array{
|
||||
|
||||
bool enable;
|
||||
|
||||
double detPerpDist; /// distance from axis
|
||||
double detWidth; /// width
|
||||
double detLength; /// length
|
||||
double blocker;
|
||||
double firstPos; /// meter
|
||||
double eSigma; /// intrinsic energy resolution MeV
|
||||
double zSigma; /// intrinsic position resolution mm
|
||||
bool detFaceOut; ///detector_facing_Out_or_In
|
||||
std::vector<double> pos; /// realtive position in meter
|
||||
int colDet, rowDet; /// colDet = number of different pos, rowDet, number of same pos
|
||||
std::vector<double> detPos; ///absolute position of detector
|
||||
int numDet; /// colDet * rowDet
|
||||
|
||||
double zMin, zMax;
|
||||
|
||||
void DeduceAbsolutePos(){
|
||||
|
||||
colDet = pos.size();
|
||||
numDet = colDet * rowDet;
|
||||
detPos.clear();
|
||||
|
||||
for(int id = 0; id < colDet; id++){
|
||||
if( firstPos > 0 ) detPos.push_back(firstPos + pos[id]);
|
||||
if( firstPos < 0 ) detPos.push_back(firstPos - pos[colDet - 1 - id]);
|
||||
// printf("%d | %f, %f \n", id, pos[id], detPos[id]);
|
||||
}
|
||||
|
||||
zMin = TMath::Min(detPos.front(), detPos.back()) - (firstPos < 0 ? detLength : 0);
|
||||
zMax = TMath::Max(detPos.front(), detPos.back()) + (firstPos > 0 ? detLength : 0);
|
||||
}
|
||||
|
||||
void Print() const{
|
||||
|
||||
printf("------------------------------- Array\n");
|
||||
|
||||
for(int i = 0; i < colDet ; i++){
|
||||
if( firstPos > 0 ){
|
||||
printf("%d, %8.2f mm - %8.2f mm \n", i, detPos[i], detPos[i] + detLength);
|
||||
}else{
|
||||
printf("%d, %8.2f mm - %8.2f mm \n", i, detPos[i] - detLength , detPos[i]);
|
||||
}
|
||||
}
|
||||
|
||||
printf(" Blocker Position: %8.2f mm \n", firstPos > 0 ? firstPos - blocker : firstPos + blocker );
|
||||
printf(" First Position: %8.2f mm \n", firstPos);
|
||||
printf(" number of det : %d = %d x %d (side x col) \n", numDet, rowDet, colDet);
|
||||
printf(" detector facing : %s\n", detFaceOut ? "Out" : "In");
|
||||
printf(" energy resol.: %f MeV\n", eSigma);
|
||||
printf(" pos-Z resol.: %f mm \n", zSigma);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
struct Auxillary{
|
||||
|
||||
//========== recoil
|
||||
double detPos; //
|
||||
double outerRadius;
|
||||
double innerRadius;
|
||||
|
||||
bool isCoincident;
|
||||
|
||||
double detPos1 = 0; // virtual recoil
|
||||
double detPos2 = 0; // virtual recoil
|
||||
|
||||
//========== enum
|
||||
double elumPos1 = 0;
|
||||
double elumPos2 = 0;
|
||||
|
||||
void Print() const {
|
||||
printf("------------------------------- Auxillary\n");
|
||||
printf(" Recoil detector pos: %8.2f mm, radius: %6.2f - %6.2f mm \n", detPos, innerRadius, outerRadius);
|
||||
|
||||
if( elumPos1 != 0 || elumPos2 != 0 || detPos1 != 0 || detPos2 != 0){
|
||||
printf("=================================== Virtual Detectors\n");
|
||||
if( elumPos1 != 0 ) printf(" Elum 1 pos.: %f mm \n", elumPos1);
|
||||
if( elumPos2 != 0 ) printf(" Elum 2 pos.: %f mm \n", elumPos2);
|
||||
if( detPos1 != 0 ) printf(" Recoil 1 pos.: %f mm \n", detPos1);
|
||||
if( detPos2 != 0 ) printf(" Recoil 2 pos.: %f mm \n", detPos2);
|
||||
printf("=====================================================\n");
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
class DetGeo {
|
||||
|
||||
public:
|
||||
DetGeo(){};
|
||||
DetGeo(TString detGeoTxt){ LoadDetectorGeo(detGeoTxt, false);}
|
||||
DetGeo(TMacro * macro){ LoadDetectorGeo(macro, false);}
|
||||
~DetGeo(){};
|
||||
|
||||
double Bfield; /// T
|
||||
int BfieldSign ; /// sign of B-field
|
||||
double bore; /// bore , mm
|
||||
|
||||
unsigned short numGeo;
|
||||
double zMin, zMax; /// total range span of all arrays
|
||||
|
||||
bool LoadDetectorGeo(TString fileName, bool verbose = true);
|
||||
bool LoadDetectorGeo(TMacro * macro, bool verbose = true);
|
||||
|
||||
//=================== array
|
||||
std::vector<Array> array;
|
||||
std::vector<Auxillary> aux;
|
||||
|
||||
void Print( int printArray = 0) ; // 0 = no print, -1 = print all, 1 = print only enabled
|
||||
|
||||
short GetArrayID(int id){
|
||||
int detCount = 0;
|
||||
for( int i = 0; i < numGeo; i ++ ){
|
||||
detCount += array[i].numDet;
|
||||
if( id < detCount ) return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
};
|
||||
|
||||
inline bool DetGeo::LoadDetectorGeo(TString fileName, bool verbose){
|
||||
|
||||
TMacro * haha = new TMacro();
|
||||
if( haha->ReadFile(fileName) > 0 ) {
|
||||
if( LoadDetectorGeo(haha, verbose) ){
|
||||
delete haha;
|
||||
return true;
|
||||
}else{
|
||||
delete haha;
|
||||
return false;
|
||||
}
|
||||
}else{
|
||||
delete haha;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
///Using TMacro to load the detectorGeo frist,
|
||||
///this indrect method is good for loading detectorGeo from TMacro in root file
|
||||
inline bool DetGeo::LoadDetectorGeo(TMacro * macro, bool verbose){
|
||||
|
||||
if( macro == NULL ) return false;
|
||||
|
||||
TList * haha = macro->GetListOfLines();
|
||||
int numLine = (haha)->GetSize();
|
||||
|
||||
// for( int i = 0; i < 2 ; i++) array[i].pos.clear();
|
||||
|
||||
int detFlag = 0;
|
||||
int detLine = 0;
|
||||
|
||||
for( int i = 0 ; i < numLine; i++){
|
||||
|
||||
std::string line = macro->GetListOfLines()->At(i)->GetName();
|
||||
|
||||
if( AnalysisLib::isEmptyOrSpaces(line) ) continue;
|
||||
|
||||
std::vector<std::string> str = AnalysisLib::SplitStr(line, " ");
|
||||
|
||||
// printf("%3d | %s\n", i, str[0].c_str());
|
||||
if( str[0].find("#//") != std::string::npos ) continue;
|
||||
if( str[0].find("####") != std::string::npos ) break;
|
||||
if( str[0].find("#===") != std::string::npos ) {
|
||||
detFlag ++;
|
||||
array.push_back(Array());
|
||||
aux.push_back(Auxillary());
|
||||
detLine = 0;
|
||||
continue;;
|
||||
}
|
||||
|
||||
if( detFlag == 0 ){
|
||||
if ( detLine == 0 ) {
|
||||
Bfield = atof(str[0].c_str());
|
||||
BfieldSign = Bfield > 0 ? 1: -1;
|
||||
}
|
||||
if ( detLine == 1 ) bore = atof(str[0].c_str());
|
||||
}
|
||||
|
||||
if( detFlag > 0){
|
||||
unsigned short ID = detFlag - 1;
|
||||
if ( detLine == 0 ) array[ID].enable = str[0] == "true" ? true : false;
|
||||
if ( detLine == 1 ) aux[ID].detPos = atof(str[0].c_str());
|
||||
if ( detLine == 2 ) aux[ID].innerRadius = atof(str[0].c_str());
|
||||
if ( detLine == 3 ) aux[ID].outerRadius = atof(str[0].c_str());
|
||||
if ( detLine == 4 ) aux[ID].isCoincident = str[0] == "true" ? true : false;
|
||||
if ( detLine == 5 ) aux[ID].detPos1 = atof(str[0].c_str());
|
||||
if ( detLine == 6 ) aux[ID].detPos2 = atof(str[0].c_str());
|
||||
if ( detLine == 7 ) aux[ID].elumPos1 = atof(str[0].c_str());
|
||||
if ( detLine == 8 ) aux[ID].elumPos2 = atof(str[0].c_str());
|
||||
if ( detLine == 9 ) array[ID].detPerpDist = atof(str[0].c_str());
|
||||
if ( detLine == 10 ) array[ID].detWidth = atof(str[0].c_str());
|
||||
if ( detLine == 11 ) array[ID].detLength = atof(str[0].c_str());
|
||||
if ( detLine == 12 ) array[ID].blocker = atof(str[0].c_str());
|
||||
if ( detLine == 13 ) array[ID].firstPos = atof(str[0].c_str());
|
||||
if ( detLine == 14 ) array[ID].eSigma = atof(str[0].c_str());
|
||||
if ( detLine == 15 ) array[ID].zSigma = atof(str[0].c_str());
|
||||
if ( detLine == 16 ) array[ID].detFaceOut = str[0] == "Out" ? true : false;
|
||||
if ( detLine == 17 ) array[ID].rowDet = atoi(str[0].c_str());
|
||||
if ( detLine >= 18 ) array[ID].pos.push_back(atof(str[0].c_str()));
|
||||
}
|
||||
|
||||
detLine ++;
|
||||
}
|
||||
|
||||
zMin = 99999;
|
||||
zMax = -99999;
|
||||
numGeo = 0;
|
||||
|
||||
for( int i = 0; i < detFlag; i ++ ){
|
||||
array[i].DeduceAbsolutePos();
|
||||
if (array[i].enable ) {
|
||||
numGeo ++;
|
||||
double zmax = TMath::Max(array[i].zMin, array[i].zMax);
|
||||
double zmin = TMath::Min(array[i].zMin, array[i].zMax);
|
||||
if( zmax > zMax ) zMax = zmax;
|
||||
if( zmin < zMin ) zMin = zmin;
|
||||
}
|
||||
}
|
||||
|
||||
if( verbose ) Print(false);
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
inline void DetGeo::Print(int printArray){
|
||||
|
||||
printf("#####################################################\n");
|
||||
printf(" B-field : %8.2f T, %s\n", Bfield, Bfield > 0 ? "out of plan" : "into plan");
|
||||
printf(" Bore : %8.2f mm\n", bore);
|
||||
printf(" No. of det. Set. : %zu \n", array.size());
|
||||
|
||||
printf(" z-Min : %8.2f mm\n", zMin);
|
||||
printf(" z-Max : %8.2f mm\n", zMax);
|
||||
if( printArray != 0 ) {
|
||||
for( size_t i = 0; i < array.size() ; i++){
|
||||
if( printArray > 0 && !array[i].enable ) continue;
|
||||
printf("================================= %zu-th Detector Info (%s)\n", i, array[i].enable ? "enabled" : "disabled");
|
||||
array[i].Print();
|
||||
aux[i].Print();
|
||||
}
|
||||
}
|
||||
printf("#####################################################\n");
|
||||
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,345 +0,0 @@
|
|||
#ifndef ClassReactionConfig_H
|
||||
#define ClassReactionConfig_H
|
||||
|
||||
#include <stdio.h> /// for FILE
|
||||
#include <cstdlib>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "TMath.h"
|
||||
#include "TString.h"
|
||||
#include "TMacro.h"
|
||||
|
||||
#include "AnalysisLib.h"
|
||||
#include "../Cleopatra/ClassIsotope.h"
|
||||
|
||||
struct Recoil {
|
||||
|
||||
Isotope light;
|
||||
unsigned short lightA, lightZ;
|
||||
unsigned short heavyA, heavyZ;
|
||||
|
||||
std::string lightStoppingPowerFile = ""; ///stopping_power_for_light_recoil
|
||||
std::string heavyStoppingPowerFile = ""; ///stopping_power_for_heavy_recoil
|
||||
|
||||
bool isDecay = false; ///isDacay
|
||||
unsigned short decayA = 0; ///decayNucleus_A
|
||||
unsigned short decayZ = 0; ///decayNucleus_Z
|
||||
|
||||
void Print() const {
|
||||
printf(" light : A = %3d, Z = %2d \n", lightA, lightZ);
|
||||
printf(" heavy : A = %3d, Z = %2d \n", heavyA, heavyZ);
|
||||
|
||||
printf(" light stopping file : %s \n", lightStoppingPowerFile.c_str());
|
||||
printf(" heavy stopping file : %s \n", heavyStoppingPowerFile.c_str());
|
||||
printf(" is simulate decay : %s \n", isDecay ? "Yes" : "No");
|
||||
if( isDecay ){
|
||||
printf(" heavy decay : A = %d, Z = %d \n", decayA, decayZ);
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
struct EnergyLevel{
|
||||
|
||||
float Ex, xsec, SF, sigma;
|
||||
|
||||
EnergyLevel(float Ex, float xsec, float SF, float sigma) {
|
||||
this->Ex = Ex;
|
||||
this->xsec = xsec;
|
||||
this->SF = SF;
|
||||
this->sigma = sigma;
|
||||
}
|
||||
|
||||
void Print(std::string str) const {
|
||||
printf("%11.3f %8.1f %5.1f %5.3f%s", Ex, xsec, SF, sigma, str.c_str() );
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
struct ExcitedEnergies {
|
||||
|
||||
std::vector<EnergyLevel> ExList;
|
||||
|
||||
void Clear(){
|
||||
ExList.clear();
|
||||
}
|
||||
|
||||
void Add(float Ex, float xsec, float SF, float sigma){
|
||||
ExList.push_back( EnergyLevel(Ex, xsec, SF, sigma));
|
||||
}
|
||||
|
||||
void Print() const {
|
||||
printf("Energy[MeV] Rel.Xsec SF sigma\n");
|
||||
for( size_t i = 0; i < ExList.size(); i++){
|
||||
ExList[i].Print("\n");
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
class ReactionConfig {
|
||||
|
||||
public:
|
||||
ReactionConfig(){}
|
||||
ReactionConfig(TString configTxt){ LoadReactionConfig(configTxt);}
|
||||
ReactionConfig(TMacro * macro){ LoadReactionConfig(macro);}
|
||||
~ReactionConfig(){}
|
||||
|
||||
Isotope beam;
|
||||
unsigned short beamA, beamZ;
|
||||
float beamEx; ///excitation_energy_of_A[MeV]
|
||||
float beamEnergy; ///MeV/u
|
||||
float beamEnergySigma; ///beam-energy_sigma_in_MeV/u
|
||||
float beamTheta; ///beam-angle_in_mrad
|
||||
float beamThetaSigma; ///beam-emittance_in_mrad
|
||||
float beamX; ///x_offset_of_Beam_in_mm
|
||||
float beamY; ///y_offset_of_Beam_in_mm
|
||||
|
||||
Isotope target;
|
||||
unsigned short targetA, targetZ;
|
||||
bool isTargetScattering; ///isTargetScattering
|
||||
float targetDensity; ///target_density_in_g/cm3
|
||||
float targetThickness; ///targetThickness_in_cm
|
||||
std::string beamStoppingPowerFile; ///stopping_power_for_beam
|
||||
|
||||
std::vector<Recoil> recoil;
|
||||
std::vector<ExcitedEnergies> exList;
|
||||
|
||||
int numEvents; ///number_of_Event_being_generated
|
||||
bool isRedo; ///isReDo
|
||||
|
||||
void SetReactionSimple(int beamA, int beamZ,
|
||||
int targetA, int targetZ,
|
||||
int recoilA, int recoilZ,
|
||||
float beamEnergy_AMeV);
|
||||
|
||||
bool LoadReactionConfig(TString fileName);
|
||||
bool LoadReactionConfig(TMacro * macro);
|
||||
|
||||
void Print(int ID = -1, bool withEx = true) const;
|
||||
|
||||
private:
|
||||
|
||||
};
|
||||
|
||||
inline void ReactionConfig::SetReactionSimple(int beamA, int beamZ,
|
||||
int targetA, int targetZ,
|
||||
int recoilA, int recoilZ,
|
||||
float beamEnergy_AMeV){
|
||||
|
||||
this->beamA = beamA;
|
||||
this->beamZ = beamZ;
|
||||
this->targetA = targetA;
|
||||
this->targetZ = targetZ;
|
||||
|
||||
this->recoil.push_back(Recoil());
|
||||
|
||||
this->recoil.back().lightA = recoilA;
|
||||
this->recoil.back().lightZ = recoilZ;
|
||||
recoil.back().heavyA = this->beamA + this->targetA - recoil.back().lightA;
|
||||
recoil.back().heavyZ = this->beamZ + this->targetZ - recoil.back().lightZ;
|
||||
|
||||
beamEnergy = beamEnergy_AMeV;
|
||||
beamEnergySigma = 0;
|
||||
beamTheta = 0;
|
||||
beamThetaSigma = 0;
|
||||
beamX = 0;
|
||||
beamY = 0;
|
||||
|
||||
}
|
||||
|
||||
inline bool ReactionConfig::LoadReactionConfig(TString fileName){
|
||||
TMacro * haha = new TMacro();
|
||||
if( haha->ReadFile(fileName) > 0 ) {
|
||||
if( LoadReactionConfig(haha) ){
|
||||
delete haha;
|
||||
return true;
|
||||
}else{
|
||||
delete haha;
|
||||
return false;
|
||||
}
|
||||
}else{
|
||||
delete haha;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
inline bool ReactionConfig::LoadReactionConfig(TMacro * macro){
|
||||
|
||||
if( macro == NULL ) return false;
|
||||
|
||||
int recoilFlag = 0;
|
||||
int recoilLine = 0;
|
||||
|
||||
int numLine = macro->GetListOfLines()->GetSize();
|
||||
|
||||
for( int i = 0; i < numLine; i ++){
|
||||
|
||||
std::string line = macro->GetListOfLines()->At(i)->GetName();
|
||||
if( AnalysisLib::isEmptyOrSpaces(line) ) continue;
|
||||
|
||||
std::vector<std::string> str =AnalysisLib::SplitStr(line, " ");
|
||||
// printf("%d |%s|%d|%d\n", i, str[0].c_str(), recoilFlag, recoilLine);
|
||||
|
||||
if( str[0].find("####") != std::string::npos ) break;
|
||||
if( str[0].find("#---") != std::string::npos ) continue;
|
||||
if( str[0].find("#===") != std::string::npos ) {
|
||||
recoilFlag ++;
|
||||
recoilLine = 0;
|
||||
recoil.push_back(Recoil());
|
||||
exList.push_back(ExcitedEnergies());
|
||||
continue;
|
||||
}
|
||||
|
||||
if( recoilFlag == 0 ){
|
||||
if( recoilLine == 0 ) {
|
||||
beam.SetIsoByName(str[0]);
|
||||
beamA = beam.A;
|
||||
beamZ = beam.Z;
|
||||
}
|
||||
if( recoilLine == 1 ) beamEx = atoi(str[0].c_str());
|
||||
if( recoilLine == 2 ) beamEnergy = atof(str[0].c_str());
|
||||
if( recoilLine == 3 ) beamEnergySigma = atof(str[0].c_str());
|
||||
if( recoilLine == 4 ) beamTheta = atof(str[0].c_str());
|
||||
if( recoilLine == 5 ) beamThetaSigma = atof(str[0].c_str());
|
||||
if( recoilLine == 6 ) beamX = atof(str[0].c_str());
|
||||
if( recoilLine == 7 ) beamY = atof(str[0].c_str());
|
||||
|
||||
if( recoilLine == 8 ) {
|
||||
target.SetIsoByName(str[0]);
|
||||
targetA = target.A;
|
||||
targetZ = target.Z;
|
||||
}
|
||||
if( recoilLine == 9 ) isTargetScattering = str[0].compare("true") == 0 ? true: false;
|
||||
if( recoilLine == 10 ) targetDensity = atof(str[0].c_str());
|
||||
if( recoilLine == 11 ) targetThickness = atof(str[0].c_str());
|
||||
if( recoilLine == 12 ) beamStoppingPowerFile = str[0];
|
||||
|
||||
if( recoilLine == 13 ) numEvents = atoi(str[0].c_str());
|
||||
if( recoilLine == 14 ) isRedo = str[0].compare("true" ) == 0 ? true : false;
|
||||
}
|
||||
|
||||
if( recoilFlag > 0 ){
|
||||
|
||||
unsigned ID = recoilFlag - 1;
|
||||
if( recoilLine == 0 ) {
|
||||
recoil[ID].light.SetIsoByName(str[0]);
|
||||
recoil[ID].lightA = recoil[ID].light.A;
|
||||
recoil[ID].lightZ = recoil[ID].light.Z;
|
||||
}
|
||||
if( recoilLine == 1 ) recoil[ID].lightStoppingPowerFile = str[0];
|
||||
if( recoilLine == 2 ) recoil[ID].heavyStoppingPowerFile = str[0];
|
||||
if( recoilLine == 3 ) recoil[ID].isDecay = str[0].compare("true") == 0 ? true : false;
|
||||
if( recoilLine == 4 ) recoil[ID].decayA = atoi(str[0].c_str());
|
||||
if( recoilLine == 5 ) recoil[ID].decayZ = atoi(str[0].c_str());
|
||||
|
||||
if( recoilLine > 5 && str.size() == 4) {
|
||||
if( str[0].find('#') != std::string::npos) continue;
|
||||
if( str[0] == "IAEA"){
|
||||
|
||||
recoil[ID].heavyA = beamA + targetA - recoil[ID].lightA;
|
||||
recoil[ID].heavyZ = beamZ + targetZ - recoil[ID].lightZ;
|
||||
printf(">>>>>>>>>>>>> Retrieving Ex data from IAEA website....\n");
|
||||
std::string scriptPath = "../WebSimHelper/getEx.py " + std::to_string(recoil[ID].heavyA) + " " + std::to_string(recoil[ID].heavyZ) + " " + str[2];
|
||||
std::vector<std::string> output = AnalysisLib::executePythonScript(scriptPath);
|
||||
|
||||
if( output.size() > 1 ){
|
||||
for( size_t dudu = 1 ; dudu < output.size(); dudu ++ ){
|
||||
printf("%s", output[dudu].c_str());
|
||||
std::vector<std::string> dondon = AnalysisLib::SplitStr(output[dudu], " ");
|
||||
|
||||
if( str[1].find("all") == std::string::npos){ // only comfirm states
|
||||
if(dondon[2].find(')') != std::string::npos ) continue;
|
||||
if(dondon[2].find('N') != std::string::npos ) continue;
|
||||
// printf("kdlsakdas ---- %s\n", str[1].c_str());
|
||||
|
||||
if(str[1] == "+" && dondon[2].find('+') != std::string::npos ){
|
||||
// printf(" only comfim + states\n");
|
||||
exList[ID].Add( atoi(dondon[1].c_str()), 1.0, 1.0, atoi(str[3].c_str()));
|
||||
}
|
||||
if(str[1] == "-" && dondon[2].find('-') != std::string::npos ){
|
||||
// printf(" only comfim - states\n");
|
||||
exList[ID].Add( atoi(dondon[1].c_str()), 1.0, 1.0, atoi(str[3].c_str()));
|
||||
}
|
||||
if( str[1] == "known" ){
|
||||
// printf(" All comfim state\n");
|
||||
exList[ID].Add( atoi(dondon[1].c_str()), 1.0, 1.0, atoi(str[3].c_str()));
|
||||
}
|
||||
|
||||
}else{
|
||||
if(str[1] == "+all" && dondon[2].find('+') != std::string::npos ){
|
||||
// printf(" All state : %s\n", str[1].c_str());
|
||||
exList[ID].Add( atoi(dondon[1].c_str()), 1.0, 1.0, atoi(str[3].c_str()));
|
||||
}
|
||||
if(str[1] == "-all" && dondon[2].find('-') != std::string::npos ){
|
||||
// printf(" All state : %s\n", str[1].c_str());
|
||||
exList[ID].Add( atoi(dondon[1].c_str()), 1.0, 1.0, atoi(str[3].c_str()));
|
||||
}
|
||||
if( str[1] == "all" ){
|
||||
// printf(" All state \n");
|
||||
exList[ID].Add( atoi(dondon[1].c_str()), 1.0, 1.0, atoi(str[3].c_str()));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}else{
|
||||
printf(" No states found from IAEA database, assume ground state.");
|
||||
exList[ID].Add( 0, 1.0, 1.0, 0.01);
|
||||
}
|
||||
}else{
|
||||
exList[ID].Add( atoi(str[0].c_str()), atoi(str[1].c_str()), atoi(str[2].c_str()), atoi(str[3].c_str()));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
recoilLine ++;
|
||||
|
||||
}
|
||||
|
||||
for( size_t i = 0; i < recoil.size(); i++){
|
||||
recoil[i].heavyA = beamA + targetA - recoil[i].lightA;
|
||||
recoil[i].heavyZ = beamZ + targetZ - recoil[i].lightZ;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
inline void ReactionConfig::Print(int ID, bool withEx) const{
|
||||
|
||||
printf("#####################################################\n");
|
||||
|
||||
printf("number of Simulation Events : %d \n", numEvents);
|
||||
printf(" is Redo until hit array : %s \n", isRedo ? "Yes" : "No");
|
||||
|
||||
printf("================================= Beam\n");
|
||||
printf(" beam : A = %3d, Z = %2d, Ex = %.2f MeV\n", beamA, beamZ, beamEx);
|
||||
printf(" beam Energy : %.2f +- %.2f MeV/u, dE/E = %5.2f %%\n", beamEnergy, beamEnergySigma, beamEnergySigma/beamEnergy);
|
||||
printf(" Angle : %.2f +- %.2f mrad\n", beamTheta, beamThetaSigma);
|
||||
printf(" offset : (x,y) = (%.2f, %.2f) mmm \n", beamX, beamY);
|
||||
|
||||
printf("================================= Target\n");
|
||||
printf(" target : A = %3d, Z = %2d \n", targetA, targetZ);
|
||||
printf(" enable scattering : %s \n", isTargetScattering ? "Yes" : "No");
|
||||
if(isTargetScattering){
|
||||
printf(" target density : %.f g/cm3\n", targetDensity);
|
||||
printf(" thickness : %.f cm\n", targetThickness);
|
||||
printf(" beam stopping file : %s \n", beamStoppingPowerFile.c_str());
|
||||
}
|
||||
|
||||
printf("================================= Number of recoil reactions : %zu\n", recoil.size());
|
||||
for( int i = 0; i < (int)recoil.size(); i ++ ){
|
||||
if( ID == i || ID < 0 ){
|
||||
printf("------------------------------------------ Recoil-%d\n", i);
|
||||
recoil[i].Print();
|
||||
if( withEx ) exList[i].Print();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
printf("#####################################################\n");
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,158 +0,0 @@
|
|||
#ifndef ReactionParameters_H
|
||||
#define ReactionParameters_H
|
||||
|
||||
#include "ClassDetGeo.h"
|
||||
|
||||
class ReactionParas{
|
||||
|
||||
public:
|
||||
ReactionParas();
|
||||
|
||||
double Et; // total energy in CM frame
|
||||
double beta; // Lorentz beta from Lab to CM
|
||||
double gamma; // Lorentz gamma from Lab to CM
|
||||
double alpha; // E-Z slope / beta
|
||||
double G; //The G-coefficient....
|
||||
double massB; // heavy mass
|
||||
double q; // charge of light particle
|
||||
double mass; //light mass
|
||||
bool hasReactionPara;
|
||||
|
||||
double detPrepDist;
|
||||
|
||||
void LoadReactionParas(bool verbose = false);
|
||||
std::pair<double, double> CalExTheta(double e, double z)
|
||||
|
||||
};
|
||||
|
||||
ReactionParas::ReactionParas(){
|
||||
|
||||
}
|
||||
|
||||
//~========================================= reaction parameters
|
||||
inline void ReactionParas::LoadReactionParas(bool verbose = false){
|
||||
|
||||
//check is the transfer.root is using the latest reactionConfig.txt
|
||||
//sicne reaction.dat is generated as a by-product of transfer.root
|
||||
//TFile * transfer = new TFile("transfer.root");
|
||||
//TString aaa1 = "";
|
||||
//TString aaa2 = "";
|
||||
//if( transfer->IsOpen() ){
|
||||
// TMacro * reactionConfig = (TMacro *) transfer->FindObjectAny("reactionConfig");
|
||||
// TMacro presentReactionConfig ("reactionConfig.txt");
|
||||
// aaa1 = ((TMD5*) reactionConfig->Checksum())->AsString();
|
||||
// aaa2 = ((TMD5*) presentReactionConfig.Checksum())->AsString();
|
||||
//}
|
||||
//printf("%s\n", aaa1.Data());
|
||||
//printf("%s\n", aaa2.Data());
|
||||
|
||||
//if( aaa1 != aaa2 ) {
|
||||
// printf("########################## recalculate transfer.root \n");
|
||||
// system("../Cleopatra/Transfer");
|
||||
// printf("########################## transfer.root updated\n");
|
||||
//}
|
||||
|
||||
std::string fileName;
|
||||
|
||||
detPrepDist = Array::detPerpDist;
|
||||
|
||||
printf(" loading reaction parameters");
|
||||
std::ifstream file;
|
||||
file.open(fileName.c_str());
|
||||
hasReactionPara = false;
|
||||
if( file.is_open() ){
|
||||
std::string x;
|
||||
int i = 0;
|
||||
while( file >> x ){
|
||||
if( x.substr(0,2) == "//" ) continue;
|
||||
if( i == 0 ) mass = atof(x.c_str());
|
||||
if( i == 1 ) q = atof(x.c_str());
|
||||
if( i == 2 ) beta = atof(x.c_str());
|
||||
if( i == 3 ) Et = atof(x.c_str());
|
||||
if( i == 4 ) massB = atof(x.c_str());
|
||||
i = i + 1;
|
||||
}
|
||||
printf("........ done.\n");
|
||||
|
||||
hasReactionPara = true;
|
||||
alpha = 299.792458 * abs(detGeo.Bfield) * q / TMath::TwoPi()/1000.; //MeV/mm
|
||||
gamma = 1./TMath::Sqrt(1-beta * beta);
|
||||
G = alpha * gamma * beta * detPrepDist ;
|
||||
|
||||
if( verbose ){
|
||||
printf("\tmass-b : %f MeV/c2 \n", mass);
|
||||
printf("\tcharge-b : %f \n", q);
|
||||
printf("\tE-total : %f MeV \n", Et);
|
||||
printf("\tmass-B : %f MeV/c2 \n", massB);
|
||||
printf("\tbeta : %f \n", beta);
|
||||
printf("\tB-field : %f T \n", detGeo.Bfield);
|
||||
printf("\tslope : %f MeV/mm \n", alpha * beta);
|
||||
printf("\tdet radius: %f mm \n", detPrepDist);
|
||||
printf("\tG-coeff : %f MeV \n", G);
|
||||
printf("=====================================================\n");
|
||||
}
|
||||
|
||||
}else{
|
||||
printf("........ fail.\n");
|
||||
}
|
||||
file.close();
|
||||
|
||||
}
|
||||
|
||||
inline std::pair<double, double> ReactionParas::CalExTheta(double e, double z){
|
||||
|
||||
ReactionParas * reactParas = nullptr;
|
||||
|
||||
if( detGeo.array1.zMin <= z && z <= detGeo.array1.zMax ){
|
||||
reactParas = &reactParas1;
|
||||
if( !hasReactionPara) return {TMath::QuietNaN(), TMath::QuietNaN()};
|
||||
}
|
||||
|
||||
if( detGeo.array2.zMin <= z && z <= detGeo.array2.zMax ){
|
||||
reactParas = &reactParas2;
|
||||
if( !hasReactionPara) return {TMath::QuietNaN(), TMath::QuietNaN()};
|
||||
}
|
||||
|
||||
double Ex = TMath::QuietNaN();
|
||||
double thetaCM = TMath::QuietNaN();
|
||||
|
||||
double y = e + mass; // to give the KE + mass of proton;
|
||||
double Z = alpha * gamma * beta * z;
|
||||
double H = TMath::Sqrt(TMath::Power(gamma * beta,2) * (y*y - mass * mass) ) ;
|
||||
|
||||
if( TMath::Abs(Z) < H ) {
|
||||
///using Newton's method to solve 0 == H * sin(phi) - G * tan(phi) - Z = f(phi)
|
||||
double tolerrence = 0.001;
|
||||
double phi = 0; ///initial phi = 0 -> ensure the solution has f'(phi) > 0
|
||||
double nPhi = 0; /// new phi
|
||||
|
||||
int iter = 0;
|
||||
do{
|
||||
phi = nPhi;
|
||||
nPhi = phi - (H * TMath::Sin(phi) - G * TMath::Tan(phi) - Z) / (H * TMath::Cos(phi) - G /TMath::Power( TMath::Cos(phi), 2));
|
||||
iter ++;
|
||||
if( iter > 10 || TMath::Abs(nPhi) > TMath::PiOver2()) break;
|
||||
}while( TMath::Abs(phi - nPhi ) > tolerrence);
|
||||
phi = nPhi;
|
||||
|
||||
/// check f'(phi) > 0
|
||||
double Df = H * TMath::Cos(phi) - G / TMath::Power( TMath::Cos(phi),2);
|
||||
if( Df > 0 && TMath::Abs(phi) < TMath::PiOver2() ){
|
||||
double K = H * TMath::Sin(phi);
|
||||
double x = TMath::ACos( mass / ( y * gamma - K));
|
||||
double momt = mass * TMath::Tan(x); /// momentum of particel b or B in CM frame
|
||||
double EB = TMath::Sqrt(mass * mass + Et * Et - 2 * Et * TMath::Sqrt(momt*momt + mass * mass));
|
||||
Ex = EB - massB;
|
||||
|
||||
double hahaha1 = gamma * TMath::Sqrt(mass * mass + momt * momt) - y;
|
||||
double hahaha2 = gamma * beta * momt;
|
||||
thetaCM = TMath::ACos(hahaha1/hahaha2) * TMath::RadToDeg();
|
||||
|
||||
}
|
||||
}
|
||||
return std::make_pair(Ex, thetaCM);
|
||||
|
||||
}
|
||||
|
||||
|
||||
#endif
|
|
@ -1 +0,0 @@
|
|||
/home/ryan/SOLARIS_DAQ/Aux/EventBuilder
|
|
@ -1,90 +0,0 @@
|
|||
#!/bin/bash -l
|
||||
|
||||
##############################################
|
||||
#
|
||||
# This script define color and dataPath
|
||||
#
|
||||
##############################################
|
||||
|
||||
if [ ! -z $RED ]; then
|
||||
echo "Process_BasicConfig already loaded."
|
||||
return
|
||||
fi
|
||||
|
||||
RED='\033[1;31m'
|
||||
YELLOW='\033[1;33m'
|
||||
ORANGE='\033[0;33m'
|
||||
GREEN='\033[1;32m'
|
||||
BLUE='\033[0;34m'
|
||||
CYAN='\033[0;36m'
|
||||
NC='\033[0m' #no color
|
||||
LRED='\033[1;91m'
|
||||
|
||||
echo -e "${RED}##################### Loading Process_BasicConfig.sh ${NC}"
|
||||
|
||||
############## need to distingish mac and daq
|
||||
Arch="$(uname -s)"
|
||||
PCName="$(hostname)"
|
||||
PCID=-1 #if PCID == 1 (DAQ), 2 (MAC), 3 (test station), -1(OTHER)
|
||||
|
||||
#------ Set up data folder, check disk space
|
||||
echo -e "${YELLOW}##################### Check computer name and arch. ${NC}"
|
||||
echo "PC name : ${PCName}"
|
||||
echo "Archetech: ${Arch}"
|
||||
|
||||
|
||||
rawDataPath=${SOLARISANADIR}/data_raw/
|
||||
rootDataPath=${SOLARISANADIR}/root_data/
|
||||
|
||||
echo "Raw Data Path : "${rawDataPath}
|
||||
echo "Root Data Path : "${rootDataPath}
|
||||
|
||||
|
||||
if [ ${Arch} == "Linux" ] && [ ${PCName} == "solaris-daq" ]; then
|
||||
|
||||
PCID=1
|
||||
|
||||
# pathsSetting=${HOME}/SOLARIS_DAQ/programSettings.txt
|
||||
# if [ -e ${pathsSetting} ]; then
|
||||
# #echo "Found DAQ programSettings.txt for paths settings"
|
||||
|
||||
# analysisPath=$(cat ${pathsSetting} | head -n 2 | tail -n 1)
|
||||
|
||||
# if [ ! "${analysisPath}" = "$SOLARISANADIR" ]; then
|
||||
# echo "The analysisPath from ${analysisPath} is different from present folder $SOLARISANADIR. Abort."
|
||||
# exit
|
||||
# fi
|
||||
|
||||
# rawDataPathParent=$(cat ${pathsSetting} | head -n 3 | tail -n 1)
|
||||
# rootDataPathParent=$(cat ${pathsSetting} | head -n 4 | tail -n 1)
|
||||
|
||||
# databaseIP=$(cat ${pathsSetting} | head -n 6 | tail -n 1)
|
||||
# databaseName=$(cat ${pathsSetting} | head -n 7 | tail -n 1)
|
||||
|
||||
# #echo ${rawDataPathParent}
|
||||
# #echo ${rootDataPathParent}
|
||||
# #echo ${databaseIP}
|
||||
# #echo ${databaseName}
|
||||
|
||||
# else
|
||||
|
||||
# echo "${RED} Cannot found DAQ programSettings.txt for path settings ${NC}"
|
||||
# echo "Seek Ryan for help"
|
||||
# exit
|
||||
|
||||
# fi
|
||||
|
||||
fi
|
||||
|
||||
if [ ${Arch} == "Darwin" ] && [ ${PCName} == "SOLARISs-Mac-Studio.local" ]; then
|
||||
PCID=2
|
||||
# rawDataPathParent=${HOME}/experimentalData/
|
||||
# rootDataPathParent=${HOME}/experimentalData/
|
||||
fi
|
||||
|
||||
if [ ${Arch} == "Linux" ] && [ ${PCName} == "solarisdaq" ]; then
|
||||
PCID=3
|
||||
# rawDataPathParent=${SOLARISANADIR}/data_raw/
|
||||
# rootDataPathParent=${SOLARISANADIR}/root_data/
|
||||
fi
|
||||
|
654
Cleopatra/Check_Simulation.C
Normal file
|
@ -0,0 +1,654 @@
|
|||
#include <TFile.h>
|
||||
#include <TTree.h>
|
||||
#include <TCanvas.h>
|
||||
#include <TROOT.h>
|
||||
#include <TObjArray.h>
|
||||
#include <TStyle.h>
|
||||
#include <TH2F.h>
|
||||
#include <TH1F.h>
|
||||
#include <TF1.h>
|
||||
#include <TArc.h>
|
||||
#include <TMath.h>
|
||||
#include <TLine.h>
|
||||
#include <TSpectrum.h>
|
||||
#include <TGraph.h>
|
||||
#include <TLegend.h>
|
||||
#include <TLatex.h>
|
||||
#include <TMacro.h>
|
||||
#include <TObjArray.h>
|
||||
#include <fstream>
|
||||
#include <TCutG.h>
|
||||
#include "../armory/AnalysisLib.h"
|
||||
#include "../Cleopatra/Isotope.h"
|
||||
|
||||
double * FindRange(TString branch, TString gate, TTree * tree, double output[2]);
|
||||
double ExtractNumber(int index, TMacro * macro);
|
||||
TString ExtractString(int index, TMacro * macro);
|
||||
vector<TString> StringToVector(TString str);
|
||||
vector<int> intConvertor(vector<TString> arr);
|
||||
vector<double> doubleConvertor(vector<TString> arr);
|
||||
|
||||
enum plotID { pEZ, /// 0
|
||||
pRecoilXY, /// 1
|
||||
pRecoilXY1, /// 2
|
||||
pRecoilXY2, /// 3
|
||||
pRecoilRZ, /// 4
|
||||
pRecoilRTR, /// 5
|
||||
pTDiffZ, /// 6
|
||||
pThetaCM, /// 7
|
||||
pThetaCM_Z, /// 8
|
||||
pExCal, /// 9
|
||||
pRecoilRThetaCM, /// 10
|
||||
pArrayXY, /// 11
|
||||
pInfo, /// 12
|
||||
pHitID, /// 13
|
||||
pElum1XY, /// 14
|
||||
pEElum1R, /// 15
|
||||
pElum1RThetaCM, /// 16
|
||||
pEmpty }; /// 17
|
||||
plotID StringToPlotID(TString str);
|
||||
void Check_Simulation(TString filename = "transfer1.root",
|
||||
TString configFile = "../working/Check_Simulation_Config.txt",
|
||||
Int_t padSize = 500,
|
||||
bool outputCanvas = false){
|
||||
|
||||
printf("=========================== Check_Simulation.C\n");
|
||||
|
||||
TMacro * config = new TMacro(configFile);
|
||||
int numLine = config->GetListOfLines()->GetSize();
|
||||
int startLineNum = 0;
|
||||
for( int i = 0; i < numLine ; i++){
|
||||
TString haha = config->GetListOfLines()->At(i)->GetName();
|
||||
haha.Remove(4);
|
||||
if( haha != "////" ) {
|
||||
startLineNum = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
TString gate = ExtractString(startLineNum+1, config);
|
||||
double elumRange = ExtractNumber(startLineNum+2, config);
|
||||
vector<double> thetaCMRange = doubleConvertor( StringToVector( ExtractString(startLineNum+3,config) ));
|
||||
bool shownKELines = (ExtractString(startLineNum+4, config).Remove(4) == "true" ? true : false);
|
||||
bool isOverRideEx = (ExtractString(startLineNum+5, config).Remove(4) == "true" ? true : false);
|
||||
vector<double> oExRange = doubleConvertor( StringToVector ( ExtractString(startLineNum+6, config )));
|
||||
|
||||
printf("%s \n", gate.Data());
|
||||
|
||||
|
||||
///==== config Canvas
|
||||
vector<TString> plotConfig = StringToVector( ExtractString(startLineNum, config));
|
||||
vector<plotID> canvas;
|
||||
int colCount = 0;
|
||||
int colCount_new = 0;
|
||||
int rowCount = 1;
|
||||
for( int i = 0; i < (int) plotConfig.size(); i++){
|
||||
if( plotConfig[i] == "break" ) {
|
||||
rowCount ++;
|
||||
if( colCount_new > colCount ) colCount = colCount_new;
|
||||
colCount_new = 0;
|
||||
continue;
|
||||
}
|
||||
canvas.push_back( StringToPlotID(plotConfig[i]));
|
||||
colCount_new ++;
|
||||
}
|
||||
|
||||
if( colCount == 0 ) colCount = colCount_new;
|
||||
///printf("plot row: %d, col: %d \n", rowCount, colCount);
|
||||
|
||||
vector<int> Div = {colCount, rowCount};
|
||||
|
||||
|
||||
TFile * file = new TFile(filename, "read");
|
||||
TTree * tree = (TTree*) file->Get("tree");
|
||||
|
||||
TObjArray * fxList = (TObjArray *) file->FindObjectAny("fxList");
|
||||
TObjArray * txList = (TObjArray *) file->FindObjectAny("txList");
|
||||
|
||||
//================== reactionConfig
|
||||
TMacro * reactionConfigTxt = (TMacro *) file->FindObjectAny("reactionConfig");
|
||||
TString Reaction=reactionConfigTxt->GetName();
|
||||
|
||||
AnalysisLib::ReactionConfig reactionConfig = AnalysisLib::LoadReactionConfig(reactionConfigTxt);
|
||||
|
||||
int nEvent = reactionConfig.numEvents;
|
||||
printf("number of events generated : %d \n", nEvent);
|
||||
|
||||
double xBeam = reactionConfig.beamX;
|
||||
double yBeam = reactionConfig.beamY;
|
||||
printf(" beam position : (%5.2f, %5.2f) mm \n", xBeam, yBeam);
|
||||
|
||||
gStyle->SetOptStat("");
|
||||
gStyle->SetStatY(0.9);
|
||||
gStyle->SetStatX(0.9);
|
||||
gStyle->SetStatW(0.4);
|
||||
gStyle->SetStatH(0.2);
|
||||
gStyle->SetLabelSize(0.05, "XY");
|
||||
gStyle->SetTitleFontSize(0.1);
|
||||
|
||||
double eRange[2] = {0, 10};
|
||||
double zRange[3] = {400, -1000, 1000}; /// zRange[0] = nBin
|
||||
double recoilERange[2];
|
||||
vector<double> exList;
|
||||
double ExRange[2];
|
||||
|
||||
//================================== detetcor Geometry
|
||||
printf("=================================\n");
|
||||
printf(" loading detector Geometry.\n");
|
||||
TMacro * detGeoTxt = (TMacro *) file->FindObjectAny("detGeo");
|
||||
|
||||
AnalysisLib::DetGeo detGeo = AnalysisLib::LoadDetectorGeo(detGeoTxt);
|
||||
|
||||
AnalysisLib::Array array;
|
||||
if( detGeo.use2ndArray){
|
||||
array = detGeo.array2;
|
||||
}else{
|
||||
array = detGeo.array1;
|
||||
}
|
||||
|
||||
double field = detGeo.Bfield;
|
||||
TString fdmsg = field > 0 ? "out of plan" : "into plan";
|
||||
TString msg2;
|
||||
msg2.Form("field = %.2f T, %s", field, fdmsg.Data());
|
||||
|
||||
double prepDist = array.detPerpDist;
|
||||
double length = array.detLength;
|
||||
|
||||
double posRecoil = detGeo.recoilPos;
|
||||
double rhoRecoilIn = detGeo.recoilInnerRadius;
|
||||
double rhoRecoilOut = detGeo.recoilOuterRadius;
|
||||
|
||||
double posRecoil1 = detGeo.recoilPos1;
|
||||
double posRecoil2 = detGeo.recoilPos2;
|
||||
|
||||
vector<double> pos = array.detPos;
|
||||
|
||||
float firstPos = array.firstPos;
|
||||
int rDet = array.nDet;
|
||||
int cDet = array.mDet;
|
||||
|
||||
double elum1 = detGeo.elumPos1;
|
||||
|
||||
printf("number of row-Det : %d \n", rDet);
|
||||
printf("number of col-Det : %d \n", cDet);
|
||||
|
||||
for(int i = 0; i < rDet ; i++){
|
||||
if( firstPos > 0 ){
|
||||
printf("%d, %10.2f mm - %10.2f mm \n", i, pos[i], pos[i] + length);
|
||||
}else{
|
||||
printf("%d, %10.2f mm - %10.2f mm \n", i, pos[i] - length , pos[i]);
|
||||
}
|
||||
}
|
||||
|
||||
printf("=================================\n");
|
||||
|
||||
int numDet = rDet * cDet;
|
||||
|
||||
zRange[1] = array.zMin - 50;
|
||||
zRange[2] = array.zMax + 50;
|
||||
|
||||
printf(" zRange : %f - %f \n", zRange[1], zRange[2]);
|
||||
printf("=================================\n");
|
||||
|
||||
//========================================= Ex List;
|
||||
printf(" loading Ex list\n");
|
||||
|
||||
TMacro * exListMacro = (TMacro *) file->FindObjectAny("ExList");
|
||||
int numEx = exListMacro->GetListOfLines()->GetSize() - 1 ;
|
||||
for(int i = 1; i <= numEx ; i++){
|
||||
string temp = exListMacro->GetListOfLines()->At(i)->GetName();
|
||||
if( temp[0] == '#' ) break;
|
||||
if( temp[0] == '/' ) continue;
|
||||
vector<string> tempStr = AnalysisLib::SplitStr(temp, " ");
|
||||
printf("%d | %s \n", i, tempStr[0].c_str());
|
||||
exList.push_back(atof(tempStr[0].c_str()));
|
||||
}
|
||||
|
||||
double exSpan = exList.back() - exList[0];
|
||||
|
||||
const int nExID = exList.size();
|
||||
printf("========= number of excited states : %d \n", nExID);
|
||||
|
||||
ExRange[0] = exList[0] - exSpan * 0.2;
|
||||
ExRange[1] = exList.back() + exSpan * 0.2;
|
||||
if( isOverRideEx ) {
|
||||
ExRange[0] = oExRange[0];
|
||||
ExRange[1] = oExRange[1];
|
||||
}
|
||||
|
||||
printf("=================================\n");
|
||||
|
||||
//========================================= reaction parameters
|
||||
|
||||
printf(" loading reaction parameters \n");
|
||||
TMacro * reactionData = (TMacro *) file->FindObjectAny("reactionData");
|
||||
|
||||
double mass = ExtractNumber(0, reactionData);
|
||||
double q = ExtractNumber(1, reactionData);
|
||||
double beta = ExtractNumber(2, reactionData);
|
||||
double Et = ExtractNumber(3, reactionData);
|
||||
double massB = ExtractNumber(4, reactionData);
|
||||
double alpha = ExtractNumber(5, reactionData);
|
||||
|
||||
double gamm = 1./TMath::Sqrt(1-beta*beta);
|
||||
double slope = alpha * beta;
|
||||
printf("\tmass-b : %f MeV/c2 \n", mass);
|
||||
printf("\tcharge-b : %f \n", q);
|
||||
printf("\tE-total : %f MeV \n", Et);
|
||||
printf("\tmass-B : %f MeV/c2 \n", massB);
|
||||
printf("\tbeta : %f \n", beta);
|
||||
printf("\tslope : %f MeV/mm \n", slope);
|
||||
printf("=================================\n");
|
||||
|
||||
//=================================== calculate Ranges
|
||||
|
||||
//eRange by zRange and exList
|
||||
double QQ = (Et*Et + mass*mass - (massB-exList[0])*(massB-exList[0]))/2/Et;
|
||||
double intercept = QQ/gamm - mass;
|
||||
eRange[1] = intercept + zRange[2] * slope;
|
||||
///printf("intercept of 0 MeV : %f MeV \n", intercept);
|
||||
///printf("eRange 0 MeV : %f MeV \n", eRange[1]);
|
||||
|
||||
//thetaCMRange
|
||||
///double momentum = sqrt(( Et*Et - pow(mass + massB - exList[0],2)) * ( Et*Et - pow(mass - massB + exList[0],2)))/2/Et;
|
||||
///double thetaMax = acos( (beta * QQ- alpha / gamm * zRange[2])/momentum) * TMath::RadToDeg();
|
||||
///thetaCMRange[1] = (int) TMath::Ceil(thetaMax/10.)*10;
|
||||
///printf(" momentum : %f \n", momentum);
|
||||
///printf(" thetaCM Max : %f \n", thetaMax);
|
||||
///printf(" thetaCM Range : %d \n", thetaCMRange[1]);
|
||||
|
||||
//===================================================
|
||||
printf("============================== Gate\n");
|
||||
printf("gate : %s\n", gate.Data());
|
||||
printf("====================================\n");
|
||||
|
||||
Int_t size[2] = {padSize,padSize}; ///x,y, single Canvas size
|
||||
TCanvas * cCheck = new TCanvas("cCheck", "Check For Simulation", 0, 0, size[0]*Div[0], size[1]*Div[1]);
|
||||
if(cCheck->GetShowEditor() )cCheck->ToggleEditor();
|
||||
if(cCheck->GetShowToolBar() )cCheck->ToggleToolBar();
|
||||
cCheck->Divide(Div[0],Div[1]);
|
||||
|
||||
for( int i = 1; i <= Div[0]*Div[1] ; i++){
|
||||
cCheck->cd(i);
|
||||
cCheck->cd(i)->SetGrid();
|
||||
if( canvas[i-1] == pThetaCM ) {
|
||||
cCheck->cd(i)->SetGrid(0,0);
|
||||
cCheck->cd(i)->SetLogy();
|
||||
}
|
||||
if( canvas[i-1] == pHitID ){
|
||||
cCheck->cd(i)->SetLogy();
|
||||
}
|
||||
plotID pID = canvas[i-1];
|
||||
///########################################
|
||||
if( pID == pEZ){
|
||||
TH2F * hez = new TH2F("hez", Form("e-z [gated] @ %5.0f mm; z [mm]; e [MeV]", firstPos), zRange[0], zRange[1], zRange[2], 400, eRange[0], eRange[1]);
|
||||
tree->Draw("e:z>>hez", gate, "colz");
|
||||
if( shownKELines){
|
||||
for( int i = 0; i < nExID ; i++){
|
||||
fxList->At(i)->Draw("same");
|
||||
}
|
||||
}
|
||||
}
|
||||
if( pID == pRecoilXY ){
|
||||
TH2F * hRecoilXY = new TH2F("hRecoilXY", Form("RecoilXY [gated] @ %4.0f mm; X [mm]; Y [mm]", posRecoil ), 400, -rhoRecoilOut, rhoRecoilOut, 400,-rhoRecoilOut, rhoRecoilOut);
|
||||
tree->Draw("yRecoil:xRecoil>>hRecoilXY", gate, "colz");
|
||||
TArc * detArc1 = new TArc(0,0, rhoRecoilOut);
|
||||
detArc1->SetLineColor(kBlue-8);
|
||||
detArc1->SetFillStyle(0);
|
||||
detArc1->Draw("same");
|
||||
TArc * detArc2 = new TArc(0,0, rhoRecoilIn);
|
||||
detArc2->SetLineColor(kBlue-8);
|
||||
detArc2->SetFillStyle(0);
|
||||
detArc2->Draw("same");
|
||||
|
||||
if( xBeam != 0. || yBeam != 0. ){
|
||||
TArc * arc = new TArc(xBeam, yBeam, 1);
|
||||
arc->SetLineColor(2);
|
||||
detArc1->SetFillStyle(0);
|
||||
arc->Draw("same");
|
||||
}
|
||||
}
|
||||
if( pID == pRecoilXY1 ){
|
||||
TH2F * hRecoilXY1 = new TH2F("hRecoilXY1", Form("RecoilXY-1 [gated] @ %4.0f mm; X [mm]; Y [mm]", posRecoil1 ), 400, -rhoRecoilOut, rhoRecoilOut, 400,-rhoRecoilOut, rhoRecoilOut);
|
||||
tree->Draw("yRecoil1:xRecoil1>>hRecoilXY1", gate, "colz");
|
||||
}
|
||||
if( pID == pRecoilXY2 ){
|
||||
TH2F * hRecoilXY2 = new TH2F("hRecoilXY2", Form("RecoilXY-2 [gated] @ %4.0f mm; X [mm]; Y [mm]", posRecoil2 ), 400, -rhoRecoilOut, rhoRecoilOut, 400,-rhoRecoilOut, rhoRecoilOut);
|
||||
tree->Draw("yRecoil2:xRecoil2>>hRecoilXY2", gate, "colz");
|
||||
}
|
||||
if( pID == pRecoilRZ ){
|
||||
TH2F * hRecoilRZ = new TH2F("hRecoilRZ", "RecoilR - Z [gated]; z [mm]; RecoilR [mm]", zRange[0], zRange[1], zRange[2], 400,0, rhoRecoilOut);
|
||||
tree->Draw("rhoRecoil:z>>hRecoilRZ", gate, "colz");
|
||||
}
|
||||
if( pID == pRecoilRTR ){
|
||||
FindRange("TB", gate, tree, recoilERange);
|
||||
TH2F * hRecoilRTR = new TH2F("hRecoilRTR", "RecoilR - recoilE [gated]; recoil Energy [MeV]; RecoilR [mm]", 500, recoilERange[0], recoilERange[1], 500, 0, rhoRecoilOut);
|
||||
tree->Draw("rhoRecoil:TB>>hRecoilRTR", gate, "colz");
|
||||
}
|
||||
if( pID == pTDiffZ ){
|
||||
double tDiffRange [2];
|
||||
FindRange("t-tB", gate, tree, tDiffRange);
|
||||
TH2F * hTDiffZ = new TH2F("hTDiffZ", "time(Array) - time(Recoil) vs Z [gated]; z [mm]; time diff [ns]", zRange[0], zRange[1], zRange[2], 500, tDiffRange[0], tDiffRange[1]);
|
||||
tree->Draw("t - tB : z >> hTDiffZ", gate, "colz");
|
||||
}
|
||||
if( pID == pThetaCM ){
|
||||
TH1F * hThetaCM[nExID];
|
||||
TLegend * legend = new TLegend(0.8,0.2,0.99,0.8);
|
||||
double maxCount = 0;
|
||||
int startID = 0; // set the start ExID
|
||||
for( int i = startID; i < nExID; i++){
|
||||
hThetaCM[i] = new TH1F(Form("hThetaCM%d", i), Form("thetaCM [gated] (ExID=%d); thetaCM [deg]; count", i), 200, thetaCMRange[0], thetaCMRange[1]);
|
||||
hThetaCM[i]->SetLineColor(i+1-startID);
|
||||
hThetaCM[i]->SetFillColor(i+1-startID);
|
||||
hThetaCM[i]->SetFillStyle(3000+i-startID);
|
||||
tree->Draw(Form("thetaCM>>hThetaCM%d", i), gate + Form("&& ExID==%d", i), "");
|
||||
legend->AddEntry(hThetaCM[i], Form("Ex=%5.1f MeV", exList[i]));
|
||||
double max = hThetaCM[i]->GetMaximum();
|
||||
if( max > maxCount ) maxCount = max;
|
||||
}
|
||||
|
||||
for( int i = startID; i < nExID; i++){
|
||||
hThetaCM[i]->GetYaxis()->SetRangeUser(1, maxCount * 1.2);
|
||||
if( i == startID ) {
|
||||
hThetaCM[i]->Draw();
|
||||
}else{
|
||||
hThetaCM[i]->Draw("same");
|
||||
}
|
||||
}
|
||||
legend->Draw();
|
||||
}
|
||||
if( pID == pThetaCM_Z ){
|
||||
TH2F *hThetaCM_Z = new TH2F("hThetaCM_Z","ThetaCM vs Z ; Z [mm]; thetaCM [deg]",zRange[0], zRange[1], zRange[2], 200, thetaCMRange[0], thetaCMRange[1]);
|
||||
tree->Draw("thetaCM:z>>hThetaCM_Z",gate,"col");
|
||||
if( shownKELines){
|
||||
for( int i = 0; i < nExID ; i++){
|
||||
txList->At(i)->Draw("same");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
if( pID == pExCal ){
|
||||
TH1F * hExCal = new TH1F("hExCal", Form("calculated Ex [gated]; Ex [MeV]; count / %.2f keV", (ExRange[1]-ExRange[0])/400.*1000), 400, ExRange[0], ExRange[1]);
|
||||
tree->Draw("ExCal>>hExCal", gate, "");
|
||||
Isotope hRecoil(reactionConfig.recoilHeavyA, reactionConfig.recoilHeavyZ);
|
||||
double Sn = hRecoil.CalSp(0,1);
|
||||
double Sp = hRecoil.CalSp(1,0);
|
||||
double Sa = hRecoil.CalSp2(4,2);
|
||||
double S2n = hRecoil.CalSp(0, 2);
|
||||
|
||||
printf("Heavy recoil: %s \n", hRecoil.Name.c_str());
|
||||
printf("Sn : %f MeV/u \n", Sn);
|
||||
printf("Sp : %f MeV/u \n", Sp);
|
||||
printf("Sa : %f MeV/u \n", Sa);
|
||||
printf("S2n : %f MeV/u \n", S2n);
|
||||
|
||||
double yMax = hExCal->GetMaximum();
|
||||
TLine * lineSn = new TLine(Sn, 0, Sn, yMax); lineSn->SetLineColor(2); lineSn->Draw("");
|
||||
TLine * lineSp = new TLine(Sp, 0, Sp, yMax); lineSp->SetLineColor(4); lineSp->Draw("same");
|
||||
TLine * lineSa = new TLine(Sa, 0, Sa, yMax); lineSa->SetLineColor(6); lineSa->Draw("same");
|
||||
TLine * lineS2n = new TLine(S2n, 0, S2n, yMax); lineS2n->SetLineColor(8); lineS2n->Draw("same");
|
||||
|
||||
TLatex * text = new TLatex();
|
||||
text->SetTextFont(82);
|
||||
text->SetTextSize(0.06);
|
||||
text->SetTextColor(2); text->DrawLatex(Sn, yMax*0.9, "S_{n}");
|
||||
text->SetTextColor(4); text->DrawLatex(Sp, yMax*0.9, "S_{p}");
|
||||
text->SetTextColor(6); text->DrawLatex(Sa, yMax*0.9, "S_{a}");
|
||||
text->SetTextColor(8); text->DrawLatex(S2n, yMax*0.9, "S_{2n}");
|
||||
|
||||
}
|
||||
if( pID == pRecoilRThetaCM ){
|
||||
TH2F * hRecoilRThetaCM = new TH2F("hRecoilRThetaCM", "RecoilR - thetaCM [gated]; thetaCM [deg]; RecoilR [mm]", 400, 0, 60, 400,0, rhoRecoilOut);
|
||||
tree->Draw("rhoRecoil:thetaCM>>hRecoilRThetaCM", gate, "colz");
|
||||
}
|
||||
if( pID == pArrayXY ){
|
||||
TH2F * hArrayXY = new TH2F("hArrayXY", "Array-XY [gated]; X [mm]; Y [mm]", 400, -prepDist*1.5, prepDist*1.5, 400, -prepDist*1.5, prepDist*1.5);
|
||||
tree->Draw("yArray:xArray>>hArrayXY", gate, "colz");
|
||||
}
|
||||
if( pID == pInfo ){
|
||||
TLatex text;
|
||||
text.SetNDC();
|
||||
text.SetTextFont(82);
|
||||
text.SetTextSize(0.06);
|
||||
text.SetTextColor(2);
|
||||
|
||||
text.DrawLatex(0., 0.9, Reaction);
|
||||
text.DrawLatex(0., 0.8, msg2);
|
||||
text.SetTextColor(1);
|
||||
text.DrawLatex(0., 0.7, "gate:");
|
||||
|
||||
text.SetTextColor(2);
|
||||
//check gate text length, if > 30, break by "&&"
|
||||
int ll = gate.Length();
|
||||
if( ll > 30 ) {
|
||||
vector<string> strList = AnalysisLib::SplitStr( (string) gate.Data(), "&&");
|
||||
for( int i = 0; i < strList.size(); i++){
|
||||
text.DrawLatex(0., 0.6 - 0.05*i, (TString) strList[i]);
|
||||
}
|
||||
}else{
|
||||
text.DrawLatex(0., 0.6, gate);
|
||||
}
|
||||
|
||||
if( xBeam != 0.0 || yBeam != 0.0 ){
|
||||
text.DrawLatex(0.0, 0.1, Form("Bema pos: (%4.1f, %4.1f) mm", xBeam, yBeam));
|
||||
}
|
||||
}
|
||||
|
||||
if( pID == pElum1XY ){
|
||||
|
||||
TH2F * hElum1XY = new TH2F("hElum1XY", Form("Elum-1 XY [gated] @ %.0f mm ; X [mm]; Y [mm]", elum1), 400, -elumRange, elumRange, 400, -elumRange, elumRange);
|
||||
tree->Draw("yElum1:xElum1>>hElum1XY", gate, "colz");
|
||||
|
||||
double count = hElum1XY->GetEntries();
|
||||
|
||||
if( count < 2000. ) {
|
||||
hElum1XY->SetMarkerStyle(7);
|
||||
if( count < 500. ) hElum1XY->SetMarkerStyle(3);
|
||||
hElum1XY->Draw("scat");
|
||||
}
|
||||
}
|
||||
|
||||
if( pID == pEElum1R ){
|
||||
TH2F * hEElum1Rho = new TH2F("hEElum1Rho", "Elum-1 E-R [gated]; R[mm]; Energy[MeV]", 400, 0, elumRange, 400, eRange[0], eRange[1]);
|
||||
tree->Draw("Tb:rhoElum1>>hEElum1Rho", gate, "colz");
|
||||
}
|
||||
|
||||
if( pID == pElum1RThetaCM){
|
||||
int angBin = 400;
|
||||
|
||||
TH2F * hElum1RThetaCM = new TH2F("hElum1RThetaCM", "Elum-1 rho vs ThetaCM [gated]; thatCM [deg]; Elum- rho [mm]", angBin, thetaCMRange[0], thetaCMRange[1], 400, 0, elumRange);
|
||||
tree->Draw("rhoElum1:thetaCM>>hElum1RThetaCM", gate, "colz");
|
||||
|
||||
TH1F * htemp = (TH1F *) hElum1RThetaCM->ProjectionX("htemp");
|
||||
|
||||
double rel = (thetaCMRange[1] - thetaCMRange[0])*1.0/angBin;
|
||||
printf("angular resolution : %f deg \n", rel);
|
||||
|
||||
vector<double> xList;
|
||||
double old_y = 0;
|
||||
for( int i = 1; i <= angBin; i++){
|
||||
double y = htemp->GetBinContent(i);
|
||||
if( old_y == 0 && y > 0) xList.push_back(htemp->GetBinCenter(i));
|
||||
if( old_y > 0 && y == 0 ) xList.push_back(htemp->GetBinCenter(i));
|
||||
old_y = y;
|
||||
}
|
||||
|
||||
printf("list of gaps :\n");
|
||||
for( int i = 0; i < (int) xList.size(); i+=2){
|
||||
printf("%d | %.3f - %.3f deg\n", i, xList[i], xList[i+1]);
|
||||
}
|
||||
|
||||
TF1 f1("f1", "sin(x)");
|
||||
double acceptance = 0;
|
||||
double err1 = 0;
|
||||
double err2 = 0;
|
||||
for( int i = 0; i < (int) xList.size(); i += 2 ){
|
||||
acceptance += f1.Integral(xList[i] * TMath::DegToRad(), xList[i+1] * TMath::DegToRad() ) * TMath::TwoPi();
|
||||
err1 += f1.Integral((xList[i]-rel) * TMath::DegToRad(), (xList[i+1] + rel) * TMath::DegToRad() ) * TMath::TwoPi();
|
||||
err2 += f1.Integral((xList[i]+rel) * TMath::DegToRad(), (xList[i+1] - rel) * TMath::DegToRad() ) * TMath::TwoPi();
|
||||
}
|
||||
printf("acceptance = %f sr +- %f \n", acceptance, (err1-err2)/2);
|
||||
|
||||
TLatex text;
|
||||
text.SetTextFont(82);
|
||||
text.SetTextSize(0.06);
|
||||
text.SetTextColor(2);
|
||||
text.SetTextAngle(90);
|
||||
|
||||
for( int i = 0; i < (int) xList.size(); i++){
|
||||
text.DrawLatex(xList[i], elumRange/2, Form("%.2f", xList[i]));
|
||||
}
|
||||
|
||||
text.SetNDC();
|
||||
text.SetTextAngle(0);
|
||||
text.DrawLatex(0.15, 0.15, Form("accp. = %.2f(%.2f) msr", acceptance * 1000., (err1-err2)*1000./2));
|
||||
|
||||
}
|
||||
|
||||
if( pID == pHitID ){
|
||||
printf("=======================meaning of Hit ID\n");
|
||||
printf(" 1 = light recoil hit array & heavy recoil hit recoil\n");
|
||||
printf(" 0 = no detector\n");
|
||||
printf(" -1 = light recoil go opposite side of array\n");
|
||||
printf(" -2 = light recoil hit > det width\n");
|
||||
printf(" -3 = light recoil hit > array \n");
|
||||
printf(" -4 = light recoil hit blocker \n");
|
||||
printf(" -10 = light recoil orbit radius too big \n");
|
||||
printf(" -11 = light recoil orbit radius too small\n");
|
||||
printf(" -12 = when reocol at the same side of array, light recoil blocked by recoil detector\n");
|
||||
printf(" -13 = more than 3 loops\n");
|
||||
printf(" -14 = heavy recoil did not hit recoil \n");
|
||||
printf(" -15 = cannot find hit on array\n");
|
||||
printf(" -20 = unknown\n");
|
||||
printf("===========================================\n");
|
||||
|
||||
TH1F * hHit = new TH1F("hHit", "hit; hit-ID; count", 13, -11, 2);
|
||||
tree->Draw("hit>>hHit", "", "");
|
||||
}
|
||||
///#######################################################
|
||||
|
||||
}
|
||||
|
||||
cCheck->Modified();
|
||||
cCheck->Update();
|
||||
|
||||
if( outputCanvas ){
|
||||
TDatime dateTime;
|
||||
TString outPNGName = Form("Sim_%d%02d%02d_%06d.png", dateTime.GetYear(), dateTime.GetMonth(), dateTime.GetDay(), dateTime.GetTime());
|
||||
|
||||
cCheck->SaveAs(outPNGName);
|
||||
printf("%s\n", outPNGName.Data());
|
||||
|
||||
gROOT->ProcessLine(".q");
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
///============================================================
|
||||
///============================================================
|
||||
|
||||
double * FindRange(TString branch, TString gate, TTree * tree, double output[2]){
|
||||
tree->Draw(Form("%s>>temp1", branch.Data()), gate);
|
||||
TH1F * temp1 = (TH1F *) gROOT->FindObjectAny("temp1");
|
||||
|
||||
output[1] = temp1->GetXaxis()->GetXmax();
|
||||
output[0] = temp1->GetXaxis()->GetXmin();
|
||||
|
||||
delete temp1;
|
||||
return output;
|
||||
}
|
||||
|
||||
double ExtractNumber(int index, TMacro * macro){
|
||||
|
||||
TString field = macro->GetListOfLines()->At(index)->GetName();
|
||||
int pos = field.First('/');
|
||||
if( pos >= 0 ) field.Remove(pos);
|
||||
|
||||
return field.Atof();
|
||||
|
||||
}
|
||||
TString ExtractString(int index, TMacro * macro){
|
||||
|
||||
TString field = macro->GetListOfLines()->At(index)->GetName();
|
||||
|
||||
int pos = field.First('/');
|
||||
if( pos >= 0 ) field.Remove(pos);
|
||||
|
||||
return field;
|
||||
|
||||
}
|
||||
|
||||
vector<TString> StringToVector(TString str){
|
||||
|
||||
vector<TString> temp;
|
||||
|
||||
bool startFlag = false;
|
||||
bool endFlag = false;
|
||||
string jaja="";
|
||||
for(int i = 0; i < str.Length(); i++){
|
||||
|
||||
if( str[i] == '{' ) {
|
||||
startFlag = true;
|
||||
continue;
|
||||
}
|
||||
if( str[i] == ' '){
|
||||
continue;
|
||||
}
|
||||
if( startFlag && !endFlag){
|
||||
|
||||
if( str[i] == ',' ){
|
||||
temp.push_back(jaja);
|
||||
jaja="";
|
||||
continue;
|
||||
}
|
||||
|
||||
if( str[i] == '}') {
|
||||
temp.push_back(jaja);
|
||||
endFlag = true;
|
||||
continue;
|
||||
}
|
||||
jaja += str[i];
|
||||
|
||||
}
|
||||
}
|
||||
return temp;
|
||||
}
|
||||
|
||||
vector<int> intConvertor(vector<TString> arr){
|
||||
vector<int> out ;
|
||||
for( int i = 0 ; i < (int) arr.size(); i++){
|
||||
out.push_back( arr[i].Atoi());
|
||||
}
|
||||
return out;
|
||||
}
|
||||
vector<double> doubleConvertor(vector<TString> arr){
|
||||
vector<double> out ;
|
||||
for( int i = 0 ; i < (int) arr.size(); i++){
|
||||
out.push_back( arr[i].Atof());
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
plotID StringToPlotID(TString str){
|
||||
|
||||
if( str == "pEZ") return plotID::pEZ; ///0
|
||||
if( str == "pRecoilXY") return plotID::pRecoilXY; /// 1
|
||||
if( str == "pRecoilXY1" ) return plotID::pRecoilXY1; /// 2
|
||||
if( str == "pRecoilXY2" ) return plotID::pRecoilXY2; /// 3
|
||||
if( str == "pRecoilRZ" ) return plotID::pRecoilRZ; /// 4
|
||||
if( str == "pRecoilRTR" ) return plotID::pRecoilRTR; /// 5
|
||||
if( str == "pTDiffZ" ) return plotID::pTDiffZ; /// 6
|
||||
if( str == "pThetaCM" ) return plotID::pThetaCM; /// 7
|
||||
if( str == "pThetaCM_Z" ) return plotID::pThetaCM_Z; /// 8
|
||||
if( str == "pExCal" ) return plotID::pExCal; /// 9
|
||||
if( str == "pRecoilRThetaCM" ) return plotID::pRecoilRThetaCM; /// 10
|
||||
if( str == "pArrayXY" ) return plotID::pArrayXY; /// 11
|
||||
if( str == "pInfo" ) return plotID::pInfo; /// 12
|
||||
if( str == "pHitID" ) return plotID::pHitID; /// 13
|
||||
if( str == "pElum1XY" ) return plotID::pElum1XY; /// 14
|
||||
if( str == "pEElum1R" ) return plotID::pEElum1R; /// 14
|
||||
if( str == "pElum1RThetaCM" ) return plotID::pElum1RThetaCM; /// 15
|
||||
if( str == "pEmpty" ) return plotID::pEmpty ; /// 16
|
||||
|
||||
return plotID::pEmpty;
|
||||
}
|
|
@ -1,656 +0,0 @@
|
|||
#include <TFile.h>
|
||||
#include <TTree.h>
|
||||
#include <TCanvas.h>
|
||||
#include <TROOT.h>
|
||||
#include <TObjArray.h>
|
||||
#include <TStyle.h>
|
||||
#include <TH2F.h>
|
||||
#include <TH1F.h>
|
||||
#include <TF1.h>
|
||||
#include <TArc.h>
|
||||
#include <TMath.h>
|
||||
#include <TLine.h>
|
||||
#include <TSpectrum.h>
|
||||
#include <TGraph.h>
|
||||
#include <TLegend.h>
|
||||
#include <TLatex.h>
|
||||
#include <TMacro.h>
|
||||
#include <TObjArray.h>
|
||||
#include <fstream>
|
||||
#include <TCutG.h>
|
||||
#include "../Armory/AnalysisLib.h"
|
||||
#include "../Armory/ClassDetGeo.h"
|
||||
#include "../Armory/ClassReactionConfig.h"
|
||||
#include "../Cleopatra/ClassIsotope.h"
|
||||
#include "../Cleopatra/ClassTransfer.h"
|
||||
|
||||
double * FindRange(TString branch, TString gate, TTree * tree, double output[2]);
|
||||
double ExtractNumber(int index, TMacro * macro);
|
||||
TString ExtractString(int index, TMacro * macro);
|
||||
vector<TString> StringToVector(TString str);
|
||||
vector<int> intConvertor(vector<TString> arr);
|
||||
vector<double> doubleConvertor(vector<TString> arr);
|
||||
|
||||
enum plotID { pEZ, /// 0
|
||||
pRecoilXY, /// 1
|
||||
pRecoilXY1, /// 2
|
||||
pRecoilXY2, /// 3
|
||||
pRecoilRZ, /// 4
|
||||
pRecoilRTR, /// 5
|
||||
pTDiffZ, /// 6
|
||||
pThetaCM, /// 7
|
||||
pThetaCM_Z, /// 8
|
||||
pExCal, /// 9
|
||||
pRecoilRThetaCM, /// 10
|
||||
pArrayXY, /// 11
|
||||
pInfo, /// 12
|
||||
pHitID, /// 13
|
||||
pElum1XY, /// 14
|
||||
pEElum1R, /// 15
|
||||
pElum1RThetaCM, /// 16
|
||||
pEmpty }; /// 17
|
||||
plotID StringToPlotID(TString str);
|
||||
|
||||
//*=====================================================
|
||||
void Check_Simulation(TString filename = "transfer.root",
|
||||
TString configFile = "../working/Check_Simulation_Config.txt",
|
||||
Int_t padSize = 500,
|
||||
bool outputCanvas = false){
|
||||
|
||||
printf("=========================== Check_Simulation.C\n");
|
||||
|
||||
TMacro * config = new TMacro(configFile);
|
||||
int numLine = config->GetListOfLines()->GetSize();
|
||||
int startLineNum = 0;
|
||||
for( int i = 0; i < numLine ; i++){
|
||||
TString haha = config->GetListOfLines()->At(i)->GetName();
|
||||
haha.Remove(4);
|
||||
if( haha != "////" ) {
|
||||
startLineNum = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
TString gate = ExtractString(startLineNum+1, config);
|
||||
double elumRange = ExtractNumber(startLineNum+2, config);
|
||||
std::vector<double> thetaCMRange = doubleConvertor( StringToVector( ExtractString(startLineNum+3,config) ));
|
||||
bool shownKELines = (ExtractString(startLineNum+4, config).Remove(4) == "true" ? true : false);
|
||||
bool isOverRideEx = (ExtractString(startLineNum+5, config).Remove(4) == "true" ? true : false);
|
||||
std::vector<double> oExRange = doubleConvertor( StringToVector ( ExtractString(startLineNum+6, config )));
|
||||
|
||||
printf("%s \n", gate.Data());
|
||||
|
||||
///==== config Canvas
|
||||
std::vector<TString> plotConfig = StringToVector( ExtractString(startLineNum, config));
|
||||
std::vector<plotID> canvas;
|
||||
int colCount = 0;
|
||||
int colCount_new = 0;
|
||||
int rowCount = 1;
|
||||
for( int i = 0; i < (int) plotConfig.size(); i++){
|
||||
if( plotConfig[i] == "break" ) {
|
||||
rowCount ++;
|
||||
if( colCount_new > colCount ) colCount = colCount_new;
|
||||
colCount_new = 0;
|
||||
continue;
|
||||
}
|
||||
canvas.push_back( StringToPlotID(plotConfig[i]));
|
||||
colCount_new ++;
|
||||
}
|
||||
|
||||
if( colCount == 0 ) colCount = colCount_new;
|
||||
//printf("plot row: %d, col: %d \n", rowCount, colCount);
|
||||
|
||||
std::vector<int> Div = {colCount, rowCount};
|
||||
|
||||
TFile * file = new TFile(filename, "read");
|
||||
TTree * tree = (TTree*) file->Get("tree");
|
||||
|
||||
TObjArray * fxList = (TObjArray *) file->FindObjectAny("EZCurve");
|
||||
TObjArray * txList = (TObjArray *) file->FindObjectAny("thetaCM_Z");
|
||||
|
||||
gStyle->SetOptStat("");
|
||||
gStyle->SetStatY(0.9);
|
||||
gStyle->SetStatX(0.9);
|
||||
gStyle->SetStatW(0.4);
|
||||
gStyle->SetStatH(0.2);
|
||||
gStyle->SetLabelSize(0.05, "XY");
|
||||
gStyle->SetTitleFontSize(0.1);
|
||||
|
||||
//*================== detGeoID
|
||||
TMacro * detGeoIDTxt = (TMacro *) file->FindObjectAny("detGeoID");
|
||||
int detGeoID = atoi(detGeoIDTxt->GetListOfLines()->At(0)->GetName());
|
||||
|
||||
//*================== reactionConfig
|
||||
TMacro * reactionConfigTxt = (TMacro *) file->FindObjectAny("reactionConfig");
|
||||
TString Reaction = reactionConfigTxt->GetName();
|
||||
|
||||
ReactionConfig reactionConfig(reactionConfigTxt);
|
||||
Recoil recoil = reactionConfig.recoil[detGeoID];
|
||||
|
||||
int nEvent = reactionConfig.numEvents;
|
||||
printf("number of events generated : %d \n", nEvent);
|
||||
|
||||
reactionConfig.Print(detGeoID, false);
|
||||
|
||||
//*================================== detetcor Geometry
|
||||
printf("=================================\n");
|
||||
printf(" loading detector Geometry.\n");
|
||||
TMacro * detGeoTxt = (TMacro *) file->FindObjectAny("detGeo");
|
||||
|
||||
DetGeo detGeo(detGeoTxt);
|
||||
Array array = detGeo.array[detGeoID];
|
||||
|
||||
detGeo.Print();
|
||||
array.Print();
|
||||
|
||||
printf("=================================\n");
|
||||
|
||||
int numDet = array.colDet * array.rowDet ;
|
||||
|
||||
double zRange[3] = {400, -1000, 1000}; /// zRange[0] = nBin
|
||||
zRange[1] = array.zMin - 50;
|
||||
zRange[2] = array.zMax + 50;
|
||||
|
||||
printf(" zRange : %f - %f \n", zRange[1], zRange[2]);
|
||||
printf("=================================\n");
|
||||
|
||||
//*========================================= Ex List;
|
||||
double ExRange[2];
|
||||
int numEx = 0;
|
||||
ExcitedEnergies exList;
|
||||
|
||||
// if DEBA_ExList exist, use this, else use the recoil ExList
|
||||
TMacro * exListTxt = (TMacro *) file->FindObjectAny("DWBA_ExList");
|
||||
|
||||
ExRange[0] = 9999999;
|
||||
ExRange[1] = -9999999;
|
||||
|
||||
if( exListTxt == nullptr ){
|
||||
|
||||
exList = reactionConfig.exList[detGeoID];
|
||||
numEx = exList.ExList.size();
|
||||
|
||||
for( size_t i = 0; i < numEx; i++ ){
|
||||
double ex = exList.ExList[i].Ex;
|
||||
if( ex < ExRange[0] ) ExRange[0] = ex;
|
||||
if( ex > ExRange[1] ) ExRange[1] = ex;
|
||||
}
|
||||
|
||||
}else{
|
||||
|
||||
numEx = exListTxt->GetListOfLines()->GetSize()-1;
|
||||
for( int i = 1 ; i <= numEx ; i++){
|
||||
std::vector<std::string> tempStr = AnalysisLib::SplitStr(exListTxt->GetListOfLines()->At(i)->GetName(), " ");
|
||||
double ex = atof(tempStr[0].c_str());
|
||||
if( ex < ExRange[0] ) ExRange[0] = ex;
|
||||
if( ex > ExRange[1] ) ExRange[1] = ex;
|
||||
exList.Add(ex, atof(tempStr[1].c_str()), 1.0, 0.00);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
exList.Print();
|
||||
|
||||
double dExRange = ExRange[1] - ExRange[0];
|
||||
ExRange[0] = ExRange[0] - 0.3 - dExRange * 0.1;
|
||||
ExRange[1] = ExRange[1] + 0.3 + dExRange * 0.1;
|
||||
|
||||
printf("Number of Ex states = %d \n", numEx);
|
||||
|
||||
//*=================================== calculate Ranges
|
||||
//eRange by zRange and exList
|
||||
|
||||
TransferReaction transfer;
|
||||
transfer.SetReactionSimple( reactionConfig.beamA,
|
||||
reactionConfig.beamZ,
|
||||
reactionConfig.targetA,
|
||||
reactionConfig.targetZ,
|
||||
recoil.lightA,
|
||||
recoil.lightZ,
|
||||
reactionConfig.beamEnergy);
|
||||
|
||||
double QQ = transfer.GetCMTotalEnergy();
|
||||
double gamm = transfer.GetReactionGamma();
|
||||
double mass = transfer.GetMass_b();
|
||||
double slope = transfer.GetEZSlope( detGeo.Bfield);
|
||||
|
||||
double eRange[2] = {0, 10};
|
||||
eRange[1] = zRange[2] * slope;
|
||||
|
||||
// printf("intercept of 0 MeV : %f MeV \n", intercept);
|
||||
printf("eRange 0 MeV : %f MeV \n", eRange[1]);
|
||||
|
||||
double dERange = eRange[1] - eRange[0];
|
||||
|
||||
eRange[0] = eRange[0] - dERange * 0.1;
|
||||
eRange[1] = eRange[1] + dERange * 0.1;
|
||||
|
||||
|
||||
//thetaCMRange
|
||||
double momentum = transfer.GetMomentumbCM();
|
||||
double beta = transfer.GetReactionBeta();
|
||||
double alpha = slope / beta;
|
||||
double thetaMax = acos( (beta * QQ- alpha / gamm * zRange[2])/momentum) * TMath::RadToDeg();
|
||||
thetaCMRange[1] = (int) TMath::Ceil(thetaMax/10.)*10;
|
||||
///printf(" momentum : %f \n", momentum);
|
||||
///printf(" thetaCM Max : %f \n", thetaMax);
|
||||
///printf(" thetaCM Range : %d \n", thetaCMRange[1]);
|
||||
|
||||
|
||||
double recoilERange[2] = {0, 100};
|
||||
|
||||
//===================================================
|
||||
printf("============================== Gate\n");
|
||||
printf("gate : %s\n", gate.Data());
|
||||
printf("====================================\n");
|
||||
|
||||
Int_t size[2] = {padSize,padSize}; ///x,y, single Canvas size
|
||||
TCanvas * cCheck = new TCanvas("cCheck", "Check For Simulation", 0, 0, size[0]*Div[0], size[1]*Div[1]);
|
||||
if(cCheck->GetShowEditor() )cCheck->ToggleEditor();
|
||||
if(cCheck->GetShowToolBar() )cCheck->ToggleToolBar();
|
||||
cCheck->Divide(Div[0],Div[1]);
|
||||
|
||||
for( int i = 1; i <= Div[0]*Div[1] ; i++){
|
||||
cCheck->cd(i);
|
||||
|
||||
if( canvas[i-1] == pThetaCM ) {
|
||||
cCheck->cd(i)->SetGrid(0,0);
|
||||
cCheck->cd(i)->SetLogy();
|
||||
}
|
||||
|
||||
if( canvas[i-1] == pHitID ){
|
||||
cCheck->cd(i)->SetLogy();
|
||||
}
|
||||
|
||||
plotID pID = canvas[i-1];
|
||||
|
||||
///########################################
|
||||
if( pID == pEZ){
|
||||
TH2F * hez = new TH2F("hez", Form("e-z [gated] @ %5.0f mm; z [mm]; e [MeV]", array.firstPos), zRange[0], zRange[1], zRange[2],
|
||||
400, eRange[0], eRange[1]);
|
||||
tree->Draw("e:z>>hez", gate, "colz");
|
||||
if( shownKELines){
|
||||
for( int i = 0; i < numEx ; i++){
|
||||
fxList->At(i)->Draw("same");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( pID == pRecoilXY ){
|
||||
TH2F * hRecoilXY = new TH2F("hRecoilXY", Form("RecoilXY [gated] @ %4.0f mm; X [mm]; Y [mm]", detGeo.aux[detGeoID].detPos ),
|
||||
400, -detGeo.aux[detGeoID].outerRadius, detGeo.aux[detGeoID].outerRadius,
|
||||
400, -detGeo.aux[detGeoID].outerRadius, detGeo.aux[detGeoID].outerRadius);
|
||||
tree->Draw("yRecoil:xRecoil>>hRecoilXY", gate, "colz");
|
||||
TArc * detArc1 = new TArc(0,0, detGeo.aux[detGeoID].outerRadius);
|
||||
detArc1->SetLineColor(kBlue-8);
|
||||
detArc1->SetFillStyle(0);
|
||||
detArc1->Draw("same");
|
||||
TArc * detArc2 = new TArc(0,0, detGeo.aux[detGeoID].innerRadius);
|
||||
detArc2->SetLineColor(kBlue-8);
|
||||
detArc2->SetFillStyle(0);
|
||||
detArc2->Draw("same");
|
||||
|
||||
if( reactionConfig.beamX != 0. || reactionConfig.beamY != 0. ){
|
||||
TArc * arc = new TArc(reactionConfig.beamX, reactionConfig.beamY, 1);
|
||||
arc->SetLineColor(2);
|
||||
detArc1->SetFillStyle(0);
|
||||
arc->Draw("same");
|
||||
}
|
||||
}
|
||||
|
||||
if( pID == pRecoilXY1 ){
|
||||
TH2F * hRecoilXY1 = new TH2F("hRecoilXY1", Form("RecoilXY-1 [gated] @ %4.0f mm; X [mm]; Y [mm]", detGeo.aux[detGeoID].detPos1 ),
|
||||
400, -detGeo.aux[detGeoID].outerRadius, detGeo.aux[detGeoID].outerRadius,
|
||||
400, -detGeo.aux[detGeoID].outerRadius, detGeo.aux[detGeoID].outerRadius);
|
||||
tree->Draw("yRecoil1:xRecoil1>>hRecoilXY1", gate, "colz");
|
||||
}
|
||||
|
||||
if( pID == pRecoilXY2 ){
|
||||
TH2F * hRecoilXY2 = new TH2F("hRecoilXY2", Form("RecoilXY-2 [gated] @ %4.0f mm; X [mm]; Y [mm]", detGeo.aux[detGeoID].detPos2 ),
|
||||
400, -detGeo.aux[detGeoID].outerRadius, detGeo.aux[detGeoID].outerRadius,
|
||||
400, -detGeo.aux[detGeoID].outerRadius, detGeo.aux[detGeoID].outerRadius);
|
||||
tree->Draw("yRecoil2:xRecoil2>>hRecoilXY2", gate, "colz");
|
||||
}
|
||||
|
||||
if( pID == pRecoilRZ ){
|
||||
TH2F * hRecoilRZ = new TH2F("hRecoilRZ", "RecoilR - Z [gated]; z [mm]; RecoilR [mm]", zRange[0], zRange[1], zRange[2], 400,0, detGeo.aux[detGeoID].outerRadius);
|
||||
tree->Draw("rhoRecoil:z>>hRecoilRZ", gate, "colz");
|
||||
}
|
||||
|
||||
if( pID == pRecoilRTR ){
|
||||
FindRange("TB", gate, tree, recoilERange);
|
||||
TH2F * hRecoilRTR = new TH2F("hRecoilRTR", "RecoilR - recoilE [gated]; recoil Energy [MeV]; RecoilR [mm]", 500, recoilERange[0], recoilERange[1], 500, 0, detGeo.aux[detGeoID].outerRadius);
|
||||
tree->Draw("rhoRecoil:TB>>hRecoilRTR", gate, "colz");
|
||||
}
|
||||
|
||||
if( pID == pTDiffZ ){
|
||||
double tDiffRange [2];
|
||||
FindRange("t-tB", gate, tree, tDiffRange);
|
||||
TH2F * hTDiffZ = new TH2F("hTDiffZ", "time(Array) - time(Recoil) vs Z [gated]; z [mm]; time diff [ns]", zRange[0], zRange[1], zRange[2], 500, tDiffRange[0], tDiffRange[1]);
|
||||
tree->Draw("t - tB : z >> hTDiffZ", gate, "colz");
|
||||
}
|
||||
|
||||
if( pID == pThetaCM ){
|
||||
TH1F * hThetaCM[numEx];
|
||||
TLegend * legend = new TLegend(0.8,0.2,0.99,0.8);
|
||||
double maxCount = 0;
|
||||
int startID = 0; // set the start ExID
|
||||
for( int i = startID; i < numEx; i++){
|
||||
hThetaCM[i] = new TH1F(Form("hThetaCM%d", i), Form("thetaCM [gated] (ExID=%d); thetaCM [deg]; count", i), 200, thetaCMRange[0], thetaCMRange[1]);
|
||||
hThetaCM[i]->SetLineColor(i+1-startID);
|
||||
hThetaCM[i]->SetFillColor(i+1-startID);
|
||||
hThetaCM[i]->SetFillStyle(3000+i-startID);
|
||||
tree->Draw(Form("thetaCM>>hThetaCM%d", i), gate + Form("&& ExID==%d", i), "");
|
||||
legend->AddEntry(hThetaCM[i], Form("Ex=%5.1f MeV", exList.ExList[i].Ex));
|
||||
double max = hThetaCM[i]->GetMaximum();
|
||||
if( max > maxCount ) maxCount = max;
|
||||
}
|
||||
|
||||
for( int i = startID; i < numEx; i++){
|
||||
hThetaCM[i]->GetYaxis()->SetRangeUser(1, maxCount * 1.2);
|
||||
if( i == startID ) {
|
||||
hThetaCM[i]->Draw();
|
||||
}else{
|
||||
hThetaCM[i]->Draw("same");
|
||||
}
|
||||
}
|
||||
legend->Draw();
|
||||
}
|
||||
|
||||
if( pID == pThetaCM_Z ){
|
||||
TH2F *hThetaCM_Z = new TH2F("hThetaCM_Z","ThetaCM vs Z ; Z [mm]; thetaCM [deg]",zRange[0], zRange[1], zRange[2], 200, thetaCMRange[0], thetaCMRange[1]);
|
||||
tree->Draw("thetaCM:z>>hThetaCM_Z",gate,"col");
|
||||
if( shownKELines){
|
||||
for( int i = 0; i < numEx ; i++){
|
||||
txList->At(i)->Draw("same");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( pID == pExCal ){
|
||||
TH1F * hExCal = new TH1F("hExCal", Form("calculated Ex [gated]; Ex [MeV]; count / %.2f keV", (ExRange[1]-ExRange[0])/400.*1000), 400, ExRange[0], ExRange[1]);
|
||||
tree->Draw("ExCal>>hExCal", gate, "");
|
||||
Isotope hRecoil(recoil.heavyA, recoil.heavyZ);
|
||||
double Sn = hRecoil.CalSp(0,1);
|
||||
double Sp = hRecoil.CalSp(1,0);
|
||||
double Sa = hRecoil.CalSp2(4,2);
|
||||
double S2n = hRecoil.CalSp(0, 2);
|
||||
|
||||
printf("Heavy recoil: %s \n", hRecoil.Name.c_str());
|
||||
printf("Sn : %f MeV/u \n", Sn);
|
||||
printf("Sp : %f MeV/u \n", Sp);
|
||||
printf("Sa : %f MeV/u \n", Sa);
|
||||
printf("S2n : %f MeV/u \n", S2n);
|
||||
|
||||
double yMax = hExCal->GetMaximum();
|
||||
TLine * lineSn = new TLine(Sn, 0, Sn, yMax); lineSn->SetLineColor(2); lineSn->Draw("");
|
||||
TLine * lineSp = new TLine(Sp, 0, Sp, yMax); lineSp->SetLineColor(4); lineSp->Draw("same");
|
||||
TLine * lineSa = new TLine(Sa, 0, Sa, yMax); lineSa->SetLineColor(6); lineSa->Draw("same");
|
||||
TLine * lineS2n = new TLine(S2n, 0, S2n, yMax); lineS2n->SetLineColor(8); lineS2n->Draw("same");
|
||||
|
||||
TLatex * text = new TLatex();
|
||||
text->SetTextFont(82);
|
||||
text->SetTextSize(0.06);
|
||||
text->SetTextColor(2); text->DrawLatex(Sn, yMax*0.9, "S_{n}");
|
||||
text->SetTextColor(4); text->DrawLatex(Sp, yMax*0.9, "S_{p}");
|
||||
text->SetTextColor(6); text->DrawLatex(Sa, yMax*0.9, "S_{a}");
|
||||
text->SetTextColor(8); text->DrawLatex(S2n, yMax*0.9, "S_{2n}");
|
||||
|
||||
}
|
||||
|
||||
if( pID == pRecoilRThetaCM ){
|
||||
TH2F * hRecoilRThetaCM = new TH2F("hRecoilRThetaCM", "RecoilR - thetaCM [gated]; thetaCM [deg]; RecoilR [mm]", 400, 0, 60, 400,0, detGeo.aux[detGeoID].outerRadius);
|
||||
tree->Draw("rhoRecoil:thetaCM>>hRecoilRThetaCM", gate, "colz");
|
||||
}
|
||||
|
||||
if( pID == pArrayXY ){
|
||||
TH2F * hArrayXY = new TH2F("hArrayXY", "Array-XY [gated]; X [mm]; Y [mm]", 400, -array.detPerpDist*1.5, array.detPerpDist*1.5, 400, -array.detPerpDist*1.5, array.detPerpDist*1.5);
|
||||
tree->Draw("yArray:xArray>>hArrayXY", gate, "colz");
|
||||
}
|
||||
|
||||
if( pID == pInfo ){
|
||||
TLatex text;
|
||||
text.SetNDC();
|
||||
text.SetTextFont(82);
|
||||
text.SetTextSize(0.06);
|
||||
text.SetTextColor(2);
|
||||
|
||||
text.DrawLatex(0., 0.9, Reaction);
|
||||
text.DrawLatex(0., 0.8, detGeo.Bfield > 0 ? "out of plan" : "into plan");
|
||||
text.SetTextColor(1);
|
||||
text.DrawLatex(0., 0.7, "gate:");
|
||||
|
||||
text.SetTextColor(2);
|
||||
//check gate text length, if > 30, break by "&&"
|
||||
int ll = gate.Length();
|
||||
if( ll > 30 ) {
|
||||
vector<string> strList = AnalysisLib::SplitStr( (string) gate.Data(), "&&");
|
||||
for( int i = 0; i < strList.size(); i++){
|
||||
text.DrawLatex(0., 0.6 - 0.05*i, (TString) strList[i]);
|
||||
}
|
||||
}else{
|
||||
text.DrawLatex(0., 0.6, gate);
|
||||
}
|
||||
|
||||
if( reactionConfig.beamX != 0.0 || reactionConfig.beamY != 0.0 ){
|
||||
text.DrawLatex(0.0, 0.1, Form("Bema pos: (%4.1f, %4.1f) mm", reactionConfig.beamX, reactionConfig.beamY));
|
||||
}
|
||||
}
|
||||
|
||||
if( pID == pElum1XY ){
|
||||
TH2F * hElum1XY = new TH2F("hElum1XY", Form("Elum-1 XY [gated] @ %.0f mm ; X [mm]; Y [mm]", detGeo.aux[detGeoID].elumPos1), 400, -elumRange, elumRange, 400, -elumRange, elumRange);
|
||||
tree->Draw("yElum1:xElum1>>hElum1XY", gate, "colz");
|
||||
|
||||
double count = hElum1XY->GetEntries();
|
||||
|
||||
if( count < 2000. ) {
|
||||
hElum1XY->SetMarkerStyle(7);
|
||||
if( count < 500. ) hElum1XY->SetMarkerStyle(3);
|
||||
hElum1XY->Draw("scat");
|
||||
}
|
||||
}
|
||||
|
||||
if( pID == pEElum1R ){
|
||||
TH2F * hEElum1Rho = new TH2F("hEElum1Rho", "Elum-1 E-R [gated]; R[mm]; Energy[MeV]", 400, 0, elumRange, 400, eRange[0], eRange[1]);
|
||||
tree->Draw("Tb:rhoElum1>>hEElum1Rho", gate, "colz");
|
||||
}
|
||||
|
||||
if( pID == pElum1RThetaCM){
|
||||
int angBin = 400;
|
||||
|
||||
TH2F * hElum1RThetaCM = new TH2F("hElum1RThetaCM", "Elum-1 rho vs ThetaCM [gated]; thatCM [deg]; Elum- rho [mm]", angBin, thetaCMRange[0], thetaCMRange[1], 400, 0, elumRange);
|
||||
tree->Draw("rhoElum1:thetaCM>>hElum1RThetaCM", gate, "colz");
|
||||
|
||||
TH1F * htemp = (TH1F *) hElum1RThetaCM->ProjectionX("htemp");
|
||||
|
||||
double rel = (thetaCMRange[1] - thetaCMRange[0])*1.0/angBin;
|
||||
printf("angular resolution : %f deg \n", rel);
|
||||
|
||||
vector<double> xList;
|
||||
double old_y = 0;
|
||||
for( int i = 1; i <= angBin; i++){
|
||||
double y = htemp->GetBinContent(i);
|
||||
if( old_y == 0 && y > 0) xList.push_back(htemp->GetBinCenter(i));
|
||||
if( old_y > 0 && y == 0 ) xList.push_back(htemp->GetBinCenter(i));
|
||||
old_y = y;
|
||||
}
|
||||
|
||||
printf("list of gaps :\n");
|
||||
for( int i = 0; i < (int) xList.size(); i+=2){
|
||||
printf("%d | %.3f - %.3f deg\n", i, xList[i], xList[i+1]);
|
||||
}
|
||||
|
||||
TF1 f1("f1", "sin(x)");
|
||||
double acceptance = 0;
|
||||
double err1 = 0;
|
||||
double err2 = 0;
|
||||
for( int i = 0; i < (int) xList.size(); i += 2 ){
|
||||
acceptance += f1.Integral(xList[i] * TMath::DegToRad(), xList[i+1] * TMath::DegToRad() ) * TMath::TwoPi();
|
||||
err1 += f1.Integral((xList[i]-rel) * TMath::DegToRad(), (xList[i+1] + rel) * TMath::DegToRad() ) * TMath::TwoPi();
|
||||
err2 += f1.Integral((xList[i]+rel) * TMath::DegToRad(), (xList[i+1] - rel) * TMath::DegToRad() ) * TMath::TwoPi();
|
||||
}
|
||||
printf("acceptance = %f sr +- %f \n", acceptance, (err1-err2)/2);
|
||||
|
||||
TLatex text;
|
||||
text.SetTextFont(82);
|
||||
text.SetTextSize(0.06);
|
||||
text.SetTextColor(2);
|
||||
text.SetTextAngle(90);
|
||||
|
||||
for( int i = 0; i < (int) xList.size(); i++){
|
||||
text.DrawLatex(xList[i], elumRange/2, Form("%.2f", xList[i]));
|
||||
}
|
||||
|
||||
text.SetNDC();
|
||||
text.SetTextAngle(0);
|
||||
text.DrawLatex(0.15, 0.15, Form("accp. = %.2f(%.2f) msr", acceptance * 1000., (err1-err2)*1000./2));
|
||||
|
||||
}
|
||||
|
||||
if( pID == pHitID ){
|
||||
printf("=======================meaning of Hit ID\n");
|
||||
printf(" 1 = light recoil hit array & heavy recoil hit recoil\n");
|
||||
printf(" 0 = no detector\n");
|
||||
printf(" -1 = light recoil go opposite side of array\n");
|
||||
printf(" -2 = light recoil hit > det width\n");
|
||||
printf(" -3 = light recoil hit > array \n");
|
||||
printf(" -4 = light recoil hit blocker \n");
|
||||
printf(" -10 = light recoil orbit radius too big \n");
|
||||
printf(" -11 = light recoil orbit radius too small\n");
|
||||
printf(" -12 = when reocol at the same side of array, light recoil blocked by recoil detector\n");
|
||||
printf(" -13 = more than 3 loops\n");
|
||||
printf(" -14 = heavy recoil did not hit recoil \n");
|
||||
printf(" -15 = cannot find hit on array\n");
|
||||
printf(" -20 = unknown\n");
|
||||
printf("===========================================\n");
|
||||
|
||||
TH1F * hHit = new TH1F("hHit", "hit; hit-ID; count", 13, -11, 2);
|
||||
tree->Draw("hit>>hHit", "", "");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
cCheck->Modified();
|
||||
cCheck->Update();
|
||||
|
||||
if( outputCanvas ){
|
||||
TDatime dateTime;
|
||||
TString outPNGName = Form("Sim_%d%02d%02d_%06d.png", dateTime.GetYear(), dateTime.GetMonth(), dateTime.GetDay(), dateTime.GetTime());
|
||||
|
||||
cCheck->SaveAs(outPNGName);
|
||||
printf("%s\n", outPNGName.Data());
|
||||
|
||||
gROOT->ProcessLine(".q");
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
///============================================================
|
||||
///============================================================
|
||||
|
||||
double * FindRange(TString branch, TString gate, TTree * tree, double output[2]){
|
||||
tree->Draw(Form("%s>>temp1", branch.Data()), gate);
|
||||
TH1F * temp1 = (TH1F *) gROOT->FindObjectAny("temp1");
|
||||
|
||||
output[1] = temp1->GetXaxis()->GetXmax();
|
||||
output[0] = temp1->GetXaxis()->GetXmin();
|
||||
|
||||
delete temp1;
|
||||
return output;
|
||||
}
|
||||
|
||||
double ExtractNumber(int index, TMacro * macro){
|
||||
|
||||
TString field = macro->GetListOfLines()->At(index)->GetName();
|
||||
int pos = field.First('/');
|
||||
if( pos >= 0 ) field.Remove(pos);
|
||||
|
||||
return field.Atof();
|
||||
|
||||
}
|
||||
TString ExtractString(int index, TMacro * macro){
|
||||
|
||||
TString field = macro->GetListOfLines()->At(index)->GetName();
|
||||
|
||||
int pos = field.First('/');
|
||||
if( pos >= 0 ) field.Remove(pos);
|
||||
|
||||
return field;
|
||||
|
||||
}
|
||||
|
||||
vector<TString> StringToVector(TString str){
|
||||
|
||||
vector<TString> temp;
|
||||
|
||||
bool startFlag = false;
|
||||
bool endFlag = false;
|
||||
string jaja="";
|
||||
for(int i = 0; i < str.Length(); i++){
|
||||
|
||||
if( str[i] == '{' ) {
|
||||
startFlag = true;
|
||||
continue;
|
||||
}
|
||||
if( str[i] == ' '){
|
||||
continue;
|
||||
}
|
||||
if( startFlag && !endFlag){
|
||||
|
||||
if( str[i] == ',' ){
|
||||
temp.push_back(jaja);
|
||||
jaja="";
|
||||
continue;
|
||||
}
|
||||
|
||||
if( str[i] == '}') {
|
||||
temp.push_back(jaja);
|
||||
endFlag = true;
|
||||
continue;
|
||||
}
|
||||
jaja += str[i];
|
||||
|
||||
}
|
||||
}
|
||||
return temp;
|
||||
}
|
||||
|
||||
vector<int> intConvertor(vector<TString> arr){
|
||||
vector<int> out ;
|
||||
for( int i = 0 ; i < (int) arr.size(); i++){
|
||||
out.push_back( arr[i].Atoi());
|
||||
}
|
||||
return out;
|
||||
}
|
||||
vector<double> doubleConvertor(vector<TString> arr){
|
||||
vector<double> out ;
|
||||
for( int i = 0 ; i < (int) arr.size(); i++){
|
||||
out.push_back( arr[i].Atof());
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
plotID StringToPlotID(TString str){
|
||||
|
||||
if( str == "pEZ") return plotID::pEZ; /// 0
|
||||
if( str == "pRecoilXY") return plotID::pRecoilXY; /// 1
|
||||
if( str == "pThetaCM" ) return plotID::pThetaCM; /// 2
|
||||
if( str == "pExCal" ) return plotID::pExCal; /// 2
|
||||
if( str == "pArrayXY" ) return plotID::pArrayXY; /// 3
|
||||
if( str == "pInfo" ) return plotID::pInfo; /// 4
|
||||
if( str == "pElum1XY" ) return plotID::pElum1XY; /// 5
|
||||
if( str == "pRecoilXY1" ) return plotID::pRecoilXY1; /// 6
|
||||
if( str == "pRecoilXY2" ) return plotID::pRecoilXY2; /// 7
|
||||
if( str == "pTDiffZ" ) return plotID::pTDiffZ; /// 8
|
||||
if( str == "pRecoilRThetaCM" ) return plotID::pRecoilRThetaCM; /// 9
|
||||
if( str == "pRecoilRZ" ) return plotID::pRecoilRZ; /// 10
|
||||
if( str == "pEElum1R" ) return plotID::pEElum1R; /// 11
|
||||
if( str == "pRecoilRTR" ) return plotID::pRecoilRTR; /// 12
|
||||
if( str == "pThetaCM_Z" ) return plotID::pThetaCM_Z; /// 13
|
||||
if( str == "pElum1RThetaCM" ) return plotID::pElum1RThetaCM; /// 14
|
||||
|
||||
if( str == "pHitID" ) return plotID::pHitID; /// 13
|
||||
if( str == "pEmpty" ) return plotID::pEmpty ; /// 16
|
||||
|
||||
return plotID::pEmpty;
|
||||
}
|
|
@ -1,180 +0,0 @@
|
|||
#ifndef decay_h
|
||||
#define decay_h
|
||||
|
||||
#include "TVector3.h"
|
||||
|
||||
#include "../Cleopatra/ClassIsotope.h"
|
||||
#include "../Armory/ClassReactionConfig.h"
|
||||
|
||||
//=======================================================
|
||||
//#######################################################
|
||||
// Class for Particle Decay
|
||||
// B --> d + D
|
||||
// input : TLorentzVector, emitting particle
|
||||
// output : scattered TLorentzVector
|
||||
//=======================================================
|
||||
class Decay{
|
||||
public:
|
||||
Decay();
|
||||
~Decay();
|
||||
|
||||
double GetQValue() { return Q;}
|
||||
|
||||
double GetAngleChange(){
|
||||
TVector3 vD = PD.Vect();
|
||||
TVector3 vB = PB.Vect();
|
||||
vD.SetMag(1);
|
||||
vB.SetMag(1);
|
||||
double dot = vD.Dot(vB);
|
||||
return TMath::ACos(dot)*TMath::RadToDeg() ;
|
||||
}
|
||||
|
||||
double GetThetaCM() { return theta * TMath::RadToDeg();}
|
||||
|
||||
double GetCMMomentum(){ return k;}
|
||||
TLorentzVector GetDaugther_d() {return Pd;}
|
||||
TLorentzVector GetDaugther_D() {return PD;}
|
||||
|
||||
void SetMotherDaugther(Recoil recoil){
|
||||
|
||||
Isotope Mother(recoil.heavyA, recoil.heavyZ);
|
||||
Isotope Daugther_D(recoil.decayA, recoil.decayZ);
|
||||
Isotope Daugther_d(recoil.heavyA - recoil.decayA, recoil.heavyZ - recoil.decayZ);
|
||||
|
||||
zB = recoil.heavyZ;
|
||||
zD = recoil.decayZ;
|
||||
zd = recoil.heavyZ - recoil.decayZ;
|
||||
|
||||
mB = Mother.Mass;
|
||||
mD = Daugther_D.Mass;
|
||||
md = Daugther_d.Mass;
|
||||
|
||||
double Q = mB - mD - md;
|
||||
|
||||
printf("====== decay mode : %s --> %s + %s, Q = %.3f MeV \n", Mother.Name.c_str(), Daugther_d.Name.c_str(), Daugther_D.Name.c_str(), Q);
|
||||
|
||||
isMotherSet = true;
|
||||
|
||||
}
|
||||
|
||||
void SetMotherDaugther(int AB, int zB, int AD, int zD){
|
||||
Isotope Mother(AB, zB);
|
||||
Isotope Daugther_D(AD, zD);
|
||||
Isotope Daugther_d(AB-AD, zB-zD);
|
||||
|
||||
mB = Mother.Mass;
|
||||
mD = Daugther_D.Mass;
|
||||
md = Daugther_d.Mass;
|
||||
|
||||
double Q = mB - mD - md;
|
||||
|
||||
printf("====== decay mode : %s --> %s + %s, Q = %.3f MeV \n", Mother.Name.c_str(), Daugther_d.Name.c_str(), Daugther_D.Name.c_str(), Q);
|
||||
|
||||
isMotherSet = true;
|
||||
}
|
||||
|
||||
int CalDecay(TLorentzVector P_mother, double ExB, double ExD, double normOfReactionPlane = 0){
|
||||
if( !isMotherSet ) {
|
||||
return -1;
|
||||
}
|
||||
this->PB = P_mother;
|
||||
|
||||
double MB = mB + ExB; ///mother
|
||||
double MD = mD + ExD; ///Big_Daugther
|
||||
Q = MB - MD - md;
|
||||
if( Q < 0 ) {
|
||||
this->PD = this->PB;
|
||||
dTheta = TMath::QuietNaN();
|
||||
k = TMath::QuietNaN();
|
||||
return -2;
|
||||
}
|
||||
|
||||
//clear
|
||||
TLorentzVector temp(0,0,0,0);
|
||||
PD = temp;
|
||||
Pd = temp;
|
||||
|
||||
PD.SetUniqueID(zD);
|
||||
Pd.SetUniqueID(zd);
|
||||
|
||||
k = TMath::Sqrt((MB+MD+md)*(MB+MD-md)*(MB-MD+md)*(MB-MD-md))/2./MB;
|
||||
|
||||
//in mother's frame, assume isotropic decay
|
||||
theta = TMath::ACos(2 * gRandom->Rndm() - 1) ;
|
||||
|
||||
//for non isotropic decay, edit f1.
|
||||
//theta = TMath::ACos(f1->GetRandom());
|
||||
|
||||
double phi = TMath::TwoPi() * gRandom->Rndm();
|
||||
PD.SetE(TMath::Sqrt(mD * mD + k * k ));
|
||||
PD.SetPz(k);
|
||||
PD.SetTheta(theta);
|
||||
PD.SetPhi(phi);
|
||||
|
||||
Pd.SetE(TMath::Sqrt(md * md + k * k ));
|
||||
Pd.SetPz(k);
|
||||
Pd.SetTheta(theta + TMath::Pi());
|
||||
Pd.SetPhi(phi + TMath::Pi());
|
||||
|
||||
PD.RotateY(TMath::Pi()/2.);
|
||||
PD.RotateZ(normOfReactionPlane);
|
||||
|
||||
Pd.RotateY(TMath::Pi()/2.);
|
||||
Pd.RotateZ(normOfReactionPlane);
|
||||
|
||||
//Transform to Lab frame;
|
||||
TVector3 boost = PB.BoostVector();
|
||||
|
||||
PD.Boost(boost);
|
||||
Pd.Boost(boost);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
private:
|
||||
TLorentzVector PB, Pd, PD;
|
||||
|
||||
double mB, mD, md;
|
||||
double zB, zD, zd;
|
||||
double theta;
|
||||
|
||||
TF1 * f1;
|
||||
|
||||
bool isMotherSet;
|
||||
double Q;
|
||||
double k; // momentum in B-frame
|
||||
double dTheta; // change of angle
|
||||
};
|
||||
|
||||
Decay::Decay(){
|
||||
TLorentzVector temp(0,0,0,0);
|
||||
PB = temp;
|
||||
Pd = temp;
|
||||
PD = temp;
|
||||
|
||||
mB = TMath::QuietNaN();
|
||||
mD = TMath::QuietNaN();
|
||||
md = TMath::QuietNaN();
|
||||
|
||||
zB = 0;
|
||||
zD = 0;
|
||||
zd = 0;
|
||||
|
||||
theta = TMath::QuietNaN();
|
||||
|
||||
k = TMath::QuietNaN();
|
||||
|
||||
Q = TMath::QuietNaN();
|
||||
dTheta = TMath::QuietNaN();
|
||||
isMotherSet = false;
|
||||
|
||||
// f1 = new TF1("f1", "(1+ROOT::Math::legendre(2,x))/2.", -1, 1); //need to compile ROOT with -Dmathmore=ON
|
||||
f1 = new TF1("f1", "sin(x)", -1, 1);
|
||||
}
|
||||
|
||||
Decay::~Decay(){
|
||||
delete f1;
|
||||
}
|
||||
|
||||
|
||||
#endif
|
|
@ -1,551 +0,0 @@
|
|||
#ifndef HELIOS_Library_h
|
||||
#define HELIOS_Library_h
|
||||
|
||||
#include "TBenchmark.h"
|
||||
#include "TLorentzVector.h"
|
||||
#include "TVector3.h"
|
||||
#include "TMath.h"
|
||||
#include "TFile.h"
|
||||
#include "TTree.h"
|
||||
#include "TRandom.h"
|
||||
#include "TMacro.h"
|
||||
#include "TGraph.h"
|
||||
#include <vector>
|
||||
#include <fstream>
|
||||
|
||||
#include "../Armory/AnalysisLib.h"
|
||||
#include "../Armory/ClassDetGeo.h"
|
||||
#include "../Armory/ClassReactionConfig.h"
|
||||
|
||||
//=======================================================
|
||||
//#######################################################
|
||||
//Class for HELIOS
|
||||
//input Lorentz vector, detector configuration
|
||||
//output e, z, Ex, thetaCM, etc
|
||||
//=======================================================
|
||||
|
||||
struct trajectory{
|
||||
double theta, phi;
|
||||
double vt, vp; // tranvser and perpendicular velocity
|
||||
double rho; // orbit radius
|
||||
double z0, t0; // position cycle
|
||||
double x, y, z; // hit position
|
||||
double t; //actual orbit time;
|
||||
double R; //hit radius = sqrt(x^2+y^2);
|
||||
int detID, detRowID;
|
||||
int loop;
|
||||
double effLoop;
|
||||
|
||||
void PrintTrajectory(){
|
||||
printf("=====================\n");
|
||||
printf(" theta : %f deg\n", theta*TMath::RadToDeg());
|
||||
printf(" phi : %f deg\n", phi*TMath::RadToDeg());
|
||||
printf(" vt : %f mm/ns\n", vt);
|
||||
printf(" vp : %f mm/ns\n", vp);
|
||||
printf(" rho : %f mm\n", rho);
|
||||
printf(" z0 : %f mm\n", z0);
|
||||
printf(" t0 : %f ns\n", t0);
|
||||
printf("(x, y, z) : (%f, %f. %f) mm\n", x, y, z);
|
||||
printf(" R : %f mm\n", R);
|
||||
printf(" t : %f ns\n", t);
|
||||
printf(" effLoop : %f cycle\n", effLoop);
|
||||
printf(" Loop : %d cycle\n", loop);
|
||||
printf(" detRowID : %d \n", detRowID);
|
||||
printf(" detID : %d \n", detID);
|
||||
|
||||
}
|
||||
|
||||
void Clear(){
|
||||
theta = TMath::QuietNaN();
|
||||
phi = TMath::QuietNaN();
|
||||
vt = TMath::QuietNaN();
|
||||
vp = TMath::QuietNaN();
|
||||
rho = TMath::QuietNaN();
|
||||
z0 = TMath::QuietNaN();
|
||||
t0 = TMath::QuietNaN();
|
||||
x = TMath::QuietNaN();
|
||||
y = TMath::QuietNaN();
|
||||
z = TMath::QuietNaN();
|
||||
effLoop = TMath::QuietNaN();
|
||||
detID = -1;
|
||||
detRowID = -1;
|
||||
loop = -1;
|
||||
}
|
||||
};
|
||||
|
||||
class HELIOS{
|
||||
public:
|
||||
|
||||
HELIOS();
|
||||
HELIOS(std::string detGeoFile, unsigned short ID);
|
||||
~HELIOS();
|
||||
|
||||
void SetCoincidentWithRecoil(bool TorF){ this->isCoincidentWithRecoil = TorF;}
|
||||
bool GetCoincidentWithRecoil(){return this->isCoincidentWithRecoil;}
|
||||
bool SetDetectorGeometry(std::string filename, unsigned short ID);
|
||||
void SetBeamPosition(double x, double y) { xOff = x; yOff = y;}
|
||||
|
||||
void OverrideMagneticField(double BField);
|
||||
void OverrideFirstPos(double firstPos);
|
||||
void OverrideDetectorDistance(double perpDist);
|
||||
void OverrideDetectorFacing(bool isOutside);
|
||||
|
||||
int CheckDetAcceptance();
|
||||
int CalArrayHit(TLorentzVector Pb, bool debug = false);
|
||||
int CalRecoilHit(TLorentzVector PB);
|
||||
void CalTrajectoryPara(TLorentzVector P, bool isLightRecoil);
|
||||
|
||||
int GetNumberOfDetectorsInSamePos(){return array.rowDet;}
|
||||
double GetEnergy()const {return e;}
|
||||
double GetDetX() const {return detX;} // position in each detector, range from -1, 1
|
||||
|
||||
/// clockwise rotation for B-field along the z-axis, sign = 1.
|
||||
double XPos(double Zpos, double theta, double phi, double rho, int sign){
|
||||
if( TMath::IsNaN(Zpos) ) return TMath::QuietNaN();
|
||||
return rho * ( TMath::Sin( TMath::Tan(theta) * Zpos / rho - sign * phi ) + sign * TMath::Sin(phi) ) + xOff;
|
||||
}
|
||||
double YPos(double Zpos, double theta, double phi, double rho, int sign){
|
||||
if( TMath::IsNaN(Zpos) ) return TMath::QuietNaN();
|
||||
return rho * sign * (TMath::Cos( TMath::Tan(theta) * Zpos / rho - sign * phi ) - TMath::Cos(phi)) + yOff;
|
||||
}
|
||||
double RPos(double Zpos, double theta, double phi, double rho, int sign){
|
||||
if( TMath::IsNaN(Zpos) ) return TMath::QuietNaN();
|
||||
double x = XPos(Zpos, theta, phi, rho, sign) ;
|
||||
double y = YPos(Zpos, theta, phi, rho, sign) ;
|
||||
return sqrt(x*x+y*y);
|
||||
}
|
||||
|
||||
double GetXPos(double ZPos){ return TMath::IsNaN(ZPos) ? TMath::QuietNaN() : XPos( ZPos, orbitb.theta, orbitb.phi, orbitb.rho, detGeo.BfieldSign); }
|
||||
double GetYPos(double ZPos){ return TMath::IsNaN(ZPos) ? TMath::QuietNaN() : YPos( ZPos, orbitb.theta, orbitb.phi, orbitb.rho, detGeo.BfieldSign); }
|
||||
double GetR(double ZPos) { return TMath::IsNaN(ZPos) ? TMath::QuietNaN() : RPos( ZPos, orbitb.theta, orbitb.phi, orbitb.rho, detGeo.BfieldSign); }
|
||||
|
||||
double GetRecoilEnergy(){return eB;}
|
||||
double GetRecoilXPos(double ZPos){ return TMath::IsNaN(ZPos) ? TMath::QuietNaN() : XPos( ZPos, orbitB.theta, orbitB.phi, orbitB.rho, detGeo.BfieldSign); }
|
||||
double GetRecoilYPos(double ZPos){ return TMath::IsNaN(ZPos) ? TMath::QuietNaN() : YPos( ZPos, orbitB.theta, orbitB.phi, orbitB.rho, detGeo.BfieldSign); }
|
||||
double GetRecoilR(double ZPos) { return TMath::IsNaN(ZPos) ? TMath::QuietNaN() : RPos( ZPos, orbitB.theta, orbitB.phi, orbitB.rho, detGeo.BfieldSign); }
|
||||
|
||||
void PrintGeometry() const;
|
||||
|
||||
double GetBField() const {return detGeo.Bfield;}
|
||||
double GetDetRadius() const {return array.detPerpDist;}
|
||||
|
||||
trajectory GetTrajectory_b() const {return orbitb;}
|
||||
trajectory GetTrajectory_B() const {return orbitB;}
|
||||
|
||||
DetGeo GetDetectorGeometry() const {return detGeo;}
|
||||
Array GetArrayGeometry() const {return array;}
|
||||
Auxillary GetAuxGeometry() const {return aux;}
|
||||
|
||||
TString GetHitMessage() {return hitMessage;}
|
||||
TString GetAcceptanceMessage() { AcceptanceCodeToMsg(acceptanceCode); return acceptanceMsg;}
|
||||
|
||||
TString AcceptanceCodeToMsg(short code );
|
||||
|
||||
private:
|
||||
|
||||
DetGeo detGeo;
|
||||
Array array;
|
||||
Auxillary aux;
|
||||
|
||||
trajectory orbitb, orbitB;
|
||||
|
||||
double e,detX ; ///energy of light recoil, position X
|
||||
double rhoHit; /// radius of particle-b hit on recoil detector
|
||||
|
||||
double eB; ///energy of heavy recoil
|
||||
|
||||
bool isDetReady;
|
||||
|
||||
TString hitMessage;
|
||||
TString acceptanceMsg; //acceptance check
|
||||
short acceptanceCode;
|
||||
|
||||
double xOff, yOff; // beam position
|
||||
|
||||
bool overrideDetDistance;
|
||||
bool overrideFirstPos;
|
||||
bool isCoincidentWithRecoil;
|
||||
|
||||
const double c = 299.792458; //mm/ns
|
||||
|
||||
void Clear();
|
||||
|
||||
};
|
||||
|
||||
HELIOS::HELIOS(){
|
||||
Clear();
|
||||
}
|
||||
|
||||
HELIOS::HELIOS(std::string detGeoFile, unsigned short ID){
|
||||
Clear();
|
||||
SetDetectorGeometry(detGeoFile, ID);
|
||||
}
|
||||
|
||||
HELIOS::~HELIOS(){
|
||||
|
||||
}
|
||||
|
||||
void HELIOS::Clear(){
|
||||
|
||||
orbitb.Clear();
|
||||
orbitB.Clear();
|
||||
|
||||
e = TMath::QuietNaN();
|
||||
eB = TMath::QuietNaN();
|
||||
detX = TMath::QuietNaN();
|
||||
rhoHit = TMath::QuietNaN();
|
||||
|
||||
xOff = 0.0;
|
||||
yOff = 0.0;
|
||||
|
||||
isDetReady = false;
|
||||
|
||||
hitMessage = "";
|
||||
acceptanceMsg = "";
|
||||
acceptanceCode = 0;
|
||||
|
||||
overrideDetDistance = false;
|
||||
overrideFirstPos = false;
|
||||
isCoincidentWithRecoil = false;
|
||||
}
|
||||
|
||||
void HELIOS::OverrideMagneticField(double BField){
|
||||
this->detGeo.Bfield = BField;
|
||||
this->detGeo.BfieldSign = BField > 0 ? 1: -1;
|
||||
}
|
||||
|
||||
void HELIOS::OverrideFirstPos(double firstPos){
|
||||
overrideFirstPos = true;
|
||||
printf("------ Overriding FirstPosition to : %8.2f mm \n", firstPos);
|
||||
this->array.firstPos = firstPos;
|
||||
}
|
||||
|
||||
void HELIOS::OverrideDetectorDistance(double perpDist){
|
||||
overrideDetDistance = true;
|
||||
printf("------ Overriding Detector Distance to : %8.2f mm \n", perpDist);
|
||||
this->array.detPerpDist = perpDist;
|
||||
}
|
||||
|
||||
void HELIOS::OverrideDetectorFacing(bool isOutside){
|
||||
this->array.detFaceOut = isOutside;
|
||||
printf(" Detectors are facing %s\n", array.detFaceOut ? "outside": "inside" );
|
||||
}
|
||||
|
||||
bool HELIOS::SetDetectorGeometry(std::string filename, unsigned short ID){
|
||||
|
||||
if( detGeo.LoadDetectorGeo(filename, false)) {
|
||||
|
||||
array = detGeo.array[ID];
|
||||
aux = detGeo.aux[ID];
|
||||
isCoincidentWithRecoil = detGeo.aux[ID].isCoincident;
|
||||
isDetReady = true;
|
||||
|
||||
}else{
|
||||
printf("cannot read file %s.\n", filename.c_str());
|
||||
isDetReady = false;
|
||||
}
|
||||
|
||||
return isDetReady;
|
||||
}
|
||||
|
||||
void HELIOS::PrintGeometry() const{
|
||||
|
||||
printf("=====================================================\n");
|
||||
printf(" B-field : %8.2f T, %s\n", detGeo.Bfield, detGeo.Bfield > 0 ? "out of plan" : "into plan");
|
||||
printf(" Bore : %8.2f mm\n", detGeo.bore);
|
||||
printf("----------------------------------- Detector Position \n");
|
||||
array.Print();
|
||||
aux.Print();
|
||||
printf("=====================================================\n");
|
||||
|
||||
}
|
||||
|
||||
TString HELIOS::AcceptanceCodeToMsg(short code ){
|
||||
|
||||
switch(code){
|
||||
case 3 : acceptanceMsg = "try one more loop"; break;
|
||||
case 2 : acceptanceMsg = "hit less than the nearest array. increase loop"; break;
|
||||
case 1 : acceptanceMsg = "GOOD!! hit Array"; break;
|
||||
|
||||
case 0 : acceptanceMsg = "detector geometry incomplete."; break;
|
||||
case -1 : acceptanceMsg = "array at upstream, z is downstream."; break;
|
||||
case -2 : acceptanceMsg = "array at downstream, z is upstream."; break;
|
||||
case -3 : acceptanceMsg = "hit at the XY gap."; break;
|
||||
case -4 : acceptanceMsg = "hit more upstream than the array length"; break;
|
||||
case -5 : acceptanceMsg = "hit more downstream than the array length"; break;
|
||||
case -6 : acceptanceMsg = "hit blocker"; break;
|
||||
case -7 : acceptanceMsg = "hit array Z-gap"; break;
|
||||
|
||||
case -10 : acceptanceMsg = "rho is too big"; break;
|
||||
case -11 : acceptanceMsg = "rho is too small"; break;
|
||||
case -12 : acceptanceMsg = "light recoil blocked by recoil detector"; break;
|
||||
case -13 : acceptanceMsg = "more than 3 loops."; break;
|
||||
case -14 : acceptanceMsg = "heavy recoil does not hit recoil detector"; break;
|
||||
case -15 : acceptanceMsg = "det Row ID == -1"; break;
|
||||
default : acceptanceMsg = "unknown error."; break;
|
||||
}
|
||||
|
||||
return acceptanceMsg;
|
||||
|
||||
}
|
||||
|
||||
int HELIOS::CheckDetAcceptance(){
|
||||
|
||||
//CalArrayHit and CalRecoilHit must be done before.
|
||||
|
||||
if( isDetReady == false ) { acceptanceCode = 0; return acceptanceCode; }
|
||||
|
||||
// -1 ========= when recoil direction is not same side of array
|
||||
if( array.firstPos < 0 && orbitb.z > 0 ) {acceptanceCode = -1; return acceptanceCode;}
|
||||
|
||||
// -2 ========= when recoil direction is not same side of array
|
||||
if( array.firstPos > 0 && orbitb.z < 0 ) {acceptanceCode = -2; return acceptanceCode;}
|
||||
|
||||
// -11 ======== rho is too small
|
||||
if( 2 * orbitb.rho < array.detPerpDist ) { acceptanceCode = -11; return acceptanceCode;}
|
||||
|
||||
// -15 ========= if detRowID == -1, should be (2 * orbitb.rho < perpDist)
|
||||
if( orbitb.detRowID == -1 ) {acceptanceCode = -15; return acceptanceCode;}
|
||||
|
||||
// -10 =========== when rho is too big .
|
||||
if( array.detFaceOut && detGeo.bore < 2 * orbitb.rho) { acceptanceCode = -10; return acceptanceCode;}
|
||||
|
||||
// -14 ========== check particle-B hit radius on recoil dectector
|
||||
if( isCoincidentWithRecoil && orbitB.R > aux.outerRadius ) {acceptanceCode = -14; return acceptanceCode;}
|
||||
|
||||
//if( isCoincidentWithRecoil && (orbitB.R > rhoRecoilout || orbitB.R < rhoRecoilin) ) return -14;
|
||||
|
||||
// -12 ========= check is particle-b was blocked by recoil detector
|
||||
rhoHit = GetR(aux.detPos);
|
||||
if( orbitb.z > 0 && aux.detPos > 0 && orbitb.z > aux.detPos && rhoHit < aux.outerRadius ) { acceptanceCode = -12; return acceptanceCode;}
|
||||
if( orbitb.z < 0 && aux.detPos < 0 && orbitb.z < aux.detPos && rhoHit < aux.outerRadius ) { acceptanceCode = -12; return acceptanceCode;}
|
||||
|
||||
// -13 ========= not more than 3 loops
|
||||
if( orbitb.loop > 3 ) {acceptanceCode = -13; return acceptanceCode;}
|
||||
|
||||
// -3 ========= calculate the "y"-distance from detector center
|
||||
if( sqrt(orbitb.R*orbitb.R - array.detPerpDist * array.detPerpDist)> array.detWidth/2 ) { acceptanceCode = -3; return acceptanceCode;}
|
||||
|
||||
// -4, -5 ==== when zPos further the range of whole array, more loop would not save
|
||||
if( array.firstPos < 0 && orbitb.z < array.detPos[0] - array.detLength ) { acceptanceCode = -4; return acceptanceCode;}
|
||||
if( array.firstPos > 0 && orbitb.z > array.detPos[array.colDet-1] + array.detLength ) { acceptanceCode = -5; return acceptanceCode;}
|
||||
|
||||
// -6 ======== Hit on blacker
|
||||
if( array.blocker != 0 && array.firstPos > 0 && array.detPos[0] - array.blocker < orbitb.z && orbitb.z < array.detPos[0] ) {acceptanceCode = -6; return acceptanceCode;}
|
||||
if( array.blocker != 0 && array.firstPos < 0 && array.detPos[array.colDet-1] < orbitb.z && orbitb.z < array.detPos[array.colDet-1] + array.blocker ) { acceptanceCode = -6; return acceptanceCode;}
|
||||
|
||||
// 2 ====== when zPos less then the nearest position, more loop may hit
|
||||
int increaseLoopFlag = 0;
|
||||
if( array.firstPos < 0 && array.detPos[array.colDet-1] < orbitb.z ) increaseLoopFlag = 2;
|
||||
if( array.firstPos > 0 && array.detPos[0] > orbitb.z ) increaseLoopFlag = 2;
|
||||
if (increaseLoopFlag == 2 ) {
|
||||
orbitb.z += orbitb.z0;
|
||||
orbitb.effLoop += 1.0;
|
||||
orbitb.loop += 1;
|
||||
orbitb.t = orbitb.t0 * orbitb.effLoop;
|
||||
acceptanceCode = 2;
|
||||
return acceptanceCode;
|
||||
}
|
||||
|
||||
// 1 ======= check hit array z- position
|
||||
if( array.firstPos < 0 ){
|
||||
for( int i = 0; i < array.colDet; i++){
|
||||
if( array.detPos[i] - array.detLength <= orbitb.z && orbitb.z <= array.detPos[i]) {
|
||||
orbitb.detID = i;
|
||||
detX = ( orbitb.z - (array.detPos[i] + array.detLength/2 ))/ array.detLength * 2 ;// range from -1 , 1
|
||||
acceptanceCode = 1;
|
||||
return acceptanceCode;
|
||||
}
|
||||
}
|
||||
}else{
|
||||
for( int i = 0; i < array.colDet ; i++){
|
||||
if( array.detPos[i] <= orbitb.z && orbitb.z <= array.detPos[i] + array.detLength) {
|
||||
///printf(" %d | %f < z = %f < %f \n", i, array.detPos[i], orbitb.z, array.detPos[i]+length);
|
||||
orbitb.detID = i;
|
||||
detX = ( orbitb.z - (array.detPos[i] - array.detLength/2 ))/ array.detLength*2 ;// range from -1 , 1
|
||||
acceptanceCode = 1;
|
||||
return acceptanceCode;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// -7 ======== check hit array gap
|
||||
if( array.firstPos < 0 ){
|
||||
for( int i = 0; i < array.colDet-1 ; i++){
|
||||
if( array.detPos[i] < orbitb.z && orbitb.z < array.detPos[i+1] - array.detLength ) { acceptanceCode = -7; return acceptanceCode; }//increaseLoopFlag = 3;
|
||||
}
|
||||
}else{
|
||||
for( int i = 0; i < array.colDet-1 ; i++){
|
||||
if( array.detPos[i] + array.detLength < orbitb.z && orbitb.z < array.detPos[i+1] ) { acceptanceCode = -7; return acceptanceCode; }//increaseLoopFlag = 3;
|
||||
}
|
||||
}
|
||||
if (increaseLoopFlag == 3 ) {
|
||||
orbitb.z += orbitb.z0;
|
||||
orbitb.effLoop += 1.0;
|
||||
orbitb.loop += 1;
|
||||
orbitb.t = orbitb.t0 * orbitb.effLoop;
|
||||
acceptanceCode = 3;
|
||||
return acceptanceCode;
|
||||
}
|
||||
|
||||
acceptanceCode = -20 ;
|
||||
return acceptanceCode; // for unknown reason
|
||||
}
|
||||
|
||||
void HELIOS::CalTrajectoryPara(TLorentzVector P, bool isLightRecoil){
|
||||
|
||||
if( isLightRecoil ){
|
||||
orbitb.theta = P.Theta();
|
||||
orbitb.phi = P.Phi();
|
||||
orbitb.rho = P.Pt() / abs(detGeo.Bfield) / P.GetUniqueID() / c * 1000; //mm
|
||||
orbitb.vt = P.Beta() * TMath::Sin(P.Theta()) * c ; // mm / nano-second
|
||||
orbitb.vp = P.Beta() * TMath::Cos(P.Theta()) * c ; // mm / nano-second
|
||||
orbitb.t0 = TMath::TwoPi() * orbitb.rho / orbitb.vt; // nano-second
|
||||
orbitb.z0 = orbitb.vp * orbitb.t0;
|
||||
|
||||
orbitb.detID = -1;
|
||||
orbitb.detRowID = -1;
|
||||
|
||||
}else{
|
||||
orbitB.theta = P.Theta();
|
||||
orbitB.phi = P.Phi();
|
||||
orbitB.rho = P.Pt() / abs(detGeo.Bfield) / P.GetUniqueID() / c * 1000; //mm
|
||||
orbitB.vt = P.Beta() * TMath::Sin(P.Theta()) * c ; // mm / nano-second
|
||||
orbitB.vp = P.Beta() * TMath::Cos(P.Theta()) * c ; // mm / nano-second
|
||||
orbitB.t0 = TMath::TwoPi() * orbitB.rho / orbitB.vt; // nano-second
|
||||
orbitB.z0 = orbitB.vp * orbitB.t0;
|
||||
|
||||
orbitB.detID = -1;
|
||||
orbitB.detRowID = -1;
|
||||
}
|
||||
}
|
||||
|
||||
int HELIOS::CalArrayHit(TLorentzVector Pb, bool debug){
|
||||
|
||||
e = Pb.E() - Pb.M();
|
||||
detX = TMath::QuietNaN();
|
||||
rhoHit = TMath::QuietNaN();
|
||||
|
||||
CalTrajectoryPara(Pb, true);
|
||||
|
||||
int targetLoop = 1;
|
||||
int inOut = array.detFaceOut == true ? 1: 0; //1 = from Outside, 0 = from inside
|
||||
|
||||
if( debug ) {
|
||||
printf("===================================\n");
|
||||
printf("theta : %f deg, phi : %f deg \n", orbitb.theta * TMath::RadToDeg(), orbitb.phi * TMath::RadToDeg());
|
||||
printf("z0: %f mm, rho : %f mm \n", orbitb.z0, orbitb.rho);
|
||||
printf(" inOut : %d = %s \n", inOut, inOut == 1 ? "Out" : "in");
|
||||
printf(" z range : %.2f - %.2f \n", detGeo.zMin, detGeo.zMax);
|
||||
printf(" B-field sign : %d\n", detGeo.BfieldSign);
|
||||
printf("-----------------------------------\n");
|
||||
}
|
||||
|
||||
std::vector<double> zPossible;
|
||||
std::vector<int> dID; //detRowID
|
||||
|
||||
int iStart = ( detGeo.BfieldSign == 1 ? 0 : -array.rowDet );
|
||||
int iEnd = ( detGeo.BfieldSign == 1 ? 2 * array.rowDet : array.rowDet );
|
||||
for( int i = iStart; i < iEnd ; i++){
|
||||
|
||||
double phiD = TMath::TwoPi()/array.rowDet * i ;
|
||||
double dphi = orbitb.phi - phiD;
|
||||
double aEff = array.detPerpDist - (xOff * TMath::Cos(phiD) + yOff * TMath::Sin(phiD));
|
||||
double hahaha = asin( aEff/ orbitb.rho - detGeo.BfieldSign * sin(dphi));
|
||||
|
||||
int n = 2*targetLoop + inOut;
|
||||
|
||||
double zP = orbitb.z0 /TMath::TwoPi() * ( detGeo.BfieldSign * dphi + n * TMath::Pi() + pow(-1, n) * hahaha );
|
||||
|
||||
if( debug ) {
|
||||
double xP = GetXPos(zP) ;
|
||||
double yP = GetYPos(zP) ;
|
||||
printf("phiD: %4.0f, dphi: %6.1f, mod(pi): %6.1f, Loop : %9.5f, zHit : %8.3f mm, (x,y) = (%7.2f, %7.2f) \n",
|
||||
phiD * TMath::RadToDeg(),
|
||||
(orbitb.phi-phiD) * TMath::RadToDeg(),
|
||||
fmod(orbitb.phi-phiD, TMath::Pi())*TMath::RadToDeg(),
|
||||
zP/orbitb.z0, zP, xP, yP );
|
||||
}
|
||||
|
||||
///Selection
|
||||
if( !TMath::IsNaN(zP) && 0 < zP/orbitb.z0 && TMath::Max(0, targetLoop-1) < zP/orbitb.z0 && zP/orbitb.z0 < targetLoop ) {
|
||||
zPossible.push_back(zP);
|
||||
dID.push_back(i);
|
||||
}
|
||||
}
|
||||
|
||||
if( debug ) printf("-----------------------------------\n");
|
||||
double dMin = 1;
|
||||
for( int i = 0; i < (int) zPossible.size(); i++){
|
||||
|
||||
double dd = abs(zPossible[i]/orbitb.z0 - (targetLoop - (1-inOut)));
|
||||
|
||||
if( debug ) printf(" %d | zP : %8.3f mm; loop : %9.5f ", i, zPossible[i], zPossible[i]/orbitb.z0);
|
||||
|
||||
if( dd < dMin) {
|
||||
orbitb.z = zPossible[i];
|
||||
dMin = dd;
|
||||
orbitb.effLoop = zPossible[i]/orbitb.z0;
|
||||
orbitb.loop = TMath::Ceil(orbitb.effLoop);
|
||||
orbitb.detRowID = (12+dID[i])%4;
|
||||
orbitb.t = orbitb.t0 * orbitb.effLoop;
|
||||
|
||||
double phiD = TMath::TwoPi()/array.rowDet * dID[i] ;
|
||||
double dphi = orbitb.phi - phiD ;
|
||||
|
||||
if( debug ) {
|
||||
// Check is in or out
|
||||
double hitDir = cos( orbitb.z/orbitb.z0 * TMath::TwoPi() - detGeo.BfieldSign * dphi );
|
||||
printf(" hitDir : %4.1f ", hitDir);
|
||||
if( ( inOut == 1 && hitDir > 0 ) || (inOut == 0 && hitDir < 0 ) ) {
|
||||
printf(" != %f ", array.detPerpDist);
|
||||
orbitb.z = TMath::QuietNaN();
|
||||
orbitb.loop = -1;
|
||||
orbitb.detRowID = -1;
|
||||
hitMessage = "wrong direction.";
|
||||
return - 2;
|
||||
}
|
||||
|
||||
// this must be false, otherwise, calculation error
|
||||
double xPos = GetXPos(orbitb.z ) ;
|
||||
double yPos = GetYPos(orbitb.z ) ;
|
||||
double a = xPos * cos(phiD) + yPos * sin(phiD);
|
||||
printf(" a : %f ", a);
|
||||
if( abs(a - array.detPerpDist) > 0.01) {
|
||||
printf(" != %f ", array.detPerpDist);
|
||||
orbitb.z = TMath::QuietNaN();
|
||||
orbitb.loop = -1;
|
||||
orbitb.detRowID = -1;
|
||||
hitMessage = "not on the detector plan.";
|
||||
return -3;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(debug) printf("\n");
|
||||
}
|
||||
|
||||
// calculate x, y, R
|
||||
orbitb.x = GetXPos(orbitb.z) ;
|
||||
orbitb.y = GetYPos(orbitb.z) ;
|
||||
orbitb.R = GetR(orbitb.z);
|
||||
|
||||
hitMessage = "successful hit.";
|
||||
return 1; // return 1 when OK
|
||||
}
|
||||
|
||||
int HELIOS::CalRecoilHit(TLorentzVector PB){
|
||||
|
||||
CalTrajectoryPara(PB, false);
|
||||
|
||||
orbitB.z = aux.detPos;
|
||||
orbitB.x = GetRecoilXPos(aux.detPos) ;
|
||||
orbitB.y = GetRecoilYPos(aux.detPos) ;
|
||||
orbitB.R = GetRecoilR(aux.detPos);
|
||||
orbitB.effLoop = orbitB.z/orbitB.z0;
|
||||
orbitB.t = orbitB.t0 * orbitB.effLoop ;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,301 +0,0 @@
|
|||
#ifndef knockout_h
|
||||
#define knockout_h
|
||||
|
||||
|
||||
//=======================================================
|
||||
//#######################################################
|
||||
// Class for Knockout Reaction
|
||||
// A(a,12)B, A = B + b, a->1, b->2
|
||||
// incident particle is A
|
||||
// the calculation: 1) go to A's rest frame
|
||||
// 2) calculate the b = A - B
|
||||
// 3) go to CM frame
|
||||
//=======================================================
|
||||
class Knockout{
|
||||
public:
|
||||
Knockout();
|
||||
~Knockout();
|
||||
|
||||
void SetA(int A, int Z){
|
||||
Isotope temp(A,Z);
|
||||
mA = temp.Mass;
|
||||
AA = A;
|
||||
ZA = Z;
|
||||
nameA = temp.Name;
|
||||
}
|
||||
|
||||
void SetExA(double Ex){
|
||||
this->ExA = Ex;
|
||||
}
|
||||
|
||||
void Seta(int A, int Z){
|
||||
Isotope temp(A,Z);
|
||||
ma = temp.Mass;
|
||||
Aa = A;
|
||||
Za = Z;
|
||||
m1 = ma;
|
||||
A1 = A;
|
||||
Z1 = Z;
|
||||
namea = temp.Name;
|
||||
name1 = temp.Name;
|
||||
}
|
||||
|
||||
void Set2(int A, int Z){
|
||||
Isotope temp(A,Z);
|
||||
m2 = temp.Mass;
|
||||
A2 = A;
|
||||
Z2 = Z;
|
||||
name2 = temp.Name;
|
||||
|
||||
AB = AA + Aa - A1 - A2;
|
||||
ZB = ZA + Za - Z1 - Z2;
|
||||
Isotope temp2(AB,ZB);
|
||||
mB0 = temp2.Mass;
|
||||
nameB = temp2.Name;
|
||||
|
||||
}
|
||||
|
||||
void SetBSpk(double S, double kb, double thetab, double phib){
|
||||
this->S = S;
|
||||
AB = AA + Aa - A1 - A2;
|
||||
ZB = ZA + Za - Z1 - Z2;
|
||||
Isotope temp(AB,ZB);
|
||||
mB0 = temp.Mass;
|
||||
nameB = temp.Name;
|
||||
this->kb = kb;
|
||||
this->thetab = thetab;
|
||||
this->phib = phib;
|
||||
|
||||
mB = mA + ExA - m2 + S;
|
||||
|
||||
ExB = mB - mB0;
|
||||
|
||||
if( ExB < 0 && !isOverRideExNegative ){
|
||||
printf(" seperation energy is too small. \n");
|
||||
}
|
||||
}
|
||||
|
||||
void OverRideExNegative(bool YN){
|
||||
isOverRideExNegative = YN;
|
||||
}
|
||||
|
||||
TString GetReactionName(){
|
||||
TString rName;
|
||||
|
||||
TString normInv;
|
||||
if( isNormalKinematics ){
|
||||
normInv = "Normal Kinematics";
|
||||
}else{
|
||||
normInv = "Inverse Kinematics";
|
||||
}
|
||||
|
||||
rName.Form("%s(%s,%s%s)%s, %s", nameA.c_str(), namea.c_str(), name1.c_str(), name2.c_str(), nameB.c_str(), normInv.Data());
|
||||
|
||||
return rName;
|
||||
}
|
||||
|
||||
void SetIncidentEnergyAngle(double KEA, double theta, double phi){
|
||||
this->KEA = KEA;
|
||||
this->thetaIN = theta;
|
||||
this->phiIN = phi;
|
||||
}
|
||||
|
||||
void CalIncidentChannel(bool isNormalKinematics);
|
||||
void CalReactionConstant(bool isNormalKinematics);
|
||||
void Event(double thetaCM, double phCM);
|
||||
|
||||
double GetMass_A(){return mA;}
|
||||
double GetMass_a(){return ma;}
|
||||
double GetMass_b(){return mb;}
|
||||
double GetMass_B(){return mB;}
|
||||
double GetMass_Bgs(){return mB0;}
|
||||
double GetMass_1(){return m1;}
|
||||
double GetMass_2(){return m2;}
|
||||
|
||||
TLorentzVector GetPA(){return PA;}
|
||||
TLorentzVector GetPa(){return Pa;}
|
||||
TLorentzVector GetPb(){return Pb;}
|
||||
TLorentzVector GetPB(){return PB;}
|
||||
TLorentzVector GetP1(){return P1;}
|
||||
TLorentzVector GetP2(){return P2;}
|
||||
|
||||
double GetMomentumbNN(){return p;}
|
||||
double GetReactionBeta(){return beta;}
|
||||
double GetReactionGamma(){return gamma;}
|
||||
double GetNNTotalEnergy(){return Etot;}
|
||||
|
||||
double GetNNTotalKE() {return Etot - mb - ma;}
|
||||
double GetQValue() {return mA + ExA - m2 - mB;}
|
||||
double GetMaxExB() {return Etot - mb - mB0;}
|
||||
|
||||
private:
|
||||
int AA, Aa, A1, A2, AB;
|
||||
int ZA, Za, Z1, Z2, ZB;
|
||||
double mA, ma, m1, m2, mB, mB0, mb;
|
||||
string nameA, namea, name1, name2, nameB;
|
||||
|
||||
double S; // separation energy
|
||||
double kb; // momentum of b
|
||||
double thetab, phib;// direction of b
|
||||
|
||||
TLorentzVector PA, Pa, P1, P2, PB, Pb; // lab
|
||||
|
||||
double KEA, thetaIN, phiIN;
|
||||
double T;
|
||||
|
||||
double k, beta, gamma, Etot, p; // reaction constant, in NN frame
|
||||
double ExA, ExB;
|
||||
|
||||
bool isNormalKinematics;
|
||||
bool isOverRideExNegative;
|
||||
|
||||
};
|
||||
|
||||
Knockout::Knockout(){
|
||||
TLorentzVector temp(0,0,0,0);
|
||||
|
||||
PA = temp;
|
||||
Pa = temp;
|
||||
P1 = temp;
|
||||
P2 = temp;
|
||||
PB = temp;
|
||||
Pb = temp;
|
||||
|
||||
SetA(12,6);
|
||||
Seta(1,1);
|
||||
Set2(1,1);
|
||||
|
||||
SetBSpk(1000, 0, 0, 0);
|
||||
SetIncidentEnergyAngle(10, 0, 0);
|
||||
|
||||
ExA = 0;
|
||||
|
||||
isNormalKinematics = false;
|
||||
isOverRideExNegative = false;
|
||||
}
|
||||
|
||||
Knockout::~Knockout(){
|
||||
|
||||
}
|
||||
|
||||
void Knockout::CalIncidentChannel(bool isNormalKinematics){
|
||||
if( ExB < 0 && !isOverRideExNegative) return;
|
||||
|
||||
this->isNormalKinematics = isNormalKinematics;
|
||||
|
||||
if(!isNormalKinematics){
|
||||
//===== construct Lab frame 4-momentum
|
||||
this->T = KEA * AA;
|
||||
double kA = TMath::Sqrt(TMath::Power(mA + ExA + T, 2) - (mA + ExA) * (mA + ExA));
|
||||
PA.SetXYZM(0, 0, kA, mA + ExA);
|
||||
PA.RotateY(thetaIN);
|
||||
PA.RotateZ(phiIN);
|
||||
|
||||
Pa.SetXYZM(0,0,0,ma);
|
||||
|
||||
}else{
|
||||
//===== construct 4-momentum
|
||||
this->T = KEA * Aa;
|
||||
double ka = TMath::Sqrt(TMath::Power(ma + T, 2) - (ma) * (ma));
|
||||
Pa.SetXYZM(0, 0, ka, ma);
|
||||
Pa.RotateY(thetaIN);
|
||||
Pa.RotateZ(phiIN);
|
||||
|
||||
PA.SetXYZM(0, 0, 0, mA + ExA);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void Knockout::CalReactionConstant(bool isNormalKinematics){
|
||||
if( ExB < 0 && !isOverRideExNegative) return;
|
||||
|
||||
this->isNormalKinematics = isNormalKinematics;
|
||||
|
||||
CalIncidentChannel(isNormalKinematics);
|
||||
|
||||
if(!isNormalKinematics){
|
||||
|
||||
//===== change to A's rest frame
|
||||
TVector3 bA = PA.BoostVector();
|
||||
PA.Boost(-bA);
|
||||
|
||||
//===== constructe bounded nucleus b
|
||||
PB.SetXYZM(0, 0, -kb, mB);
|
||||
PB.RotateY(thetab);
|
||||
PB.RotateZ(phib);
|
||||
|
||||
Pb = PA - PB;
|
||||
mb = Pb.M();
|
||||
|
||||
//===== change to Lab frame
|
||||
Pb.Boost(bA);
|
||||
PA.Boost(bA);
|
||||
PB.Boost(bA);
|
||||
|
||||
}else{
|
||||
|
||||
//===== constructe bounded nucleus b
|
||||
PB.SetXYZM(0, 0, -kb, mB);
|
||||
PB.RotateY(thetab);
|
||||
PB.RotateZ(phib);
|
||||
|
||||
Pb = PA - PB;
|
||||
mb = Pb.M();
|
||||
|
||||
}
|
||||
|
||||
//====== reaction constant
|
||||
k = (Pa+Pb).P();
|
||||
double E = (Pa+Pb).E();
|
||||
beta = (Pa+Pb).Beta();
|
||||
gamma = 1 / TMath::Sqrt(1- beta * beta);
|
||||
Etot = TMath::Sqrt(TMath::Power(E,2) - k * k);
|
||||
p = TMath::Sqrt( (Etot*Etot - TMath::Power(m1 + m2,2)) * (Etot*Etot - TMath::Power(m1 - m2 ,2)) ) / 2 / Etot;
|
||||
|
||||
//if( TMath::IsNaN(p) ){
|
||||
// printf(" Mc: %f, m1+m2: %f, kb:%f, thetab:%f, phib:%f\n", Etot, m1+m2, kb, thetab, phib);
|
||||
//}
|
||||
|
||||
}
|
||||
|
||||
void Knockout::Event(double thetaCM, double phiCM){
|
||||
if( ExB < 0 && !isOverRideExNegative ) return;
|
||||
|
||||
//===== construct Pcm
|
||||
TLorentzVector Pc = Pb + Pa;
|
||||
TVector3 bc = Pc.BoostVector();
|
||||
|
||||
TLorentzVector Pac = Pa;
|
||||
Pac.Boost(-bc);
|
||||
TVector3 va = Pac.Vect();
|
||||
|
||||
TLorentzVector Pbc = Pb;
|
||||
Pbc.Boost(-bc);
|
||||
TVector3 vb = Pbc.Vect();
|
||||
|
||||
//--- from P1
|
||||
TVector3 v1 = va;
|
||||
v1.SetMag(p);
|
||||
|
||||
TVector3 u1 = va.Orthogonal();
|
||||
v1.Rotate(thetaCM, u1);
|
||||
v1.Rotate(phiCM + TMath::PiOver2(), va); // somehow, the calculation turn the vector 90 degree.
|
||||
|
||||
TLorentzVector P1c;
|
||||
P1c.SetVectM(v1, m1);
|
||||
|
||||
//--- from P2
|
||||
TLorentzVector P2c;
|
||||
P2c.SetVectM(-v1, m2);
|
||||
|
||||
//---- to Lab Frame
|
||||
P1 = P1c;
|
||||
P1.Boost(bc);
|
||||
P2 = P2c;
|
||||
P2.Boost(bc);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif
|
|
@ -1,502 +0,0 @@
|
|||
#ifndef SimPlotter_h
|
||||
#define SimPlotter_h
|
||||
|
||||
#include <TTree.h>
|
||||
#include <TH2F.h>
|
||||
#include <TH1F.h>
|
||||
#include <TString.h>
|
||||
#include <TCanvas.h>
|
||||
#include <TArc.h>
|
||||
#include <TLegend.h>
|
||||
#include <TLine.h>
|
||||
#include <TLatex.h>
|
||||
#include "../Armory/ClassDetGeo.h"
|
||||
#include "../Armory/ClassReactionConfig.h"
|
||||
#include "../Cleopatra/ClassIsotope.h"
|
||||
|
||||
enum plotID { pEZ, /// 0
|
||||
pRecoilXY, /// 1
|
||||
pRecoilXY1, /// 2
|
||||
pRecoilXY2, /// 3
|
||||
pRecoilRZ, /// 4
|
||||
pRecoilRTR, /// 5
|
||||
pTDiffZ, /// 6
|
||||
pThetaCM, /// 7
|
||||
pThetaCM_Z, /// 8
|
||||
pExCal, /// 9
|
||||
pRecoilRThetaCM, /// 10
|
||||
pArrayXY, /// 11
|
||||
pInfo, /// 12
|
||||
pElum1XY, /// 13
|
||||
pEElum1R, /// 14
|
||||
pElum1RThetaCM, /// 15
|
||||
pEmpty }; /// 16
|
||||
|
||||
class Plotter{
|
||||
public:
|
||||
Plotter(TTree * tree, short reactionID, std::string reactionName, DetGeo detGeo, ExcitedEnergies exList, TString gate, std::vector<plotID> padPlotID);
|
||||
~Plotter();
|
||||
|
||||
void SetRanges(double zMin, double zMax, double eMax, double elumMax, double thetaCM_Max){
|
||||
this->zRange[0] = zMin;
|
||||
this->zRange[1] = zMax;
|
||||
this->eMax = eMax;
|
||||
this->elumMax = elumMax;
|
||||
this->thetaCM_Max = thetaCM_Max;
|
||||
}
|
||||
void SetCanvas( int colSize, int rowSize , int padSize, std::vector<plotID> padPlotID ){
|
||||
cCheck = new TCanvas(Form("SimChecker-%d", rID),
|
||||
"Simulation Checker",
|
||||
200 * rID,
|
||||
200 * rID,
|
||||
padSize*colSize,
|
||||
padSize*rowSize);
|
||||
|
||||
if(cCheck->GetShowEditor() ) cCheck->ToggleEditor();
|
||||
if(cCheck->GetShowToolBar() )cCheck->ToggleToolBar();
|
||||
cCheck->Divide(colSize,rowSize);
|
||||
|
||||
numPad = colSize * rowSize;
|
||||
}
|
||||
|
||||
void Plot();
|
||||
|
||||
private:
|
||||
|
||||
TTree * tree;
|
||||
DetGeo detGeo;
|
||||
std::string reactionName;
|
||||
short rID;
|
||||
ExcitedEnergies exList;
|
||||
int numEx;
|
||||
TString gate;
|
||||
TString gateTrue;
|
||||
std::vector<plotID> padPlotID;
|
||||
|
||||
double zRange[2];
|
||||
double eMax;
|
||||
double recoilOut;
|
||||
double recoilIn;
|
||||
double elumMax;
|
||||
double thetaCM_Max;
|
||||
|
||||
int numPad;
|
||||
TCanvas * cCheck;
|
||||
TH2F * hez;
|
||||
TH2F * hArrayXY;
|
||||
TH2F * heavyXY;
|
||||
TH2F * hElum1XY;
|
||||
TH1F ** hThetaCM;
|
||||
TH1F * hExCal;
|
||||
TH1F * hHit;
|
||||
TH2F * hRecoilXY1;
|
||||
TH2F * hRecoilXY2;
|
||||
TH2F * hTDiffZ;
|
||||
TH2F * hRecoilRThetaCM;
|
||||
TH2F * hRecoilRZ;
|
||||
TH2F * hEElum1Rho;
|
||||
TH2F * hRecoilRTR;
|
||||
TH2F * hElum1RThetaCM;
|
||||
TH2F * hThetaCM_Z;
|
||||
|
||||
Isotope heavy;
|
||||
|
||||
std::vector<double> FindRange(TString branch);
|
||||
|
||||
};
|
||||
|
||||
Plotter::Plotter(TTree * tree, short reactionID, std::string reactionName, DetGeo detGeo, ExcitedEnergies exList, TString gate, std::vector<plotID> padPlotID){
|
||||
this->tree = tree;
|
||||
this->rID = reactionID;
|
||||
this->reactionName = reactionName;
|
||||
this->exList = exList;
|
||||
numEx = this->exList.ExList.size();
|
||||
|
||||
this->detGeo = detGeo;
|
||||
|
||||
this->recoilOut = detGeo.aux[rID].outerRadius;
|
||||
this->recoilIn = detGeo.aux[rID].innerRadius;
|
||||
|
||||
this->gate = gate;
|
||||
this->gateTrue = gate + Form(" && rID == %d", rID);
|
||||
|
||||
this->padPlotID = padPlotID;
|
||||
|
||||
cCheck = nullptr;
|
||||
hez = nullptr;
|
||||
hArrayXY = nullptr;
|
||||
heavyXY = nullptr;
|
||||
hElum1XY = nullptr;
|
||||
hThetaCM = nullptr;
|
||||
hExCal = nullptr;
|
||||
hHit = nullptr;
|
||||
hRecoilXY1 = nullptr;
|
||||
hRecoilXY2 = nullptr;
|
||||
hTDiffZ = nullptr;
|
||||
hRecoilRThetaCM = nullptr;
|
||||
hRecoilRZ = nullptr;
|
||||
hEElum1Rho = nullptr;
|
||||
hRecoilRTR = nullptr;
|
||||
hElum1RThetaCM = nullptr;
|
||||
hThetaCM_Z = nullptr;
|
||||
|
||||
std::size_t pos1 = reactionName.find(")") + 1;
|
||||
std::size_t pos2 = reactionName.find(" ", pos1);
|
||||
std::string result = reactionName.substr(pos1, pos2 - pos1);
|
||||
|
||||
pos1 = result.find("{") + 1;
|
||||
pos2 = result.find("}", pos1);
|
||||
|
||||
std::string massHeavy = result.substr(pos1, pos2-pos1);
|
||||
std::string symHeavy = result.substr(pos2+1);
|
||||
|
||||
heavy.SetIsoByName(massHeavy + symHeavy);
|
||||
|
||||
}
|
||||
|
||||
Plotter::~Plotter(){
|
||||
|
||||
if( cCheck ) delete cCheck;
|
||||
if( hez ) delete hez;
|
||||
if( hArrayXY ) delete hArrayXY;
|
||||
if( heavyXY ) delete heavyXY;
|
||||
if( hElum1XY ) delete hElum1XY;
|
||||
if( hExCal ) delete hExCal;
|
||||
if( hRecoilXY1 ) delete hRecoilXY1;
|
||||
if( hRecoilXY2 ) delete hRecoilXY2;
|
||||
if( hTDiffZ ) delete hTDiffZ;
|
||||
if( hRecoilRThetaCM ) delete hRecoilRThetaCM;
|
||||
if( hRecoilRZ ) delete hRecoilRZ;
|
||||
if( hEElum1Rho ) delete hEElum1Rho;
|
||||
if( hRecoilRTR ) delete hRecoilRTR;
|
||||
if( hElum1RThetaCM ) delete hElum1RThetaCM;
|
||||
if( hThetaCM_Z ) delete hThetaCM_Z;
|
||||
|
||||
if(hThetaCM ){
|
||||
for( int i = 0; i < numEx; i++) delete [] hThetaCM[i];
|
||||
delete [] hThetaCM;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
inline void Plotter::Plot(){
|
||||
|
||||
for( int i = 1; i <= numPad; i++ ){
|
||||
cCheck->cd(i);
|
||||
plotID pID = padPlotID[i-1];
|
||||
|
||||
//&======================================= 0
|
||||
if( pID == pEZ){
|
||||
hez = new TH2F(Form("hez%d",rID), //need unqie name in root.
|
||||
Form("e-z [gated] @ %5.0f mm; z [mm]; e [MeV]", detGeo.array[rID].firstPos),
|
||||
400, zRange[0], zRange[1],
|
||||
400, 0, eMax);
|
||||
|
||||
tree->Draw(Form("e:z>>hez%d", rID), gateTrue , "colz");
|
||||
}
|
||||
|
||||
//&======================================= 1
|
||||
if( pID == pRecoilXY ){
|
||||
heavyXY = new TH2F(Form("heavyXY%d",rID),
|
||||
Form("RecoilXY [gated] @ %4.0f mm; X [mm]; Y [mm]", detGeo.aux[rID].detPos ),
|
||||
400, -recoilOut, recoilOut,
|
||||
400, -recoilOut, recoilOut);
|
||||
tree->Draw(Form("yRecoil:xRecoil>>heavyXY%d", rID), gateTrue, "colz");
|
||||
|
||||
// printf("%f, %f\n", recoilOut, recoilIn);
|
||||
TArc * detArc1 = new TArc(0, 0, recoilOut);
|
||||
detArc1->SetLineColor(kBlue-8);
|
||||
detArc1->SetFillStyle(0);
|
||||
detArc1->Draw("same");
|
||||
TArc * detArc2 = new TArc(0, 0, recoilIn);
|
||||
detArc2->SetLineColor(kBlue-8);
|
||||
detArc2->SetFillStyle(0);
|
||||
detArc2->Draw("same");
|
||||
|
||||
// if( reactionConfig.beamX != 0. || reactionConfig.beamY != 0. ){
|
||||
// TArc * arc = new TArc(reactionConfig.beamX, reactionConfig.beamY, 1);
|
||||
// arc->SetLineColor(2);
|
||||
// detArc1->SetFillStyle(0);
|
||||
// arc->Draw("same");
|
||||
// }
|
||||
}
|
||||
|
||||
//&======================================= 2
|
||||
if( pID == pThetaCM ){
|
||||
hThetaCM = new TH1F *[numEx];
|
||||
TLegend * legend = new TLegend(0.8,0.2,0.99,0.8);
|
||||
double maxCount = 0;
|
||||
for( int h = 0; h < numEx; h++){
|
||||
hThetaCM[h] = new TH1F(Form("hThetaCM%d-%d", rID, h), Form("thetaCM [gated] (ExID=%d); thetaCM [deg]; count", h), 200, 0, thetaCM_Max);
|
||||
hThetaCM[h]->SetLineColor(h+1);
|
||||
hThetaCM[h]->SetFillColor(h+1);
|
||||
hThetaCM[h]->SetFillStyle(3000+h);
|
||||
tree->Draw(Form("thetaCM>>hThetaCM%d-%d", rID, h), gateTrue + Form("&& ExID==%d", h), "");
|
||||
legend->AddEntry(hThetaCM[h], Form("Ex=%5.1f MeV", exList.ExList[h].Ex));
|
||||
double max = hThetaCM[h]->GetMaximum();
|
||||
if( max > maxCount ) maxCount = max;
|
||||
}
|
||||
|
||||
for( int h = 0; h < numEx; h++){
|
||||
hThetaCM[h]->GetYaxis()->SetRangeUser(1, maxCount * 1.2);
|
||||
if( h == 0 ) {
|
||||
hThetaCM[h]->Draw();
|
||||
}else{
|
||||
hThetaCM[h]->Draw("same");
|
||||
}
|
||||
}
|
||||
legend->Draw();
|
||||
}
|
||||
|
||||
//&======================================= 3
|
||||
if( pID == pExCal ){
|
||||
double exMin = 9999;
|
||||
double exMax = -1;
|
||||
for( size_t k = 0 ; k < exList.ExList.size(); k++){
|
||||
double kuku = exList.ExList[k].Ex;
|
||||
if( kuku > exMax ) exMax = kuku;
|
||||
if( kuku < exMin ) exMin = kuku;
|
||||
}
|
||||
|
||||
double exPadding = (exMax - exMin) < 1 ? 1 : (exMax - exMin) * 0.3;
|
||||
|
||||
exMin = exMin - exPadding ;
|
||||
exMax = exMax + exPadding ;
|
||||
|
||||
hExCal = new TH1F(Form("hExCal%d",rID),
|
||||
Form("calculated Ex [gated]; Ex [MeV]; count / %.2f keV", (exMax-exMin)/400.*1000),
|
||||
400, exMin, exMax);
|
||||
tree->Draw(Form("ExCal>>hExCal%d", rID), gateTrue, "");
|
||||
|
||||
|
||||
double Sn = heavy.CalSp(0,1);
|
||||
double Sp = heavy.CalSp(1,0);
|
||||
double Sa = heavy.CalSp2(4,2);
|
||||
double S2n = heavy.CalSp(0, 2);
|
||||
|
||||
printf("======= Heavy recoil: %s \n", heavy.Name.c_str());
|
||||
printf("Sn : %6.2f MeV/u \n", Sn);
|
||||
printf("Sp : %6.2f MeV/u \n", Sp);
|
||||
printf("Sa : %6.2f MeV/u \n", Sa);
|
||||
printf("S2n : %6.2f MeV/u \n", S2n);
|
||||
|
||||
double yMax = hExCal->GetMaximum();
|
||||
TLatex * text = new TLatex();
|
||||
text->SetTextFont(82);
|
||||
text->SetTextSize(0.06);
|
||||
|
||||
if( Sn < exMax ) {TLine * lineSn = new TLine(Sn, 0, Sn, yMax); lineSn->SetLineColor(2); lineSn->Draw(""); text->SetTextColor(2); text->DrawLatex(Sn, yMax*0.9, "S_{n}");}
|
||||
if( Sp < exMax ) {TLine * lineSp = new TLine(Sp, 0, Sp, yMax); lineSp->SetLineColor(4); lineSp->Draw("same"); text->SetTextColor(4); text->DrawLatex(Sp, yMax*0.9, "S_{p}");}
|
||||
if( Sa < exMax ) {TLine * lineSa = new TLine(Sa, 0, Sa, yMax); lineSa->SetLineColor(6); lineSa->Draw("same"); text->SetTextColor(6); text->DrawLatex(Sa, yMax*0.9, "S_{a}");}
|
||||
if( S2n < exMax ) {TLine * lineS2n = new TLine(S2n, 0, S2n, yMax); lineS2n->SetLineColor(8); lineS2n->Draw("same"); text->SetTextColor(8); text->DrawLatex(S2n, yMax*0.9, "S_{2n}");}
|
||||
|
||||
}
|
||||
|
||||
//&======================================= 4
|
||||
if( pID == pArrayXY ){
|
||||
|
||||
hArrayXY = new TH2F(Form("hArrayXY%d", rID),
|
||||
"Array-XY [gated]; X [mm]; Y [mm]",
|
||||
400, -detGeo.array[rID].detPerpDist*1.5, detGeo.array[rID].detPerpDist*1.5,
|
||||
400, -detGeo.array[rID].detPerpDist*1.5, detGeo.array[rID].detPerpDist*1.5);
|
||||
tree->Draw(Form("yArray:xArray>>hArrayXY%d", rID), gateTrue, "colz");
|
||||
}
|
||||
|
||||
//&======================================= 5
|
||||
if( pID == pInfo ){
|
||||
TLatex text;
|
||||
text.SetNDC();
|
||||
text.SetTextFont(82);
|
||||
text.SetTextSize(0.06);
|
||||
text.SetTextColor(2);
|
||||
|
||||
text.DrawLatex(0., 0.9, reactionName.c_str());
|
||||
text.DrawLatex(0., 0.8, detGeo.Bfield > 0 ? "out of plan" : "into plan");
|
||||
text.SetTextColor(1);
|
||||
text.DrawLatex(0., 0.7, "gate:");
|
||||
|
||||
text.SetTextColor(2);
|
||||
//check gate text length, if > 30, break by "&&"
|
||||
int ll = gate.Length();
|
||||
if( ll > 30 ) {
|
||||
std::vector<std::string> strList = AnalysisLib::SplitStr( (std::string) gate.Data(), "&&");
|
||||
for( int i = 0; i < strList.size(); i++){
|
||||
text.DrawLatex(0., 0.6 - 0.05*i, (TString) strList[i]);
|
||||
}
|
||||
}else{
|
||||
text.DrawLatex(0., 0.6, gate);
|
||||
}
|
||||
|
||||
// if( reactionConfig.beamX != 0.0 || reactionConfig.beamY != 0.0 ){
|
||||
// text.DrawLatex(0.0, 0.1, Form("Bema pos: (%4.1f, %4.1f) mm", reactionConfig.beamX, reactionConfig.beamY));
|
||||
// }
|
||||
}
|
||||
|
||||
//&======================================= 6
|
||||
if( pID == pElum1XY ){
|
||||
hElum1XY = new TH2F(Form("hElum1XY%d", rID),
|
||||
Form("Elum-1 XY [gated] @ %.0f mm ; X [mm]; Y [mm]", detGeo.aux[rID].elumPos1),
|
||||
400, -elumMax, elumMax,
|
||||
400, -elumMax, elumMax);
|
||||
tree->Draw(Form("yElum1:xElum1>>hElum1XY%d", rID), gateTrue, "colz");
|
||||
|
||||
double count = hElum1XY->GetEntries();
|
||||
if( count < 2000. ) {
|
||||
hElum1XY->SetMarkerStyle(7);
|
||||
if( count < 500. ) hElum1XY->SetMarkerStyle(3);
|
||||
hElum1XY->Draw("scat");
|
||||
}
|
||||
}
|
||||
|
||||
//&======================================= 7
|
||||
if( pID == pRecoilXY1 ){
|
||||
TH2F * hRecoilXY1 = new TH2F(Form("hRecoilXY1-%d", rID),
|
||||
Form("RecoilXY-1 [gated] @ %4.0f mm; X [mm]; Y [mm]", detGeo.aux[rID].detPos1 ),
|
||||
400, -detGeo.aux[rID].outerRadius, detGeo.aux[rID].outerRadius,
|
||||
400, -detGeo.aux[rID].outerRadius, detGeo.aux[rID].outerRadius);
|
||||
tree->Draw(Form("yRecoil1:xRecoil1>>hRecoilXY1-%d", rID), gateTrue, "colz");
|
||||
}
|
||||
|
||||
//&======================================= 8
|
||||
if( pID == pRecoilXY2 ){
|
||||
hRecoilXY2 = new TH2F(Form("hRecoilXY2=%d", rID),
|
||||
Form("RecoilXY-2 [gated] @ %4.0f mm; X [mm]; Y [mm]", detGeo.aux[rID].detPos2 ),
|
||||
400, -detGeo.aux[rID].outerRadius, detGeo.aux[rID].outerRadius,
|
||||
400, -detGeo.aux[rID].outerRadius, detGeo.aux[rID].outerRadius);
|
||||
tree->Draw(Form("yRecoil2:xRecoil2>>hRecoilXY2-%d", rID), gate, "colz");
|
||||
}
|
||||
|
||||
//&======================================= 9
|
||||
if( pID == pTDiffZ ){
|
||||
std::vector<double> tDiffRange = FindRange("t-tB");
|
||||
hTDiffZ = new TH2F(Form("hTDiffZ%d", rID),
|
||||
"time(Array) - time(Recoil) vs Z [gated]; z [mm]; time diff [ns]",
|
||||
400, zRange[0], zRange[1],
|
||||
400, tDiffRange[0], tDiffRange[1]);
|
||||
tree->Draw(Form("t - tB : z >> hTDiffZ%d", rID), gateTrue, "colz");
|
||||
}
|
||||
|
||||
//&======================================= 10
|
||||
if( pID == pRecoilRThetaCM ){
|
||||
hRecoilRThetaCM = new TH2F(Form("hRecoilRThetaCM%d", rID),
|
||||
"RecoilR - thetaCM [gated]; thetaCM [deg]; RecoilR [mm]",
|
||||
400, 0, 60,
|
||||
400, 0, detGeo.aux[rID].outerRadius);
|
||||
tree->Draw(Form("rhoRecoil:thetaCM>>hRecoilRThetaCM%d", rID), gateTrue, "colz");
|
||||
}
|
||||
|
||||
//&======================================= 11
|
||||
if( pID == pRecoilRZ ){
|
||||
hRecoilRZ = new TH2F(Form("hRecoilRZ%d", rID),
|
||||
"RecoilR - Z [gated]; z [mm]; RecoilR [mm]",
|
||||
400, zRange[0], zRange[1],
|
||||
400,0, detGeo.aux[rID].outerRadius);
|
||||
tree->Draw(Form("rhoRecoil:z>>hRecoilRZ%d", rID), gateTrue, "colz");
|
||||
}
|
||||
|
||||
//&======================================= 12
|
||||
if( pID == pEElum1R ){
|
||||
hEElum1Rho = new TH2F(Form("hEElum1Rho%d", rID),
|
||||
"Elum-1 E-R [gated]; R[mm]; Energy[MeV]",
|
||||
400, 0, elumMax,
|
||||
400, 0, eMax);
|
||||
tree->Draw(Form("Tb:rhoElum1>>hEElum1Rho%d", rID), gateTrue, "colz");
|
||||
}
|
||||
|
||||
//&======================================= 13
|
||||
if( pID == pRecoilRTR ){
|
||||
std::vector<double> recoilERange = FindRange("TB");
|
||||
hRecoilRTR = new TH2F(Form("hRecoilRTR%d", rID),
|
||||
"RecoilR - recoilE [gated]; recoil Energy [MeV]; RecoilR [mm]",
|
||||
500, recoilERange[0], recoilERange[1],
|
||||
500, 0, detGeo.aux[rID].outerRadius);
|
||||
tree->Draw(Form("rhoRecoil:TB>>hRecoilRTR%d", rID), gateTrue, "colz");
|
||||
}
|
||||
|
||||
//&======================================= 14
|
||||
if( pID == pThetaCM_Z ){
|
||||
hThetaCM_Z = new TH2F(Form("hThetaCM_Z%d", rID),
|
||||
"ThetaCM vs Z ; Z [mm]; thetaCM [deg]",
|
||||
400, zRange[0], zRange[1],
|
||||
400, 0, thetaCM_Max);
|
||||
tree->Draw(Form("thetaCM:z>>hThetaCM_Z%d", rID), gateTrue,"col");
|
||||
}
|
||||
|
||||
//&======================================= 15
|
||||
if( pID == pElum1RThetaCM){
|
||||
int angBin = 400;
|
||||
|
||||
hElum1RThetaCM = new TH2F(Form("hElum1RThetaCM%d", rID),
|
||||
"Elum-1 rho vs ThetaCM [gated]; thatCM [deg]; Elum- rho [mm]",
|
||||
angBin, 0, thetaCM_Max,
|
||||
400, 0, elumMax);
|
||||
tree->Draw(Form("rhoElum1:thetaCM>>hElum1RThetaCM%d", rID), gateTrue, "colz");
|
||||
|
||||
TH1F * htemp = (TH1F *) hElum1RThetaCM->ProjectionX("htemp");
|
||||
|
||||
double rel = (thetaCM_Max)*1.0/angBin;
|
||||
printf("angular resolution : %f deg \n", rel);
|
||||
|
||||
std::vector<double> xList;
|
||||
double old_y = 0;
|
||||
for( int i = 1; i <= angBin; i++){
|
||||
double y = htemp->GetBinContent(i);
|
||||
if( old_y == 0 && y > 0) xList.push_back(htemp->GetBinCenter(i));
|
||||
if( old_y > 0 && y == 0 ) xList.push_back(htemp->GetBinCenter(i));
|
||||
old_y = y;
|
||||
}
|
||||
|
||||
printf("list of gaps :\n");
|
||||
for( int i = 0; i < (int) xList.size(); i+=2){
|
||||
printf("%d | %.3f - %.3f deg\n", i, xList[i], xList[i+1]);
|
||||
}
|
||||
|
||||
TF1 f1("f1", "sin(x)");
|
||||
double acceptance = 0;
|
||||
double err1 = 0;
|
||||
double err2 = 0;
|
||||
for( int i = 0; i < (int) xList.size(); i += 2 ){
|
||||
acceptance += f1.Integral(xList[i] * TMath::DegToRad(), xList[i+1] * TMath::DegToRad() ) * TMath::TwoPi();
|
||||
err1 += f1.Integral((xList[i]-rel) * TMath::DegToRad(), (xList[i+1] + rel) * TMath::DegToRad() ) * TMath::TwoPi();
|
||||
err2 += f1.Integral((xList[i]+rel) * TMath::DegToRad(), (xList[i+1] - rel) * TMath::DegToRad() ) * TMath::TwoPi();
|
||||
}
|
||||
printf("acceptance = %f sr +- %f \n", acceptance, (err1-err2)/2);
|
||||
|
||||
TLatex text;
|
||||
text.SetTextFont(82);
|
||||
text.SetTextSize(0.06);
|
||||
text.SetTextColor(2);
|
||||
text.SetTextAngle(90);
|
||||
|
||||
for( int i = 0; i < (int) xList.size(); i++){
|
||||
text.DrawLatex(xList[i], elumMax/2, Form("%.2f", xList[i]));
|
||||
}
|
||||
|
||||
text.SetNDC();
|
||||
text.SetTextAngle(0);
|
||||
text.DrawLatex(0.15, 0.15, Form("accp. = %.2f(%.2f) msr", acceptance * 1000., (err1-err2)*1000./2));
|
||||
|
||||
delete htemp;
|
||||
|
||||
}
|
||||
|
||||
}///===== end of pad loop
|
||||
|
||||
}
|
||||
|
||||
std::vector<double> Plotter::FindRange(TString branch){
|
||||
|
||||
tree->Draw(Form("%s>>temp1", branch.Data()), gateTrue);
|
||||
TH1F * temp1 = (TH1F *) gROOT->FindObjectAny("temp1");
|
||||
|
||||
std::vector<double> output;
|
||||
if( temp1 != nullptr){
|
||||
output.push_back( temp1->GetXaxis()->GetXmax() );
|
||||
output.push_back( temp1->GetXaxis()->GetXmin() );
|
||||
delete temp1;
|
||||
}
|
||||
return output;
|
||||
}
|
||||
|
||||
|
||||
#endif
|
|
@ -1,202 +0,0 @@
|
|||
#ifndef targetScattering_h
|
||||
#define targetScattering_h
|
||||
|
||||
#include <vector>
|
||||
#include <fstream>
|
||||
#include <string>
|
||||
|
||||
#include "../Armory/AnalysisLib.h"
|
||||
|
||||
//=======================================================
|
||||
//#######################################################
|
||||
// Class for multi-scattering of the beam inside target
|
||||
// using SRIM to generate stopping power
|
||||
// input : TLorentzVector, data_files
|
||||
// output : scattered TLorentzVector
|
||||
//=======================================================
|
||||
class TargetScattering{
|
||||
|
||||
public:
|
||||
TargetScattering();
|
||||
~TargetScattering();
|
||||
|
||||
double GetKE0(){return KE0;}
|
||||
double GetKE() {return KE;}
|
||||
double GetKELoss() {return KE0-KE;}
|
||||
double GetDepth() {return depth;}
|
||||
double GetPathLength() {return length;}
|
||||
|
||||
void LoadStoppingPower(std::string file);
|
||||
|
||||
void SetTarget(double density, double depth){
|
||||
this->density = density;
|
||||
this->depth = depth;
|
||||
isTargetSet = true;
|
||||
//printf("===== Target, density: %f g/cm3, depth: %f um \n", density, depth * 1e+4 );
|
||||
}
|
||||
|
||||
TLorentzVector Scattering(TLorentzVector P){
|
||||
double mass = P.M();
|
||||
KE0 = (P.E() - mass);
|
||||
KE = KE0;
|
||||
double theta = P.Theta();
|
||||
this->length = TMath::Abs(depth/TMath::Cos(theta));
|
||||
//printf("------- theta: %f deg, length: %f um, KE: %f MeV \n", theta * TMath::RadToDeg(), this->length * 1e+4, KE);
|
||||
|
||||
//integrate the energy loss within the depth of A
|
||||
double dx = length/100.; // in cm
|
||||
double x = 0;
|
||||
double densityUse = density;
|
||||
if( unitID == 0 ) densityUse = 1.;
|
||||
do{
|
||||
//assume the particle will not be stopped
|
||||
//printf(" x: %f, KE: %f, S: %f \n", x, KE, gA->Eval(KE));
|
||||
KE = KE - densityUse * gA->Eval(KE) * 10 * dx ; // factor 10, convert MeV/cm -> MeV/cm
|
||||
|
||||
//angular Straggling, assume (Lateral Straggling)/(Projected range)
|
||||
|
||||
|
||||
x = x + dx;
|
||||
}while(x < length && KE > 0 );
|
||||
|
||||
//printf(" depth: %f cm = %f um, KE : %f -> %f MeV , dE = %f MeV \n", depth, depth * 1e+4, KE0, KE, KE0 - KE);
|
||||
double newk = 0;
|
||||
|
||||
TLorentzVector Pnew;
|
||||
TVector3 vb(0,0,0);
|
||||
|
||||
if( KE < 0 ) {
|
||||
KE = 0.0; // somehow, when KE == 0 , the program has problem to rotate the 4-vector
|
||||
}else{
|
||||
newk = TMath::Sqrt(TMath::Power(mass+KE,2) - mass * mass);
|
||||
vb = P.Vect();
|
||||
vb.SetMag(newk);
|
||||
}
|
||||
Pnew.SetVectM(vb,mass);
|
||||
|
||||
return Pnew;
|
||||
}
|
||||
|
||||
private:
|
||||
bool isTargetSet;
|
||||
double density; // density [mg/cm2]
|
||||
int unitID; // 0 = MeV /mm or keV/um , 1 = MeV / (ug/cm2)
|
||||
|
||||
double depth; // depth in target [cm]
|
||||
double length; // total path length in target [cm]
|
||||
double KE0, KE;
|
||||
|
||||
TGraph * gA; // stopping power of A, b, B, in unit of MeV/(mg/cm2)
|
||||
TGraph * gB; // projection range [nm]
|
||||
TGraph * gC; // parallel Straggling [nm]
|
||||
TGraph * gD; // perpendicular Straggling [nm]
|
||||
|
||||
};
|
||||
|
||||
inline TargetScattering::TargetScattering(){
|
||||
isTargetSet = false;
|
||||
density = 1; // mg/cm2
|
||||
unitID = 0;
|
||||
KE0 = 0;
|
||||
KE = 0;
|
||||
depth = 0;
|
||||
length = 0;
|
||||
gA = NULL;
|
||||
gB = NULL;
|
||||
gC = NULL;
|
||||
gD = NULL;
|
||||
}
|
||||
|
||||
inline TargetScattering::~TargetScattering(){
|
||||
delete gA;
|
||||
}
|
||||
|
||||
inline void TargetScattering::LoadStoppingPower(std::string filename){
|
||||
|
||||
printf("loading Stopping power: %s.", filename.c_str());
|
||||
|
||||
std::ifstream file;
|
||||
file.open(filename.c_str());
|
||||
|
||||
std::vector<double> energy;
|
||||
std::vector<double> stopping;
|
||||
std::vector<double> projRange;
|
||||
std::vector<double> paraStraggling;
|
||||
std::vector<double> prepStraggling;
|
||||
|
||||
if( file.is_open() ){
|
||||
printf("... OK\n");
|
||||
char lineChar[16635];
|
||||
std::string line;
|
||||
while( !file.eof() ){
|
||||
file.getline(lineChar, 16635, '\n');
|
||||
line = lineChar;
|
||||
|
||||
size_t found = line.find("Target Density");
|
||||
if( found != std::string::npos ){
|
||||
printf(" %s\n", line.c_str());
|
||||
}
|
||||
|
||||
found = line.find("Stopping Units =");
|
||||
if( found != std::string::npos){
|
||||
printf(" %s\n", line.c_str());
|
||||
if( line.find("MeV / mm") != std::string::npos ) {
|
||||
unitID = 0;
|
||||
}else if( line.find("keV / micron") != std::string::npos ){
|
||||
unitID = 0;
|
||||
}else if( line.find("MeV / (mg/cm2)") != std::string::npos ) {
|
||||
unitID = 1;
|
||||
}else{
|
||||
printf("please using MeV/mm, keV/um, or MeV/(mg/cm2) \n");
|
||||
}
|
||||
}
|
||||
|
||||
size_t foundkeV = line.find("keV ");
|
||||
size_t foundMeV = line.find("MeV ");
|
||||
size_t foundGeV = line.find("GeV ");
|
||||
if ( foundkeV != std::string::npos || foundMeV != std::string::npos || foundGeV != std::string::npos ){
|
||||
std::vector<std::string> haha = AnalysisLib::SplitStr(line, " ");
|
||||
//for( int i = 0 ; i < (int) haha.size()-1; i++){
|
||||
// printf("%d,%s|", i, haha[i].c_str());
|
||||
//}
|
||||
//printf("\n");
|
||||
|
||||
found = haha[0].find("keV"); if( found != std::string::npos ) energy.push_back(atof(haha[0].substr(0, found).c_str()) * 0.001);
|
||||
found = haha[0].find("MeV"); if( found != std::string::npos ) energy.push_back(atof(haha[0].substr(0, found).c_str()) * 1.);
|
||||
found = haha[0].find("GeV"); if( found != std::string::npos ) energy.push_back(atof(haha[0].substr(0, found).c_str()) * 1000.);
|
||||
|
||||
double a = atof(haha[1].c_str());
|
||||
double b = atof(haha[2].c_str());
|
||||
stopping.push_back(a+b);
|
||||
|
||||
found = haha[3].find("A") ; if( found != std::string::npos ) projRange.push_back(atof(haha[3].substr(0, found).c_str()) * 0.1);
|
||||
found = haha[3].find("um"); if( found != std::string::npos ) projRange.push_back(atof(haha[3].substr(0, found).c_str()) * 1000.);
|
||||
found = haha[3].find("mm"); if( found != std::string::npos ) projRange.push_back(atof(haha[3].substr(0, found).c_str()) * 1e6);
|
||||
|
||||
found = haha[4].find("A") ; if( found != std::string::npos ) paraStraggling.push_back(atof(haha[4].substr(0, found).c_str()) * 0.1);
|
||||
found = haha[4].find("um"); if( found != std::string::npos ) paraStraggling.push_back(atof(haha[4].substr(0, found).c_str()) * 1e3);
|
||||
found = haha[4].find("mm"); if( found != std::string::npos ) paraStraggling.push_back(atof(haha[4].substr(0, found).c_str()) * 1e6);
|
||||
|
||||
found = haha[5].find("A") ; if( found != std::string::npos ) prepStraggling.push_back(atof(haha[5].substr(0, found).c_str()) * 0.1);
|
||||
found = haha[5].find("um"); if( found != std::string::npos ) prepStraggling.push_back(atof(haha[5].substr(0, found).c_str()) * 1e3);
|
||||
found = haha[5].find("mm"); if( found != std::string::npos ) prepStraggling.push_back(atof(haha[5].substr(0, found).c_str()) * 1e6);
|
||||
|
||||
//printf(" %f, %f, %f, %f, %f \n", energy.back(), stopping.back(), projRange.back(), paraStraggling.back(), prepStraggling.back());
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
}else{
|
||||
printf("... fail\n");
|
||||
}
|
||||
|
||||
gA = new TGraph(energy.size(), &energy[0], &stopping[0]);
|
||||
|
||||
gB = new TGraph(energy.size(), &energy[0], &projRange[0]);
|
||||
gC = new TGraph(energy.size(), &energy[0], ¶Straggling[0]);
|
||||
gD = new TGraph(energy.size(), &energy[0], &prepStraggling[0]);
|
||||
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,593 +0,0 @@
|
|||
#ifndef Transfer_h
|
||||
#define Transfer_h
|
||||
|
||||
#include "utility"
|
||||
|
||||
#include "ClassIsotope.h"
|
||||
#include "../Armory/AnalysisLib.h"
|
||||
#include "../Armory/ClassReactionConfig.h"
|
||||
|
||||
#include "TLorentzVector.h"
|
||||
#include "TMath.h"
|
||||
#include "TF1.h"
|
||||
#include "TMacro.h"
|
||||
|
||||
//=======================================================
|
||||
//#######################################################
|
||||
// Class for Transfer Reaction
|
||||
// reaction notation A(a,b)B
|
||||
// A = incident particle
|
||||
// a = target
|
||||
// b = light scattered particle
|
||||
// B = heavy scattered particle
|
||||
//=======================================================
|
||||
class TransferReaction {
|
||||
public:
|
||||
TransferReaction(){Inititization();};
|
||||
TransferReaction(ReactionConfig config, unsigned short ID = 0);
|
||||
TransferReaction(std::string configFile, unsigned short ID = 0);
|
||||
TransferReaction(TMacro configMarco, unsigned short ID = 0);
|
||||
TransferReaction(int beamA, int beamZ,
|
||||
int targetA, int targetZ,
|
||||
int recoilA, int recoilZ, float beamEnergy_AMeV);
|
||||
|
||||
~TransferReaction();
|
||||
|
||||
void SetA(int A, int Z, double Ex = 0);
|
||||
void Seta(int A, int Z);
|
||||
void Setb(int A, int Z);
|
||||
void SetB(int A, int Z);
|
||||
void SetIncidentEnergyAngle(double KEA, double theta, double phi);
|
||||
|
||||
void SetReactionFromReactionConfigClass(ReactionConfig reactConfigClassObject, unsigned short ID = 0);
|
||||
void SetReactionFromFile(std::string configFile, unsigned short ID = 0);
|
||||
void SetReactionFromTMacro(TMacro configMacro, unsigned short ID = 0);
|
||||
void SetReactionSimple(int beamA, int beamZ,
|
||||
int targetA, int targetZ,
|
||||
int recoilA, int recoilZ, float beamEnergy_AMeV);
|
||||
|
||||
void SetExA(double Ex);
|
||||
void SetExB(double Ex);
|
||||
|
||||
TString GetReactionName() const;
|
||||
TString GetReactionName_Latex();
|
||||
|
||||
ReactionConfig GetRectionConfig() { return config;}
|
||||
Recoil GetRecoil() { return recoil;}
|
||||
ExcitedEnergies * GetExList() { return &exList;}
|
||||
|
||||
double GetMass_A() const {return mA + ExA;}
|
||||
double GetMass_a() const {return ma;}
|
||||
double GetMass_b() const {return mb;}
|
||||
double GetMass_B() const {return mB + ExB;}
|
||||
|
||||
double GetCMTotalKE() {return Etot - mA - ma;}
|
||||
double GetQValue() {return mA + ExA + ma - mb - mB - ExB;}
|
||||
double GetMaxExB() {return Etot - mb - mB;}
|
||||
|
||||
TLorentzVector GetPA() const {return PA;}
|
||||
TLorentzVector GetPa() const {return Pa;}
|
||||
TLorentzVector GetPb() const {return Pb;}
|
||||
TLorentzVector GetPB() const {return PB;}
|
||||
|
||||
void PrintFourVectors() const;
|
||||
void PrintReaction(bool withEx = true) const;
|
||||
|
||||
double CalkCM(double ExB); //momentum at CM frame
|
||||
void CalReactionConstant();
|
||||
std::pair<double, double> CalExThetaCM(double e, double z, double Bfield, double a);
|
||||
void Event(double thetaCM_rad, double phiCM_rad);
|
||||
|
||||
double GetMomentumbCM() {return p;}
|
||||
double GetReactionBeta() {return beta;}
|
||||
double GetReactionGamma() {return gamma;}
|
||||
double GetCMTotalEnergy() {return Etot;}
|
||||
double GetEZSlope(double BField) {return 299.792458 * recoil.lightZ * abs(BField) / TMath::TwoPi() * beta / 1000.;} // MeV/mm
|
||||
|
||||
|
||||
void CreateExDistribution();
|
||||
int GetRandomExID(){
|
||||
if( exDistribution ) {
|
||||
return exDistribution->GetRandom();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
double GetRandomEx(){
|
||||
if( exDistribution ) {
|
||||
int exID = exDistribution->GetRandom();
|
||||
return exList.ExList[exID].Ex;
|
||||
}
|
||||
return TMath::QuietNaN();
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
ExcitedEnergies exList;
|
||||
Recoil recoil;
|
||||
ReactionConfig config;
|
||||
|
||||
std::string nameA, namea, nameb, nameB;
|
||||
double thetaIN, phiIN;
|
||||
double mA, ma, mb, mB;
|
||||
|
||||
double TA, T; // TA = KE of A pre u, T = total energy
|
||||
double ExA, ExB;
|
||||
|
||||
bool isReady;
|
||||
bool isBSet;
|
||||
|
||||
double k; // CM Boost momentum
|
||||
double beta, gamma; //CM boost beta
|
||||
double Etot;
|
||||
double p; // CM frame momentum of b, B
|
||||
double slope; // slope of the
|
||||
|
||||
TLorentzVector PA, Pa, Pb, PB;
|
||||
|
||||
TString format(TString name);
|
||||
|
||||
void Inititization();
|
||||
|
||||
TF1 * exDistribution;
|
||||
|
||||
static double exDistFunc(Double_t *x, Double_t * par){
|
||||
return par[(int) x[0]];
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
TransferReaction::TransferReaction(ReactionConfig config, unsigned short ID){
|
||||
Inititization();
|
||||
|
||||
SetA(config.beamA, config.beamZ);
|
||||
Seta(config.targetA, config.targetZ);
|
||||
|
||||
SetExA(config.beamEx);
|
||||
|
||||
recoil = config.recoil[ID];
|
||||
exList = config.exList[ID];
|
||||
|
||||
Setb(recoil.lightA, recoil.lightZ);
|
||||
SetB(recoil.heavyA, recoil.heavyZ);
|
||||
SetIncidentEnergyAngle(config.beamEnergy, 0, 0);
|
||||
|
||||
CalReactionConstant();
|
||||
|
||||
}
|
||||
|
||||
TransferReaction::TransferReaction(std::string configFile, unsigned short ID){
|
||||
Inititization();
|
||||
SetReactionFromFile(configFile, ID);
|
||||
}
|
||||
|
||||
TransferReaction::TransferReaction(TMacro configMarco, unsigned short ID){
|
||||
Inititization();
|
||||
SetReactionFromTMacro(configMarco, ID);
|
||||
}
|
||||
|
||||
TransferReaction::TransferReaction(int beamA, int beamZ,
|
||||
int targetA, int targetZ,
|
||||
int recoilA, int recoilZ,
|
||||
float beamEnergy_AMeV){
|
||||
Inititization();
|
||||
SetReactionSimple(beamA, beamZ,
|
||||
targetA, targetZ,
|
||||
recoilA, recoilZ,
|
||||
beamEnergy_AMeV);
|
||||
}
|
||||
|
||||
void TransferReaction::Inititization(){
|
||||
|
||||
thetaIN = 0.;
|
||||
phiIN = 0.;
|
||||
SetA(12, 6, 0);
|
||||
Seta(2,1);
|
||||
Setb(1,1);
|
||||
SetB(13,6);
|
||||
TA = 6;
|
||||
T = TA * config.beamA;
|
||||
|
||||
exDistribution = nullptr;
|
||||
|
||||
ExA = 0;
|
||||
ExB = 0;
|
||||
|
||||
CalReactionConstant();
|
||||
|
||||
TLorentzVector temp (0,0,0,0);
|
||||
PA = temp;
|
||||
Pa = temp;
|
||||
Pb = temp;
|
||||
PB = temp;
|
||||
|
||||
}
|
||||
|
||||
TransferReaction::~TransferReaction(){
|
||||
delete exDistribution;
|
||||
}
|
||||
|
||||
void TransferReaction::SetA(int A, int Z, double Ex){
|
||||
Isotope temp (A, Z);
|
||||
mA = temp.Mass;
|
||||
config.beamA = A;
|
||||
config.beamZ = Z;
|
||||
ExA = Ex;
|
||||
nameA = temp.Name;
|
||||
isReady = false;
|
||||
isBSet = true;
|
||||
}
|
||||
|
||||
void TransferReaction::Seta(int A, int Z){
|
||||
Isotope temp (A, Z);
|
||||
ma = temp.Mass;
|
||||
config.targetA = A;
|
||||
config.targetZ = Z;
|
||||
namea = temp.Name;
|
||||
isReady = false;
|
||||
isBSet = false;
|
||||
}
|
||||
void TransferReaction::Setb(int A, int Z){
|
||||
Isotope temp (A, Z);
|
||||
mb = temp.Mass;
|
||||
recoil.lightA = A;
|
||||
recoil.lightZ = Z;
|
||||
nameb = temp.Name;
|
||||
isReady = false;
|
||||
isBSet = false;
|
||||
}
|
||||
void TransferReaction::SetB(int A, int Z){
|
||||
Isotope temp (A, Z);
|
||||
mB = temp.Mass;
|
||||
recoil.heavyA = A;
|
||||
recoil.heavyZ = Z;
|
||||
nameB = temp.Name;
|
||||
isReady = false;
|
||||
isBSet = true;
|
||||
}
|
||||
|
||||
void TransferReaction::SetIncidentEnergyAngle(double KEA, double theta, double phi){
|
||||
this->TA = KEA;
|
||||
this->T = TA * config.beamA;
|
||||
this->thetaIN = theta;
|
||||
this->phiIN = phi;
|
||||
isReady = false;
|
||||
}
|
||||
|
||||
void TransferReaction::SetReactionSimple(int beamA, int beamZ,
|
||||
int targetA, int targetZ,
|
||||
int recoilA, int recoilZ,
|
||||
float beamEnergy_AMeV){
|
||||
|
||||
config.SetReactionSimple(beamA, beamZ,
|
||||
targetA, targetZ,
|
||||
recoilA, recoilZ, beamEnergy_AMeV);
|
||||
|
||||
recoil = config.recoil[0];
|
||||
|
||||
SetA(config.beamA, config.beamZ);
|
||||
Seta(config.targetA, config.targetZ);
|
||||
Setb(recoil.lightA, recoil.lightZ);
|
||||
SetB(recoil.heavyA, recoil.heavyZ);
|
||||
SetIncidentEnergyAngle(config.beamEnergy, 0, 0);
|
||||
|
||||
CalReactionConstant();
|
||||
|
||||
}
|
||||
|
||||
void TransferReaction::SetExA(double Ex){
|
||||
this->ExA = Ex;
|
||||
isReady = false;
|
||||
}
|
||||
|
||||
void TransferReaction::SetExB(double Ex){
|
||||
this->ExB = Ex;
|
||||
isReady = false;
|
||||
}
|
||||
|
||||
void TransferReaction::SetReactionFromReactionConfigClass(ReactionConfig reactConfigClassObject, unsigned short ID){
|
||||
|
||||
config = reactConfigClassObject;
|
||||
SetA(config.beamA, config.beamZ);
|
||||
Seta(config.targetA, config.targetZ);
|
||||
|
||||
SetExA(config.beamEx);
|
||||
|
||||
if( ID > config.recoil.size() ){
|
||||
printf("Reaction Config only has %zu recoil settings. input is %u. Abort.\n", config.recoil.size(), ID);
|
||||
return;
|
||||
}
|
||||
|
||||
recoil = config.recoil[ID];
|
||||
exList = config.exList[ID];
|
||||
|
||||
Setb(recoil.lightA, recoil.lightZ);
|
||||
SetB(recoil.heavyA, recoil.heavyZ);
|
||||
SetIncidentEnergyAngle(config.beamEnergy, 0, 0);
|
||||
|
||||
CalReactionConstant();
|
||||
|
||||
}
|
||||
|
||||
void TransferReaction::SetReactionFromFile(std::string configFile, unsigned short ID){
|
||||
|
||||
if( config.LoadReactionConfig(configFile) ){
|
||||
|
||||
SetA(config.beamA, config.beamZ);
|
||||
Seta(config.targetA, config.targetZ);
|
||||
|
||||
SetExA(config.beamEx);
|
||||
|
||||
if( ID > config.recoil.size() ){
|
||||
printf("Reaction Config only has %zu recoil settings. input is %u. Abort.\n", config.recoil.size(), ID);
|
||||
return;
|
||||
}
|
||||
|
||||
recoil = config.recoil[ID];
|
||||
exList = config.exList[ID];
|
||||
|
||||
Setb(recoil.lightA, recoil.lightZ);
|
||||
SetB(recoil.heavyA, recoil.heavyZ);
|
||||
SetIncidentEnergyAngle(config.beamEnergy, 0, 0);
|
||||
|
||||
CalReactionConstant();
|
||||
|
||||
}else{
|
||||
printf("cannot read file %s.\n", configFile.c_str());
|
||||
isReady = false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void TransferReaction::SetReactionFromTMacro(TMacro configMacro, unsigned short ID){
|
||||
|
||||
if( config.LoadReactionConfig(&configMacro) ){
|
||||
|
||||
SetA(config.beamA, config.beamZ);
|
||||
Seta(config.targetA, config.targetZ);
|
||||
|
||||
SetExA(config.beamEx);
|
||||
|
||||
if( ID > config.recoil.size() ){
|
||||
printf("Reaction Config only has %zu recoil settings. input is %u. Abort.\n", config.recoil.size(), ID);
|
||||
return;
|
||||
}
|
||||
|
||||
recoil = config.recoil[ID];
|
||||
exList = config.exList[ID];
|
||||
|
||||
Setb(recoil.lightA, recoil.lightZ);
|
||||
SetB(recoil.heavyA, recoil.heavyZ);
|
||||
SetIncidentEnergyAngle(config.beamEnergy, 0, 0);
|
||||
|
||||
CalReactionConstant();
|
||||
|
||||
}else{
|
||||
printf("cannot read TMacro %s.\n", configMacro.GetName());
|
||||
isReady = false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
TString TransferReaction::GetReactionName() const{
|
||||
TString rName;
|
||||
rName.Form("%s(%s,%s)%s", nameA.c_str(), namea.c_str(), nameb.c_str(), nameB.c_str());
|
||||
return rName;
|
||||
}
|
||||
|
||||
TString TransferReaction::format(TString name){
|
||||
if( name.IsAlpha() ) return name;
|
||||
int len = name.Length();
|
||||
TString temp = name;
|
||||
TString temp2 = name;
|
||||
if( temp.Remove(0, len-2).IsAlpha()){
|
||||
temp2.Remove(len-2);
|
||||
}else{
|
||||
temp = name;
|
||||
temp.Remove(0, len-1);
|
||||
temp2.Remove(len-1);
|
||||
}
|
||||
return "^{"+temp2+"}"+temp;
|
||||
}
|
||||
|
||||
TString TransferReaction::GetReactionName_Latex(){
|
||||
TString rName;
|
||||
rName.Form("%s(%s,%s)%s @ %.2f MeV/u", format(nameA).Data(), format(namea).Data(), format(nameb).Data(), format(nameB).Data(), config.beamEnergy);
|
||||
return rName;
|
||||
}
|
||||
|
||||
double TransferReaction::CalkCM(double ExB){
|
||||
if( !isBSet || !isReady) return TMath::QuietNaN();
|
||||
return TMath::Sqrt( (Etot*Etot - TMath::Power(mb + mB + ExB,2)) * (Etot*Etot - TMath::Power(mb - mB - ExB,2)) ) / 2 / Etot;
|
||||
}
|
||||
|
||||
void TransferReaction::CalReactionConstant(){
|
||||
if( !isBSet){
|
||||
recoil.heavyA = config.beamA + config.targetA - recoil.lightA;
|
||||
recoil.heavyZ = config.beamZ + config.targetZ - recoil.lightZ;
|
||||
Isotope temp (recoil.heavyA, recoil.heavyZ);
|
||||
mB = temp.Mass;
|
||||
isBSet = true;
|
||||
}
|
||||
|
||||
k = TMath::Sqrt(TMath::Power(mA + ExA + T, 2) - (mA + ExA) * (mA + ExA));
|
||||
beta = k / (mA + ExA + ma + T);
|
||||
gamma = 1 / TMath::Sqrt(1- beta * beta);
|
||||
Etot = TMath::Sqrt(TMath::Power(mA + ExA + ma + T,2) - k * k);
|
||||
|
||||
PA.SetXYZM(0, 0, k, mA + ExA);
|
||||
PA.RotateY(thetaIN);
|
||||
PA.RotateZ(phiIN);
|
||||
Pa.SetXYZM(0,0,0,ma);
|
||||
|
||||
PA.SetUniqueID(config.beamZ);
|
||||
Pa.SetUniqueID(config.targetZ);
|
||||
Pb.SetUniqueID(recoil.lightZ);
|
||||
PB.SetUniqueID(recoil.heavyZ);
|
||||
|
||||
isReady = true;
|
||||
p = CalkCM(ExB);
|
||||
|
||||
}
|
||||
|
||||
void TransferReaction::PrintFourVectors() const {
|
||||
|
||||
printf("A : %10.2f %10.2f %10.2f %10.2f\n", PA.E(), PA.Px(), PA.Py(), PA.Pz());
|
||||
printf("a : %10.2f %10.2f %10.2f %10.2f\n", Pa.E(), Pa.Px(), Pa.Py(), Pa.Pz());
|
||||
printf("b : %10.2f %10.2f %10.2f %10.2f\n", Pb.E(), Pb.Px(), Pb.Py(), Pb.Pz());
|
||||
printf("B : %10.2f %10.2f %10.2f %10.2f\n", PB.E(), PB.Px(), PB.Py(), PB.Pz());
|
||||
printf("-------------------------------------------------------\n");
|
||||
printf("B : %10.2f %10.2f %10.2f %10.2f\n",
|
||||
PA.E() + Pa.E() - Pb.E() - PB.E(),
|
||||
PA.Px() + Pa.Px() - Pb.Px() - PB.Px(),
|
||||
PA.Py() + Pa.Py() - Pb.Py() - PB.Py(),
|
||||
PA.Pz() + Pa.Pz() - Pb.Pz() - PB.Pz());
|
||||
|
||||
}
|
||||
|
||||
void TransferReaction::PrintReaction(bool withEx) const {
|
||||
|
||||
printf("=====================================================\n");
|
||||
printf("\e[1m\e[33m %s \e[0m\n", GetReactionName().Data());
|
||||
printf("=====================================================\n");
|
||||
printf("------------------------------ Beam\n");
|
||||
printf(" beam : A = %3d, Z = %2d, Ex = %.2f MeV\n", config.beamA, config.beamZ, config.beamEx);
|
||||
printf(" beam Energy : %.2f +- %.2f MeV/u, dE/E = %5.2f %%\n", config.beamEnergy, config.beamEnergySigma, config.beamEnergySigma/config.beamEnergy);
|
||||
printf(" Angle : %.2f +- %.2f mrad\n", config.beamTheta, config.beamThetaSigma);
|
||||
printf(" offset : (x,y) = (%.2f, %.2f) mmm \n", config.beamX, config.beamY);
|
||||
|
||||
printf("------------------------------ Target\n");
|
||||
printf(" target : A = %3d, Z = %2d \n", config.targetA, config.targetZ);
|
||||
|
||||
printf("------------------------------ Recoil\n");
|
||||
printf(" light : A = %3d, Z = %2d \n", recoil.lightA, recoil.lightZ);
|
||||
printf(" heavy : A = %3d, Z = %2d \n", recoil.heavyA, recoil.heavyZ);
|
||||
printf("=====================================================\n");
|
||||
|
||||
if( withEx ) {
|
||||
exList.Print();
|
||||
printf("=====================================================\n");
|
||||
}
|
||||
}
|
||||
|
||||
void TransferReaction::Event(double thetaCM_rad, double phiCM_rad){
|
||||
|
||||
if( !isReady ) CalReactionConstant();
|
||||
|
||||
//---- to CM frame
|
||||
TLorentzVector Pc = PA + Pa;
|
||||
TVector3 b = Pc.BoostVector();
|
||||
|
||||
TVector3 vb(0,0,0);
|
||||
|
||||
if( b.Mag() > 0 ){
|
||||
TVector3 v0 (0,0,0);
|
||||
TVector3 nb = v0 - b;
|
||||
|
||||
TLorentzVector PAc = PA;
|
||||
PAc.Boost(nb);
|
||||
TVector3 vA = PAc.Vect();
|
||||
|
||||
TLorentzVector Pac = Pa;
|
||||
Pac.Boost(nb);
|
||||
TVector3 va = Pac.Vect();
|
||||
|
||||
//--- construct vb
|
||||
vb = va;
|
||||
vb.SetMag(p);
|
||||
|
||||
TVector3 ub = vb.Orthogonal();
|
||||
vb.Rotate(thetaCM_rad, ub);
|
||||
vb.Rotate(phiCM_rad + TMath::PiOver2(), va); // somehow, the calculation turn the vector 90 degree.
|
||||
//vb.Rotate(phiCM , va); // somehow, the calculation turn the vector 90 degree.
|
||||
}
|
||||
|
||||
//--- from Pb
|
||||
TLorentzVector Pbc;
|
||||
Pbc.SetVectM(vb, mb);
|
||||
|
||||
//--- from PB
|
||||
TLorentzVector PBc;
|
||||
//PBc.SetVectM(vB, mB + ExB);
|
||||
PBc.SetVectM(-vb, mB + ExB);
|
||||
|
||||
//---- to Lab Frame
|
||||
Pb = Pbc; Pb.Boost(b);
|
||||
PB = PBc; PB.Boost(b);
|
||||
|
||||
}
|
||||
|
||||
std::pair<double, double> TransferReaction::CalExThetaCM(double e, double z, double Bfield, double perpDist){
|
||||
|
||||
double Ex = TMath::QuietNaN();
|
||||
double thetaCM = TMath::QuietNaN();
|
||||
|
||||
double mass = mb;
|
||||
double massB = mB;
|
||||
double y = e + mass;
|
||||
double slope = 299.792458 * recoil.lightZ * abs(Bfield) / TMath::TwoPi() * beta / 1000.; // MeV/mm;
|
||||
double alpha = slope/beta;
|
||||
double G = alpha * gamma * beta * perpDist ;
|
||||
double Z = alpha * gamma * beta * z;
|
||||
double H = TMath::Sqrt(TMath::Power(gamma * beta,2) * (y*y - mass * mass) ) ;
|
||||
double Et = Etot;
|
||||
|
||||
if( TMath::Abs(Z) < H ) {
|
||||
//using Newton's method to solve 0 == H * sin(phi) - G * tan(phi) - Z = f(phi)
|
||||
double tolerrence = 0.001;
|
||||
double phi = 0; //initial phi = 0 -> ensure the solution has f'(phi) > 0
|
||||
double nPhi = 0; // new phi
|
||||
|
||||
int iter = 0;
|
||||
do{
|
||||
phi = nPhi;
|
||||
nPhi = phi - (H * TMath::Sin(phi) - G * TMath::Tan(phi) - Z) / (H * TMath::Cos(phi) - G /TMath::Power( TMath::Cos(phi), 2));
|
||||
iter ++;
|
||||
if( iter > 10 || TMath::Abs(nPhi) > TMath::PiOver2()) break;
|
||||
}while( TMath::Abs(phi - nPhi ) > tolerrence);
|
||||
|
||||
phi = nPhi;
|
||||
|
||||
// check f'(phi) > 0
|
||||
double Df = H * TMath::Cos(phi) - G / TMath::Power( TMath::Cos(phi),2);
|
||||
if( Df > 0 && TMath::Abs(phi) < TMath::PiOver2() ){
|
||||
double K = H * TMath::Sin(phi);
|
||||
double x = TMath::ACos( mass / ( y * gamma - K));
|
||||
double k = mass * TMath::Tan(x); // momentum of particel b or B in CM frame
|
||||
double EB = TMath::Sqrt(mass*mass + Et*Et - 2*Et*TMath::Sqrt(k*k + mass * mass));
|
||||
Ex = EB - massB;
|
||||
|
||||
double hahaha1 = gamma* TMath::Sqrt(mass * mass + k * k) - y;
|
||||
double hahaha2 = gamma* beta * k;
|
||||
thetaCM = TMath::ACos(hahaha1/hahaha2) * TMath::RadToDeg();
|
||||
|
||||
//double pt = k * TMath::Sin(thetaCM * TMath::DegToRad());
|
||||
//double pp = gamma*beta*TMath::Sqrt(mass*mass + k*k) - gamma * k * TMath::Cos(thetaCM * TMath::DegToRad());
|
||||
//thetaLab = TMath::ATan(pt/pp) * TMath::RadToDeg();
|
||||
|
||||
}else{
|
||||
Ex = TMath::QuietNaN();
|
||||
thetaCM = TMath::QuietNaN();
|
||||
//thetaLab = TMath::QuietNaN();
|
||||
}
|
||||
|
||||
}else{
|
||||
Ex = TMath::QuietNaN();
|
||||
thetaCM = TMath::QuietNaN();
|
||||
//thetaLab = TMath::QuietNaN();
|
||||
}
|
||||
|
||||
return std::make_pair(Ex, thetaCM);
|
||||
}
|
||||
|
||||
void TransferReaction::CreateExDistribution(){
|
||||
|
||||
int numEx = exList.ExList.size();
|
||||
|
||||
exDistribution = new TF1("exDistribution", TransferReaction::exDistFunc, 0, numEx, numEx);
|
||||
for(int q = 0; q < numEx; q++){
|
||||
exDistribution->SetParameter(q, exList.ExList[q].xsec*exList.ExList[q].SF);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
|
@ -27,14 +27,13 @@
|
|||
* ********************************************************************/
|
||||
|
||||
#include <fstream>
|
||||
#include <stdlib.h> /* atof */
|
||||
#include <cmath>
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
#include <stdexcept>
|
||||
#include <stdio.h>
|
||||
#include <string>
|
||||
#include <cstdlib>
|
||||
#include <sstream>
|
||||
#include <TROOT.h>
|
||||
#include <TFile.h>
|
||||
#include <TString.h>
|
||||
|
@ -43,6 +42,8 @@
|
|||
#include <TApplication.h>
|
||||
#include "PlotTGraphTObjArray.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
int main (int argc, char *argv[]) { //TODO add angle range
|
||||
|
||||
printf("=================================================================\n");
|
||||
|
@ -59,7 +60,7 @@ int main (int argc, char *argv[]) { //TODO add angle range
|
|||
}
|
||||
|
||||
//================= read infile. extract the reactions, write pptolemy infile for each reaction
|
||||
std::string readFile = argv[1];
|
||||
string readFile = argv[1];
|
||||
double angMin = 0.;
|
||||
double angMax = 180.;
|
||||
double angStep = 1.;
|
||||
|
@ -71,30 +72,20 @@ int main (int argc, char *argv[]) { //TODO add angle range
|
|||
angStep = atof(argv[4]);
|
||||
}
|
||||
|
||||
std::string ptolemyInFileName = argv[1];
|
||||
string ptolemyInFileName = argv[1];
|
||||
ptolemyInFileName += ".in";
|
||||
printf("=================== Create InFile\n");
|
||||
InFileCreator( readFile, ptolemyInFileName, angMin, angMax, angStep);
|
||||
|
||||
//================= run ptolemy
|
||||
std::string ptolemyOutFileName = argv[1];
|
||||
|
||||
char command[200];
|
||||
string ptolemyOutFileName = argv[1];
|
||||
ptolemyOutFileName += ".out";
|
||||
std::ostringstream commandStream;
|
||||
#if defined(__linux__)
|
||||
commandStream << "../Cleopatra/ptolemy <" << ptolemyInFileName << "> " << ptolemyOutFileName;
|
||||
#elif defined(__APPLE__) && defined(__MACH__)
|
||||
commandStream << "../Cleopatra/ptolemy_mac <" << ptolemyInFileName << "> " << ptolemyOutFileName;
|
||||
#endif
|
||||
std::string command = commandStream.str();
|
||||
|
||||
sprintf(command, "./ptolemy <%s> %s", ptolemyInFileName.c_str(), ptolemyOutFileName.c_str());
|
||||
printf("=================== Run Ptolemy\n");
|
||||
printf("%s \n", command.c_str());
|
||||
|
||||
int result = std::system(command.c_str());
|
||||
if (result == -1) {
|
||||
std::cerr << "Error executing system command." << std::endl;
|
||||
return 1;
|
||||
}
|
||||
printf("%s \n", command);
|
||||
system(command);
|
||||
|
||||
//================= extract the Xsec and save as txt and root
|
||||
printf("=================== Extract Cross-section\n");
|
||||
|
@ -102,7 +93,7 @@ int main (int argc, char *argv[]) { //TODO add angle range
|
|||
|
||||
//================= Call root to plot the d.s.c.
|
||||
printf("=================== Plot Result using ROOT.\n");
|
||||
std::string rootFileName = argv[1];
|
||||
string rootFileName = argv[1];
|
||||
rootFileName += ".root";
|
||||
TApplication app ("app", &argc, argv);
|
||||
PlotTGraphTObjArray(rootFileName);
|
||||
|
|
205
Cleopatra/Cleopatra.sh
Executable file
|
@ -0,0 +1,205 @@
|
|||
#!/bin/bash
|
||||
|
||||
|
||||
########################################################################
|
||||
#
|
||||
# This is Cleopatra.sh, a scripted version for Cleopatra
|
||||
#
|
||||
# Using bash script provide flexibility that user can add difference
|
||||
# compoenents during the calculation
|
||||
#
|
||||
# A full package includes fellowing:
|
||||
# 1) create a in-file for ptolemy
|
||||
# 2) run ptolemy from that in-file and output an out-file
|
||||
# 3) extract cross-section distribution from the out-file
|
||||
# save as txt or root TGraph format
|
||||
# 4) call ROOT to draw the TGraph
|
||||
# 5) load possible experimental Xsec and fit with Ptolemy calulation
|
||||
#
|
||||
# User can easily select/comment-out different component
|
||||
# to suit their needs
|
||||
#-------------------------------------------------------
|
||||
# created by Ryan (Tsz Leung) Tang, Nov-18, 2018
|
||||
# email: goluckyryan@gmail.com
|
||||
########################################################################
|
||||
|
||||
#===== Call thisroot.h
|
||||
ROOTPATH=$(which root)
|
||||
len=${#ROOTPATH}
|
||||
ROOTSOURCE=${ROOTPATH:0:$len-4}"thisroot.sh"
|
||||
echo $ROOTSOURCE
|
||||
source $ROOTSOURCE
|
||||
|
||||
#===== go to Cleopatra and make
|
||||
cd ../Cleopatra
|
||||
make
|
||||
cd ../working
|
||||
|
||||
#================================ User Defualt Control
|
||||
CreateInFile=0 # 0 = false, 1 = true
|
||||
RunPtolemy=0
|
||||
IsExtractXSec=0
|
||||
PlotResult=0
|
||||
SimTransfer=0
|
||||
#============================================ USER don't need to change thing below
|
||||
|
||||
if [ $# -eq 0 ] ; then
|
||||
echo "$./Cleopatra in-file X X X X X angMin angMax angStep"
|
||||
echo " | | | | |"
|
||||
echo " | | | | Simulate Transfer reaction? (1/0)"
|
||||
echo " | | | |"
|
||||
echo " | | | PlotResult? (1/0)"
|
||||
echo " | | Extract cross-section? (2/1/0)"
|
||||
echo " | | if 1 = extract Ratio to Rutherford for (d,d), (p,p)"
|
||||
echo " | | if 2 = extract total Xsec for (d,d), (p,p), (n,n)"
|
||||
echo " | | if 3 = extract Rutherford"
|
||||
echo " | Run Ptolemy? (1/0)"
|
||||
echo " Create infile? (1/0)"
|
||||
echo "default angMin = 0, angMax = 50, angStep = 0.5"
|
||||
exit 1
|
||||
fi;
|
||||
|
||||
loadfile=$1
|
||||
infile=$1".in"
|
||||
outfile=$1".out"
|
||||
rootfile=$1".root"
|
||||
exFile=$1".Ex.txt"
|
||||
|
||||
if [ $# -eq 2 ]; then
|
||||
CreateInFile=$2
|
||||
fi;
|
||||
if [ $# -eq 3 ]; then
|
||||
CreateInFile=$2
|
||||
RunPtolemy=$3
|
||||
fi;
|
||||
if [ $# -eq 4 ]; then
|
||||
CreateInFile=$2
|
||||
RunPtolemy=$3
|
||||
IsExtractXSec=$4
|
||||
fi;
|
||||
if [ $# -eq 5 ]; then
|
||||
CreateInFile=$2
|
||||
RunPtolemy=$3
|
||||
IsExtractXSec=$4
|
||||
PlotResult=$5
|
||||
fi;
|
||||
if [ $# -eq 6 ]; then
|
||||
CreateInFile=$2
|
||||
RunPtolemy=$3
|
||||
IsExtractXSec=$4
|
||||
PlotResult=$5
|
||||
SimTransfer=$6
|
||||
fi;
|
||||
if [ $# -eq 9 ]; then
|
||||
CreateInFile=$2
|
||||
RunPtolemy=$3
|
||||
IsExtractXSec=$4
|
||||
PlotResult=$5
|
||||
SimTransfer=$6
|
||||
angMin=$7
|
||||
angMax=$8
|
||||
angStep=$9
|
||||
fi;
|
||||
|
||||
ExtractXsecMsg=""
|
||||
if [ $IsExtractXSec -eq 1 ]; then
|
||||
ExtractXsecMsg=", for (d,d)(p,p), extract Ratio to Rutherford"
|
||||
elif [ $IsExtractXSec -eq 2 ]; then
|
||||
ExtractXsecMsg=", for (d,d)(p,p), extract Total Xsec"
|
||||
fi;
|
||||
|
||||
if [ $SimTransfer -eq 1 ]; then
|
||||
angMin=0
|
||||
angMax=180
|
||||
angStep=0.5
|
||||
fi
|
||||
|
||||
echo "#################################################################"
|
||||
echo "## @@@@ @@ @@@@ @@@@ @@@@@ @@@@ @@@@@@ @@@@@ @@@@ ##"
|
||||
echo "## @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ ##"
|
||||
echo "## @@ @@ @@@@ @@ @@ @@@@@ @@@@@@ @@ @@@@@ @@@@@@ ##"
|
||||
echo "## @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @ @@ @@ ##"
|
||||
echo "## @@@@ @@@@@ @@@@ @@@@ @@ @@ @@ @@ @@ @ @@ @@ ##"
|
||||
echo "#################################################################"
|
||||
echo "##### Cleopatra, Ptolemy for p,d,t,3He, a #####"
|
||||
echo "#################################################################"
|
||||
echo "Supported reactions:"
|
||||
echo "elastics/inelastics : (p,p), (d,d)"
|
||||
echo "1-neutron adding : (d,p), (t,d) | (a,3He)?"
|
||||
echo "1-proton adding : (3He,d)"
|
||||
echo "2-neutrons adding : (t,p)"
|
||||
echo "1-neutron removal : (p,d), (d,t) "
|
||||
echo "1-proton removal : (d,3He), (t,a)"
|
||||
echo "================================================================="
|
||||
echo "USER OPTION:"
|
||||
echo " --- Is Create Ptolemy infile ? " ${CreateInFile}
|
||||
echo " --- Is Run Ptolemy ? " ${RunPtolemy}
|
||||
echo " --- Is Extract Cross-Section ? " ${IsExtractXSec} ${ExtractXsecMsg}
|
||||
echo " --- Is Plot Results ? " ${PlotResult}
|
||||
echo " ----Is Simulation Transfer ? " ${SimTransfer}
|
||||
echo "================================================================="
|
||||
|
||||
#if [ ${CreateInFile} -eq 1 ] ; then
|
||||
# echo "infile ----> "${loadfile}
|
||||
#fi;
|
||||
#
|
||||
#if [ ${RunPtolemy} -eq 1 ] ; then
|
||||
# echo "Ptolemy infile ----> "${infile}
|
||||
# echo "Ptolemy outfile ----> "${outfile}
|
||||
#fi;
|
||||
|
||||
if [ ${CreateInFile} -eq 1 ] ; then
|
||||
if [ $# -eq 9 ]; then
|
||||
../Cleopatra/InFileCreator ${loadfile} $angMin $angMax $angStep
|
||||
else
|
||||
../Cleopatra/InFileCreator ${loadfile} 0.0 50.0 0.5
|
||||
fi
|
||||
fi;
|
||||
|
||||
if [ ${RunPtolemy} -eq 1 ] ; then
|
||||
echo "================================================================="
|
||||
echo "===== Ptolemy Calcualtion ==================================="
|
||||
echo "================================================================="
|
||||
|
||||
#check is linux or Mac
|
||||
|
||||
arch=$(uname)
|
||||
|
||||
if [ ${arch} == "Darwin" ] ; then
|
||||
../Cleopatra/ptolemy_mac <${infile}> ${outfile}
|
||||
ptolemyOUTPUT=$?
|
||||
else
|
||||
../Cleopatra/ptolemy <${infile}> ${outfile}
|
||||
ptolemyOUTPUT=$?
|
||||
fi
|
||||
|
||||
echo "ptolmey exit code : " $ptolemyOUTPUT
|
||||
if [ ${ptolemyOUTPUT} -eq 0 ] ; then
|
||||
echo "Ptolmey finished without problem. "
|
||||
else
|
||||
echo "Ptolemy has error, check ${infile} or ${outfile}"
|
||||
exit 1;
|
||||
fi
|
||||
|
||||
fi;
|
||||
|
||||
#===== Extracting XSec and save into *txt and *root
|
||||
if [ ${IsExtractXSec} -ge 1 ] ; then
|
||||
../Cleopatra/ExtractXSec ${outfile} ${IsExtractXSec}
|
||||
fi;
|
||||
|
||||
if [ ${PlotResult} -eq 1 ] ; then
|
||||
#===== Plot the result from the *.root
|
||||
#./PlotTGraphTObjArray ${rootfile}
|
||||
#--- other way within ROOT
|
||||
echo "================================================================="
|
||||
echo "===== Plot Result from ${rootfile}"
|
||||
echo "================================================================="
|
||||
com='../Cleopatra/PlotTGraphTObjArray.h("'${rootfile}'")'
|
||||
echo ${com}
|
||||
root -l ${com}
|
||||
fi;
|
||||
|
||||
if [ ${SimTransfer} -eq 1 ] ; then
|
||||
../Cleopatra/Transfer reactionConfig.txt detectorGeo.txt ${exFile} ${rootfile} transfer.root reaction.dat
|
||||
fi;
|
73
Cleopatra/DWBARatio.C
Normal file
|
@ -0,0 +1,73 @@
|
|||
|
||||
|
||||
TGraph * DWBARatio(int id1, int id2, TString rootFile="DWBA.root", bool isPlot = true){
|
||||
|
||||
TGraph * gR = NULL;
|
||||
|
||||
TFile * file = new TFile(rootFile, "READ");
|
||||
if( file != NULL ){
|
||||
printf("----- Opening %s\n", rootFile.Data());
|
||||
}else{
|
||||
printf("----- Opening %s .... Fail.\n", rootFile.Data());
|
||||
return gR;
|
||||
}
|
||||
|
||||
///get the TGraph of the distribution.
|
||||
TObjArray * gList = (TObjArray *) file->Get("qList");
|
||||
int size = gList->GetLast()+1;
|
||||
printf("----- found %d d.s.c\n", size);
|
||||
|
||||
if( id1 > size || id2 > size ) {
|
||||
printf(" id1 > %d || id2 > %d \n", size, size);
|
||||
return gR;
|
||||
}
|
||||
|
||||
TGraph * g1 = (TGraph *) gList->At(id1);
|
||||
TGraph * g2 = (TGraph *) gList->At(id2);
|
||||
|
||||
double g1MaxY = g1->GetHistogram()->GetMaximum();
|
||||
double g2MaxY = g2->GetHistogram()->GetMaximum();
|
||||
|
||||
g2->SetLineColor(2);
|
||||
|
||||
|
||||
TCanvas * cDWBA = NULL ;
|
||||
|
||||
if( isPlot ){
|
||||
cDWBA= new TCanvas("cDWBA", "DWBA Ratio", 1000, 500);
|
||||
cDWBA->Divide(2,1);
|
||||
|
||||
cDWBA->cd(1);
|
||||
cDWBA->cd(1)->SetLogy();
|
||||
|
||||
if( g1MaxY > g2MaxY ) {
|
||||
g1->Draw();
|
||||
g2->Draw("same");
|
||||
}else{
|
||||
g2->Draw();
|
||||
g1->Draw("same");
|
||||
}
|
||||
|
||||
TLegend * legend = new TLegend( 0.1, 0.9, 0.9, 1.0);
|
||||
legend->AddEntry(g1, g1->GetName());
|
||||
legend->AddEntry(g2, g2->GetName());
|
||||
|
||||
legend->Draw();
|
||||
|
||||
cDWBA->cd(2);
|
||||
|
||||
}
|
||||
gR = new TGraph();
|
||||
double x, y1, y2;
|
||||
for( int i = 0 ; i < g1->GetN(); i++){
|
||||
g1->GetPoint(i, x, y1);
|
||||
g2->GetPoint(i, x, y2);
|
||||
gR->SetPoint(i, x, y1/y2);
|
||||
}
|
||||
|
||||
if( isPlot) gR->Draw();
|
||||
|
||||
return gR;
|
||||
|
||||
}
|
||||
|
16
Cleopatra/DWBA_compare.C
Normal file
|
@ -0,0 +1,16 @@
|
|||
#include "DWBARatio.C"
|
||||
|
||||
void DWBA_compare(){
|
||||
|
||||
TGraph * w[12];
|
||||
for( int i = 0 ; i < 12; i++){
|
||||
|
||||
w[i] = DWBARatio(i, i+12, "DWBA.root", false);
|
||||
w[i]->SetLineColor(i+1);
|
||||
|
||||
i == 0 ? w[i]->Draw("Al") : w[i]->Draw("same");
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -23,10 +23,9 @@
|
|||
#include <TString.h>
|
||||
#include <TMath.h>
|
||||
#include <TGraph.h>
|
||||
#include <TMacro.h>
|
||||
#include <TF1.h>
|
||||
#include <TObjArray.h>
|
||||
#include "../Armory/AnalysisLib.h"
|
||||
#include "../armory/AnalysisLib.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
|
@ -294,9 +293,26 @@ int ExtractXSec (string readFile, int indexForElastic=1) {
|
|||
}
|
||||
printf("---------------------------------------------------\n");
|
||||
|
||||
//================================== save *.Ex.txt
|
||||
string saveExName = readFile;
|
||||
int len = saveExName.length();
|
||||
saveExName = saveExName.substr(0, len - 4);
|
||||
saveExName += ".Ex.txt";
|
||||
printf("Output : %s \n", saveExName.c_str());
|
||||
FILE * file_Ex;
|
||||
file_Ex = fopen(saveExName.c_str(), "w+");
|
||||
|
||||
fprintf(file_Ex, "//generated_by_ExtractXSec.h____Ex____Xsec(4pi)____SF____sigma\n");
|
||||
|
||||
for( int i = 0; i < numCal ; i++){
|
||||
fprintf(file_Ex, "%9.5f %9.5f 1.0 0.000\n", Ex[i], partialXsec[i]);
|
||||
}
|
||||
fprintf(file_Ex, "#=====End_of_File\n");
|
||||
fclose(file_Ex);
|
||||
|
||||
//================================== save file.Xsec.txt
|
||||
string saveFileName = readFile;
|
||||
int len = saveFileName.length();
|
||||
len = saveFileName.length();
|
||||
saveFileName = saveFileName.substr(0, len - 4);
|
||||
saveFileName += ".Xsec.txt";
|
||||
printf("Output : %s \n", saveFileName.c_str());
|
||||
|
@ -308,7 +324,7 @@ int ExtractXSec (string readFile, int indexForElastic=1) {
|
|||
}
|
||||
|
||||
int space = 19;
|
||||
fprintf(file_out, "%8s\t", "Angle");
|
||||
fprintf(file_out, "%8s\t", "Angel");
|
||||
for( int i = 0; i < numCal ; i++){
|
||||
fprintf(file_out, "%*s", space, title[i].c_str());
|
||||
}
|
||||
|
@ -322,16 +338,6 @@ int ExtractXSec (string readFile, int indexForElastic=1) {
|
|||
fprintf(file_out, "\n");
|
||||
}
|
||||
fclose(file_out);
|
||||
|
||||
//================================== Make TMacro for ExList
|
||||
|
||||
TMacro ExList;
|
||||
TMacro ReactList;
|
||||
ExList.AddLine("#---Ex relative_xsec SF sigma_in_MeV");
|
||||
for( int i = 0; i < numCal ; i++){
|
||||
ExList.AddLine(Form("%9.5f %9.5f 1.0 0.000", Ex[i], partialXsec[i]));
|
||||
ReactList.AddLine(reaction[i].c_str());
|
||||
}
|
||||
|
||||
//================================== Save in ROOT
|
||||
len = saveFileName.length();
|
||||
|
@ -339,8 +345,8 @@ int ExtractXSec (string readFile, int indexForElastic=1) {
|
|||
TString fileName = saveFileName;
|
||||
fileName += ".root";
|
||||
printf("Output : %s \n", fileName.Data());
|
||||
|
||||
TFile * fileOut = new TFile(fileName, "RECREATE" );
|
||||
|
||||
gList = new TObjArray(); ///no SetTitle() method for TObjArray
|
||||
gList->SetName("TGraph of d.s.c");
|
||||
TObjArray * fList = new TObjArray();
|
||||
|
@ -366,12 +372,12 @@ int ExtractXSec (string readFile, int indexForElastic=1) {
|
|||
|
||||
fList->Add(dist[i]);
|
||||
|
||||
//delete tempFunc;
|
||||
|
||||
}
|
||||
gList->Write("thetaCM_TGraph", 1);
|
||||
fList->Write("thetaCM_TF1", 1);
|
||||
|
||||
ExList.Write("ExList");
|
||||
ReactList.Write("ReactionList");
|
||||
gList->Write("qList", 1);
|
||||
fList->Write("pList", 1);
|
||||
|
||||
|
||||
fileOut->Write();
|
||||
fileOut->Close();
|
||||
|
|
|
@ -22,35 +22,37 @@ int main(int argc, char *argv[]){
|
|||
printf("=== Find ThetaCM convrage for each detector at Ex ====\n");
|
||||
printf("=================================================================\n");
|
||||
|
||||
if(argc < 2 || argc > 7) {
|
||||
if(argc < 2 || argc > 6) {
|
||||
printf("Usage: ./FindThetaCM Ex\n");
|
||||
printf("Usage: ./FindThetaCM Ex nDiv\n");
|
||||
printf("Usage: ./FindThetaCM Ex nDiv X-Ratio\n");
|
||||
printf("Usage: ./FindThetaCM Ex nDiv X-Ratio reactionTxt detGeoTxt ID\n");
|
||||
printf(" * default is the first settings from reaction and detGeo.\n");
|
||||
exit(0);
|
||||
printf("Usage: ./FindThetaCM Ex nDiv X-Ratio reactionTxt detGeoTxt\n");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
double Ex = 0;
|
||||
double xRatio = 0.95;
|
||||
int nDiv = 1;
|
||||
std::string reactionTxt = "reactionConfig.txt";
|
||||
std::string detGeoTxt = "detectorGeo.txt";
|
||||
int ID = 0;
|
||||
|
||||
if ( argc >= 2 ) Ex = atof(argv[1]);
|
||||
if ( argc >= 3 ) nDiv = atoi(argv[2]);
|
||||
if ( argc >= 4 ) xRatio = atof(argv[3]);
|
||||
if ( argc >= 5 ) reactionTxt = argv[4];
|
||||
if ( argc >= 6 ) detGeoTxt = argv[5];
|
||||
if ( argc >= 6 ) ID = atoi(argv[6]);
|
||||
|
||||
if( nDiv < 1 ) {
|
||||
printf(" nDiv must be >= 1 \n");
|
||||
return -1;
|
||||
string reactionTxt = "reactionConfig.txt";
|
||||
string detGeoTxt = "detectorGeo.txt";
|
||||
|
||||
if ( argc >= 2 ){
|
||||
Ex = atof(argv[1]);
|
||||
}
|
||||
if ( argc >= 3 ){
|
||||
nDiv = atoi(argv[2]);
|
||||
}
|
||||
if ( argc >= 4 ){
|
||||
xRatio = atof(argv[3]);
|
||||
}
|
||||
if ( argc >= 5 ){
|
||||
reactionTxt = argv[4];
|
||||
}
|
||||
if ( argc >= 6 ){
|
||||
detGeoTxt = argv[5];
|
||||
}
|
||||
|
||||
FindThetaCM(Ex, nDiv, xRatio, reactionTxt, detGeoTxt, ID);
|
||||
FindThetaCM(Ex, nDiv, xRatio, reactionTxt, detGeoTxt);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -16,128 +16,200 @@
|
|||
#include "TMacro.h"
|
||||
#include "TObjArray.h"
|
||||
#include "TGraph.h"
|
||||
#include "../Cleopatra/ClassHelios.h"
|
||||
#include "../Cleopatra/ClassTransfer.h"
|
||||
#include "../Cleopatra/HELIOS_LIB.h"
|
||||
|
||||
void FindThetaCM(double Ex, int nDivision=1, double XRATION = 0.95,
|
||||
std::string reactionConfigFileName="reactionConfig.txt",
|
||||
std::string detGeoFileName = "detectorGeo.txt", unsigned short ID = 0){
|
||||
string basicConfig="reactionConfig.txt",
|
||||
string detGeoFileName = "detectorGeo.txt"){
|
||||
|
||||
//---- reaction
|
||||
int AA, zA; //beam
|
||||
int Aa, za; //target
|
||||
int Ab, zb; //recoil-1
|
||||
double ExA;
|
||||
|
||||
///========================================================= load files
|
||||
//---- beam
|
||||
double KEAmean, KEAsigma; // MeV/u , assume Guassian
|
||||
double thetaMean, thetaSigma; // mrad , assume Guassian due to small angle
|
||||
double xBeam, yBeam; // mm
|
||||
|
||||
TransferReaction reaction(reactionConfigFileName, ID);
|
||||
reaction.SetExB(Ex);
|
||||
reaction.CalReactionConstant();
|
||||
reaction.PrintReaction(false);
|
||||
ReactionConfig reConfig = reaction.GetRectionConfig();
|
||||
Recoil recoil = reaction.GetRecoil();
|
||||
/**///========================================================= load files
|
||||
AnalysisLib::ReactionConfig reactionConfig;
|
||||
AnalysisLib::DetGeo detGeo;
|
||||
TMacro * haha = new TMacro();
|
||||
if( haha->ReadFile(basicConfig.c_str()) > 0 ){
|
||||
reactionConfig = AnalysisLib::LoadReactionConfig(haha);
|
||||
|
||||
HELIOS helios(detGeoFileName, ID);
|
||||
helios.PrintGeometry();
|
||||
DetGeo detGeo = helios.GetDetectorGeometry();
|
||||
Array array = helios.GetArrayGeometry();
|
||||
|
||||
//calculate a TGraph for thetaCM vs z
|
||||
const int nData = 170;
|
||||
double px[nData];
|
||||
double py[nData];
|
||||
|
||||
double mb = reaction.GetMass_b();
|
||||
double kCM = reaction.GetMomentumbCM();
|
||||
double q = TMath::Sqrt(mb*mb + kCM * kCM );
|
||||
double beta = reaction.GetReactionBeta() ;
|
||||
double BField = detGeo.Bfield;
|
||||
double slope = reaction.GetEZSlope(BField);
|
||||
double gamma = reaction.GetReactionGamma();
|
||||
double perpDist = array.detPerpDist;
|
||||
AnalysisLib::PrintReactionConfig(reactionConfig);
|
||||
|
||||
for(int i = 0; i < nData; i++){
|
||||
double thetacm = (i + 5.) * TMath::DegToRad();
|
||||
double temp = TMath::TwoPi() * slope / beta / kCM * perpDist / TMath::Sin(thetacm);
|
||||
px[i] = beta /slope * (gamma * beta * q - gamma * kCM * TMath::Cos(thetacm)) * (1 - TMath::ASin(temp)/TMath::TwoPi());
|
||||
py[i] = thetacm * TMath::RadToDeg();
|
||||
}
|
||||
KEAmean = reactionConfig.beamEnergy;
|
||||
KEAsigma = reactionConfig.beamEnergySigma;
|
||||
|
||||
//find minimum z position
|
||||
TGraph * xt = new TGraph(100, py, px);
|
||||
xt->SetName("xt");
|
||||
///double zMin0 = xt->Eval(0);
|
||||
///printf("z for thetaCM = 0 : %f mm \n", zMin0);
|
||||
|
||||
///xt->Draw("AC*");
|
||||
|
||||
/// find the minimum z position and the corresponding theta
|
||||
double zMin0 = 99999999;
|
||||
double tMin0 = 99999999;
|
||||
for( double ttt = 3 ; ttt < 20 ; ttt += 0.1 ){
|
||||
double zzz = xt->Eval(ttt);
|
||||
if( zzz < zMin0 ) {
|
||||
zMin0 = zzz;
|
||||
tMin0 = ttt;
|
||||
}
|
||||
}
|
||||
printf(" z min %f mm at thetaCM %f deg \n", zMin0, tMin0);
|
||||
thetaMean = reactionConfig.beamAngle;
|
||||
thetaSigma = reactionConfig.beamAngleSigma;
|
||||
|
||||
TGraph * tx = new TGraph(nData, px, py);
|
||||
tx->SetName(Form("tx"));
|
||||
tx->SetLineColor(4);
|
||||
xBeam = reactionConfig.beamX;
|
||||
yBeam = reactionConfig.beamY;
|
||||
|
||||
//Remove nan data
|
||||
for( int i = tx->GetN() -1 ; i >= 0 ; i--){
|
||||
if( TMath::IsNaN(tx->GetPointX(i)) ) tx->RemovePoint(i);
|
||||
}
|
||||
|
||||
// tx->Draw("AC");
|
||||
AA = reactionConfig.beamA; zA = reactionConfig.beamZ;
|
||||
Aa = reactionConfig.targetA; za = reactionConfig.targetZ;
|
||||
Ab = reactionConfig.recoilLightA; zb = reactionConfig.recoilLightZ;
|
||||
|
||||
///========================================================= result
|
||||
ExA = reactionConfig.beamEx[0];
|
||||
|
||||
int iDet = array.colDet;
|
||||
double length = array.detLength;
|
||||
std::vector<double> midPos;
|
||||
}else{
|
||||
printf("cannot load %s \n", basicConfig.c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
vector<double> pos;
|
||||
double a = 11.5;
|
||||
double length = 50.5;
|
||||
double firstPos = 0;
|
||||
int iDet = 6;
|
||||
int jDet = 4;
|
||||
double BField = 0;
|
||||
|
||||
for(int i = 0; i < iDet; i++){
|
||||
if( array.firstPos > 0 ){
|
||||
midPos.push_back(array.detPos[i]+length/2.);
|
||||
}else{
|
||||
midPos.push_back(array.detPos[i]-length/2.);
|
||||
}
|
||||
// printf("%2d | %f \n", i, midPos.back());
|
||||
}
|
||||
//=============================================================
|
||||
//=============================================================
|
||||
//=============================================================
|
||||
//===== Set Reaction
|
||||
TransferReaction reaction;
|
||||
int AB = AA+Aa-Ab, zB = zA+za-zb;
|
||||
reaction.SetA(AA,zA);
|
||||
reaction.Seta(Aa,za);
|
||||
reaction.Setb(Ab,zb);
|
||||
reaction.SetB(AB,zB);
|
||||
reaction.SetIncidentEnergyAngle(KEAmean, 0, 0);
|
||||
reaction.SetExB(Ex);
|
||||
reaction.SetExA(ExA);
|
||||
reaction.CalReactionConstant();
|
||||
|
||||
printf("===================================================\n");
|
||||
printf("=========== %27s ===========\n", reaction.GetReactionName().Data());
|
||||
printf("===================================================\n");
|
||||
printf("----- loading reaction from : %s. \n", basicConfig.c_str());
|
||||
printf(" Ex A: %7.3f MeV\n", ExA);
|
||||
printf(" KE: %7.4f \n", KEAmean);
|
||||
printf(" theta: %7.4f \n", thetaMean);
|
||||
printf("offset(x,y): %7.4f, %7.4f mm \n", xBeam, yBeam);
|
||||
printf(" Q-value: %7.4f MeV \n", reaction.GetQValue() );
|
||||
printf(" Max Ex: %7.4f MeV \n", reaction.GetMaxExB() );
|
||||
printf("===================================================\n");
|
||||
|
||||
|
||||
printf("----- loading detector geometery : %s.", detGeoFileName.c_str());
|
||||
TMacro * kaka = new TMacro();
|
||||
if( kaka->ReadFile(detGeoFileName.c_str()) > 0 ){
|
||||
detGeo = AnalysisLib::LoadDetectorGeo(kaka);
|
||||
|
||||
pos = detGeo.array1.detPos;
|
||||
a = detGeo.array1.detPerpDist;
|
||||
length = detGeo.array1.detLength;
|
||||
firstPos = detGeo.array1.firstPos;
|
||||
iDet = detGeo.array1.nDet;
|
||||
jDet = detGeo.array1.mDet;
|
||||
BField = detGeo.Bfield;
|
||||
|
||||
printf("... done.\n");
|
||||
|
||||
printf("==== ThetaCM in degree =================\n");
|
||||
printf(" x-ratio : %f, number of division : %d \n", XRATION, nDivision);
|
||||
printf("\n");
|
||||
for( int j = 0; j < nDivision + 1; j++) printf("%5.2f ", -XRATION + 2*XRATION/nDivision*j);
|
||||
printf(" <<-- in X \n");
|
||||
for( int j = 0; j < nDivision + 1; j++) printf("%5s ", " | ");
|
||||
printf("\n");
|
||||
for( int j = 0; j < nDivision + 1; j++) printf("%5.2f ", length/2 -length*XRATION/2 + length*XRATION/nDivision*j);
|
||||
printf(" <<-- in mm \n\n");
|
||||
printf("========================= Ex : %6.4f MeV\n", Ex);
|
||||
printf(" %6s - %6s | %6s, %6s, %6s\n", "Min", "Max", "Mean", "Dt", "sin(x)dx * 180/pi");
|
||||
printf("-------------------------------------------------\n");
|
||||
for( int i = 0; i < iDet; i++){
|
||||
double zMin = midPos[i]-length*XRATION/2.;
|
||||
double zMax = midPos[i]+length*XRATION/2.;
|
||||
double zLength = zMax - zMin;
|
||||
double zStep = zLength/(nDivision);
|
||||
for( int j = 0 ; j < nDivision ; j++){
|
||||
|
||||
double tMin = (zMin + j*zStep > zMin0) ? tx->Eval(zMin + j*zStep) : TMath::QuietNaN();
|
||||
double tMax = (zMin + (j+1)*zStep > zMin0) ? tx->Eval(zMin + (j+1)*zStep) : TMath::QuietNaN();
|
||||
|
||||
double tMean = (tMax + tMin)/2.;
|
||||
double dt = (tMax - tMin);
|
||||
|
||||
double sintdt = TMath::Sin(tMean * TMath::DegToRad()) * dt ;
|
||||
AnalysisLib::PrintDetGeo(detGeo);
|
||||
|
||||
}else{
|
||||
printf("... fail\n");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
vector<double> midPos;
|
||||
|
||||
for(int i = 0; i < iDet; i++){
|
||||
if( firstPos > 0 ){
|
||||
midPos.push_back(pos[i]+length/2.);
|
||||
}else{
|
||||
midPos.push_back(pos[i]-length/2.);
|
||||
}
|
||||
}
|
||||
|
||||
//calculate a TGraph for thetaCM vs z
|
||||
double px[100];
|
||||
double py[100];
|
||||
|
||||
double mb = reaction.GetMass_b();
|
||||
double kCM = reaction.GetMomentumbCM();
|
||||
double q = TMath::Sqrt(mb*mb + kCM * kCM );
|
||||
double beta = reaction.GetReactionBeta() ;
|
||||
double slope = 299.792458 * zb * abs(BField) / TMath::TwoPi() * beta / 1000.; // MeV/mm
|
||||
double gamma = reaction.GetReactionGamma();
|
||||
for(int i = 0; i < 100; i++){
|
||||
double thetacm = (i + 5.) * TMath::DegToRad();
|
||||
double temp = TMath::TwoPi() * slope / beta / kCM * a / TMath::Sin(thetacm);
|
||||
px[i] = beta /slope * (gamma * beta * q - gamma * kCM * TMath::Cos(thetacm)) * (1 - TMath::ASin(temp)/TMath::TwoPi());
|
||||
py[i] = thetacm * TMath::RadToDeg();
|
||||
}
|
||||
|
||||
|
||||
printf(" det-%d[%d]: %6.2f - %6.2f | %6.2f, %6.2f, %6.4f\n", i, j, tMin, tMax, tMean, dt, sintdt);
|
||||
//find minimum z position
|
||||
TGraph * xt = new TGraph(100, py, px);
|
||||
xt->SetName("xt");
|
||||
///double zMin0 = xt->Eval(0);
|
||||
///printf("z for thetaCM = 0 : %f mm \n", zMin0);
|
||||
|
||||
///xt->Draw("AC*");
|
||||
|
||||
/// find the minimum z position and the corresponding theta
|
||||
double zMin0 = 0;
|
||||
double tMin0 = 0;
|
||||
for( double ttt = 3 ; ttt < 20 ; ttt += 0.1 ){
|
||||
double zzz = xt->Eval(ttt);
|
||||
if( zzz < zMin0 ) {
|
||||
zMin0 = zzz;
|
||||
tMin0 = ttt;
|
||||
}
|
||||
}
|
||||
printf(" z min %f mm at thetaCM %f deg \n", zMin0, tMin0);
|
||||
|
||||
|
||||
TGraph * tx = new TGraph(100, px, py);
|
||||
tx->SetName(Form("tx"));
|
||||
tx->SetLineColor(4);
|
||||
|
||||
//tx->Draw("AC*");
|
||||
|
||||
/**///========================================================= result
|
||||
|
||||
}
|
||||
if( nDivision > 0 ) printf("--------------\n");
|
||||
}
|
||||
printf("================================================= \n");
|
||||
printf("==== ThetaCM in degree =================\n");
|
||||
printf("========================= x-ratio : %f, number of division : %d \n", XRATION, nDivision);
|
||||
printf("\n");
|
||||
for( int j = 0; j < nDivision + 1; j++) printf("%5.2f ", -XRATION + 2*XRATION/nDivision*j);
|
||||
printf(" <<-- in X \n");
|
||||
for( int j = 0; j < nDivision + 1; j++) printf("%5s ", " | ");
|
||||
printf("\n");
|
||||
for( int j = 0; j < nDivision + 1; j++) printf("%5.2f ", length/2 -length*XRATION/2 + length*XRATION/nDivision*j);
|
||||
printf(" <<-- in cm \n\n");
|
||||
printf("========================= Ex : %6.4f MeV\n", Ex);
|
||||
printf(" %6s - %6s | %6s, %6s, %6s\n", "Min", "Max", "Mean", "Dt", "sin(x)dx * 180/pi");
|
||||
printf("-------------------------------------------------\n");
|
||||
for( int i = 0; i < iDet; i++){
|
||||
double zMin = midPos[i]-length*XRATION/2.;
|
||||
double zMax = midPos[i]+length*XRATION/2.;
|
||||
double zLength = zMax - zMin;
|
||||
double zStep = zLength/(nDivision);
|
||||
for( int j = 0 ; j < nDivision ; j++){
|
||||
|
||||
double tMin = (zMin + j*zStep > zMin0) ? tx->Eval(zMin + j*zStep) : TMath::QuietNaN();
|
||||
double tMax = (zMin + (j+1)*zStep > zMin0) ? tx->Eval(zMin + (j+1)*zStep) : TMath::QuietNaN();
|
||||
|
||||
double tMean = (tMax + tMin)/2.;
|
||||
double dt = (tMax - tMin);
|
||||
|
||||
double sintdt = TMath::Sin(tMean * TMath::DegToRad()) * dt ;
|
||||
|
||||
|
||||
printf(" det-%d[%d]: %6.2f - %6.2f | %6.2f, %6.2f, %6.4f\n", i, j, tMin, tMax, tMean, dt, sintdt);
|
||||
|
||||
}
|
||||
if( nDivision > 0 ) printf("--------------\n");
|
||||
}
|
||||
printf("================================================= \n");
|
||||
|
||||
}
|
||||
|
|
1534
Cleopatra/HELIOS_LIB.h
Normal file
|
@ -26,9 +26,9 @@
|
|||
|
||||
#include <stdlib.h> /* atof */
|
||||
#include <vector>
|
||||
#include "../Cleopatra/ClassIsotope.h" // for geting Z
|
||||
#include "../Cleopatra/Isotope.h" // for geting Z
|
||||
#include "potentials.h"
|
||||
#include "../Armory/AnalysisLib.h"
|
||||
#include "../armory/AnalysisLib.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
|
||||
#include <fstream>
|
||||
#include <stdlib.h>
|
||||
#include "ClassIsotope.h"
|
||||
#include "Isotope.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
|
|
|
@ -20,8 +20,9 @@
|
|||
#include "constant.h" // amu
|
||||
#include <stdlib.h> //atoi
|
||||
#include <algorithm>
|
||||
using namespace std;
|
||||
|
||||
std::string massData="../Cleopatra/mass20.txt";
|
||||
string massData="/Cleopatra/mass20.txt";
|
||||
|
||||
// about the mass**.txt
|
||||
// Mass Excess = (ATOMIC MASS - A)*amu | e.g. n : (1.088664.91585E-6-1)*amu
|
||||
|
@ -33,17 +34,15 @@ class Isotope {
|
|||
public:
|
||||
int A, Z;
|
||||
double Mass, MassError, BEA;
|
||||
std::string Name, Symbol;
|
||||
std::string dataSource;
|
||||
string Name, Symbol;
|
||||
string dataSource;
|
||||
|
||||
Isotope(){dataSource = massData;};
|
||||
Isotope(int a, int z){ dataSource = massData; SetIso(a,z); };
|
||||
Isotope(std::string name){ dataSource = massData; SetIsoByName(name); };
|
||||
|
||||
void SetMassTablePath(std::string path){ dataSource = path;}
|
||||
Isotope(){findHeliosPath();};
|
||||
Isotope(int a, int z){ findHeliosPath();SetIso(a,z); };
|
||||
Isotope(string name){ findHeliosPath(); SetIsoByName(name); };
|
||||
|
||||
void SetIso(int a, int z);
|
||||
void SetIsoByName(std::string name);
|
||||
void SetIsoByName(string name);
|
||||
|
||||
double CalSp(int Np, int Nn); // this for the Np-proton, Nn-neutron removal
|
||||
double CalSp2(int a, int z); // this is for (a,z) nucleus removal
|
||||
|
@ -60,10 +59,10 @@ public:
|
|||
|
||||
private:
|
||||
void FindMassByAZ(int a, int z); // give mass, massError, BEA, Name, Symbol;
|
||||
void FindMassByName(std::string name); // give Z, mass, massError, BEA;
|
||||
void FindMassByName(string name); // give Z, mass, massError, BEA;
|
||||
|
||||
int TwoJ(int nShell);
|
||||
std::string Orbital(int nShell);
|
||||
string Orbital(int nShell);
|
||||
int magic(int i){
|
||||
switch (i){
|
||||
case 0: return 2; break;
|
||||
|
@ -110,7 +109,21 @@ private:
|
|||
lineMass200 = 2774;
|
||||
}
|
||||
|
||||
char * heliosPath;
|
||||
bool isFindOnce;
|
||||
|
||||
void findHeliosPath(){
|
||||
heliosPath = getenv("HELIOSSYS");
|
||||
if( heliosPath ){
|
||||
dataSource = heliosPath;
|
||||
dataSource += "/analysis" + massData;
|
||||
}else{
|
||||
dataSource = ".." + massData;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
@ -120,16 +133,16 @@ void Isotope::SetIso(int a, int z){
|
|||
FindMassByAZ(a,z);
|
||||
}
|
||||
|
||||
void Isotope::SetIsoByName(std::string name){
|
||||
void Isotope::SetIsoByName(string name){
|
||||
FindMassByName(name);
|
||||
}
|
||||
|
||||
void Isotope::FindMassByAZ(int A, int Z){
|
||||
std::string line;
|
||||
string line;
|
||||
int lineNum=0;
|
||||
int list_A, list_Z;
|
||||
|
||||
std::ifstream myfile;
|
||||
ifstream myfile;
|
||||
int flag=0;
|
||||
|
||||
setFileLines();
|
||||
|
@ -158,11 +171,11 @@ void Isotope::FindMassByAZ(int A, int Z){
|
|||
this->BEA = atof((line.substr(54,11)).c_str());
|
||||
this->Mass = list_Z*mp + (list_A-list_Z)*mn - this->BEA/1000*list_A;
|
||||
this->MassError = atof((line.substr(65,7)).c_str());
|
||||
std::string str = line.substr(20,2);
|
||||
string str = line.substr(20,2);
|
||||
str.erase(remove(str.begin(), str.end(), ' '), str.end());
|
||||
this->Symbol = str;
|
||||
|
||||
std::ostringstream ss;
|
||||
ostringstream ss;
|
||||
ss << A << this->Symbol;
|
||||
this->Name = ss.str();
|
||||
flag = 1;
|
||||
|
@ -189,7 +202,7 @@ void Isotope::FindMassByAZ(int A, int Z){
|
|||
}
|
||||
}
|
||||
|
||||
void Isotope::FindMassByName(std::string name){
|
||||
void Isotope::FindMassByName(string name){
|
||||
|
||||
// done seperate the Mass number and the name
|
||||
if( name == "n" ) {
|
||||
|
@ -207,7 +220,7 @@ void Isotope::FindMassByName(std::string name){
|
|||
if( name == "t" ) name = "3H";
|
||||
if( name == "a" ) name = "4He";
|
||||
|
||||
std::string temp = name;
|
||||
string temp = name;
|
||||
int lastDigit = 0;
|
||||
|
||||
for(int i=0; temp[i]; i++){
|
||||
|
@ -238,12 +251,12 @@ void Isotope::FindMassByName(std::string name){
|
|||
//printf(" Symbol = |%s| , Mass = %d\n", this->Symbol.c_str(), this->A);
|
||||
|
||||
// find the nucleus in the data
|
||||
std::string line;
|
||||
string line;
|
||||
int lineNum=0;
|
||||
int list_A;
|
||||
std::string list_symbol;
|
||||
string list_symbol;
|
||||
|
||||
std::ifstream myfile;
|
||||
ifstream myfile;
|
||||
int flag=0;
|
||||
|
||||
setFileLines();
|
||||
|
@ -276,11 +289,11 @@ void Isotope::FindMassByName(std::string name){
|
|||
this->Mass = this->Z*mp + (list_A-this->Z)*mn - this->BEA/1000*list_A;
|
||||
this->MassError = atof((line.substr(65,7)).c_str());
|
||||
|
||||
std::string str = line.substr(20,2);
|
||||
string str = line.substr(20,2);
|
||||
str.erase(remove(str.begin(), str.end(), ' '), str.end());
|
||||
this->Symbol = str;
|
||||
|
||||
std::ostringstream ss;
|
||||
ostringstream ss;
|
||||
ss << this->A << this->Symbol;
|
||||
this->Name = ss.str();
|
||||
flag = 1;
|
||||
|
@ -359,7 +372,7 @@ int Isotope::TwoJ(int nShell){
|
|||
return 0;
|
||||
}
|
||||
|
||||
std::string Isotope::Orbital(int nShell){
|
||||
string Isotope::Orbital(int nShell){
|
||||
|
||||
switch(nShell){
|
||||
case 0: return "0s1 "; break; //
|
||||
|
@ -403,7 +416,7 @@ void Isotope::ListShell(){
|
|||
int n = A-Z;
|
||||
int p = Z;
|
||||
|
||||
int k = std::min(n,p);
|
||||
int k = min(n,p);
|
||||
int nMagic = 0;
|
||||
for( int i = 0; i < 7; i++){
|
||||
if( magic(i) < k && k <= magic(i+1) ){
|
||||
|
@ -421,7 +434,7 @@ void Isotope::ListShell(){
|
|||
|
||||
printf("------------------ Core:%3s, inner Core:%3s \n", (core2.Name).c_str(), (core1.Name).c_str());
|
||||
printf(" || ");
|
||||
int t = std::max(n,p);
|
||||
int t = max(n,p);
|
||||
int nShell = 0;
|
||||
do{
|
||||
int occ = TwoJ(nShell)+1;
|
||||
|
@ -499,6 +512,8 @@ void Isotope::Print(){
|
|||
|
||||
if (Mass > 0){
|
||||
|
||||
findHeliosPath();
|
||||
|
||||
printf(" using mass data : %s \n", dataSource.c_str());
|
||||
printf(" mass of \e[47m\e[31m%s\e[m nucleus (Z,A)=(%3d,%3d) is \e[47m\e[31m%12.5f\e[m MeV, BE/A=%7.5f MeV\n", Name.c_str(), Z, A, Mass, BEA/1000.);
|
||||
printf(" total BE : %12.5f MeV\n",BEA*A/1000.);
|
54
Cleopatra/IsotopeShort.C
Normal file
|
@ -0,0 +1,54 @@
|
|||
/***********************************************************************
|
||||
*
|
||||
* This is IsotopeShort.C for isotope mass-related quatilies
|
||||
* for python web
|
||||
*
|
||||
* -----------------------------------------------------
|
||||
* To compile
|
||||
*
|
||||
* g++ IsotopeShort.C -o IsotopesShort
|
||||
*
|
||||
* ------------------------------------------------------
|
||||
* created by Ryan (Tsz Leung) Tang, Feb-20, 2021
|
||||
* email: goluckyryan@gmail.com
|
||||
* ********************************************************************/
|
||||
|
||||
#include <fstream>
|
||||
#include <stdlib.h>
|
||||
#include "Isotope.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
void Usage(){
|
||||
cout << "./NuclearData Sym" << endl;
|
||||
cout << "./NuclearData A Z" << endl;
|
||||
exit(0);
|
||||
}
|
||||
|
||||
int main (int argc, char *argv[]) {
|
||||
|
||||
if ( argc != 2 && argc != 3 && argc != 6) Usage();
|
||||
|
||||
Isotope iso1, iso2;
|
||||
int Z, A, Za, Aa;
|
||||
if (argc == 2){
|
||||
iso1.SetIsoByName(argv[1]);
|
||||
}
|
||||
if (argc == 3){
|
||||
A= atoi(argv[1]);
|
||||
Z= atoi(argv[2]);
|
||||
iso1.SetIso(A, Z);
|
||||
}
|
||||
|
||||
//iso1.Print();
|
||||
printf("A:%3d\n", iso1.A);
|
||||
printf("Z:%3d\n", iso1.Z);
|
||||
printf("N:%3d\n", iso1.A-iso1.Z);
|
||||
printf("Name:%s|\n",iso1.Name.c_str());
|
||||
printf("Mass:%13.4f\n", iso1.Mass);
|
||||
printf("Sn:%13.4f\n", iso1.CalSp(0,1));
|
||||
printf("Sp:%13.4f\n", iso1.CalSp(1,0));
|
||||
printf("Sa:%13.4f\n", iso1.CalSp2(4,2));
|
||||
printf("S2n:%13.4f\n", iso1.CalSp(0,2));
|
||||
|
||||
}
|
31
Cleopatra/PlotSimulation.C
Normal file
|
@ -0,0 +1,31 @@
|
|||
|
||||
#include <fstream>
|
||||
#include <stdlib.h>
|
||||
#include "Check_Simulation.C"
|
||||
|
||||
using namespace std;
|
||||
|
||||
int main (int argc, char *argv[]) {
|
||||
|
||||
printf("=================================================================\n");
|
||||
printf("=================== Plot Simulation Canvas ======================\n");
|
||||
printf("=================================================================\n");
|
||||
|
||||
if(argc < 2 ) {
|
||||
printf("Usage: ./PlotSimulation input_root_file [config]\n");
|
||||
exit(0);
|
||||
}else{
|
||||
printf("ROOT file : %s \n", argv[1]);
|
||||
}
|
||||
|
||||
string rootFile = argv[1];
|
||||
string config = "../Armory/Check_Simulation_Config.txt";
|
||||
if( argc >= 3 ) config = argv[2];
|
||||
|
||||
printf("Config File : %s \n", config.c_str());
|
||||
|
||||
Int_t padSize = 500;
|
||||
|
||||
Check_Simulation(rootFile, config, padSize, true);
|
||||
|
||||
}
|
|
@ -30,7 +30,7 @@ void PlotTGraphTObjArray(TString rootFileName, bool isSavePNG = false){
|
|||
|
||||
TFile * file = new TFile(rootFileName, "READ");
|
||||
|
||||
TObjArray * gList = (TObjArray *) file->FindObjectAny("thetaCM_TGraph");
|
||||
TObjArray * gList = (TObjArray *) file->FindObjectAny("qList");
|
||||
|
||||
if( gList == NULL ) {
|
||||
printf("No Result was found.\n");
|
||||
|
|
|
@ -1,132 +0,0 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
#============== experimental Simulation Helper using PyROOT and PyQT
|
||||
#
|
||||
# need pip install PyQt6
|
||||
# need to make at Cleopatra
|
||||
#
|
||||
#=====================================================
|
||||
|
||||
import sys
|
||||
from PyQt6.QtCore import Qt
|
||||
from PyQt6.QtWidgets import QApplication, QWidget, QMainWindow, QLabel, QPushButton, QVBoxLayout, QPlainTextEdit, QGroupBox, QGridLayout
|
||||
import subprocess
|
||||
import ROOT
|
||||
import webbrowser
|
||||
|
||||
def SaveTxtFromEditor():
|
||||
if presentFileName != "" :
|
||||
with open(presentFileName, "w") as f:
|
||||
f.write(editor.toPlainText())
|
||||
|
||||
def LoadTxtToEditor(txtFileName):
|
||||
global presentFileName
|
||||
SaveTxtFromEditor()
|
||||
|
||||
presentFileName = txtFileName
|
||||
with open(txtFileName) as f:
|
||||
text = f.read()
|
||||
editor.setPlainText(text)
|
||||
|
||||
def RunSimulation():
|
||||
SaveTxtFromEditor()
|
||||
bash_command = "../Cleopatra/SimTransfer reactionConfig.txt detectorGeo.txt 0 '' transfer.root"
|
||||
process = subprocess.Popen(bash_command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||
output, error = process.communicate()
|
||||
if process.returncode != 0:
|
||||
print("Error:", error.decode())
|
||||
else:
|
||||
print("Output:", output.decode())
|
||||
|
||||
|
||||
def OpenHttpServer():
|
||||
global ser, file, tree
|
||||
file = ROOT.TFile("transfer.root", "read")
|
||||
tree = file.Get("tree")
|
||||
|
||||
hEZ = ROOT.TH2F("hEZ", "E - Z; z[mm]; e[MeV]", 400, -600, 0, 400, 0, 10)
|
||||
hXY = ROOT.TH2F("hXY", "Array; X[mm]; Y[MeV]", 200, -20, 20, 200, -20, 20)
|
||||
hRecoilXY = ROOT.TH2F("hRecoilXY", "Recoil; X[mm]; Y[MeV]", 400, -60, 60, 400, -60, 60)
|
||||
hThetaCMZ = ROOT.TH2F("hThetaCMZ", "TheatCM - Z; X[mm]; thetaCM [deg]", 400, -600, 0, 400, 0, 60)
|
||||
hExCal = ROOT.TH1F("hExCal", "ExCal; MeV", 400, -1, 5)
|
||||
|
||||
|
||||
for event in tree:
|
||||
if( event.hit != 1 or event.thetaCM < 10 or event.loop != 1) : continue
|
||||
|
||||
hEZ.Fill(event.array_hit_z, event.energy_light) # x, y
|
||||
hXY.Fill(event.xArray, event.yArray)
|
||||
hRecoilXY.Fill(event.xRecoil, event.yRecoil)
|
||||
hThetaCMZ.Fill(event.array_hit_z, event.thetaCM)
|
||||
hExCal.Fill(event.ExCal)
|
||||
|
||||
|
||||
ser = ROOT.THttpServer("http:9876")
|
||||
# ser.SetJSROOT("https://root.cern.ch/js/latest/")
|
||||
|
||||
ser.Register("/", hEZ)
|
||||
ser.Register("/", hXY)
|
||||
ser.Register("/", hRecoilXY)
|
||||
ser.Register("/", hThetaCMZ)
|
||||
ser.Register("/", hExCal)
|
||||
|
||||
ser.SetItemField("/","_layout","grid4x4")
|
||||
ser.SetItemField("/","_drawitem","[hEZ, hRecoilXY, hExCal, hThetaCM]")
|
||||
|
||||
webbrowser.open("http://localhost:9876/")
|
||||
|
||||
|
||||
########################################################
|
||||
if __name__ == "__main__":
|
||||
|
||||
app = QApplication(sys.argv)
|
||||
editor = QPlainTextEdit()
|
||||
|
||||
presentFileName = ""
|
||||
|
||||
ser = None
|
||||
file = None
|
||||
tree = None
|
||||
|
||||
window = QMainWindow()
|
||||
window.setWindowTitle("Simulation Helper")
|
||||
window.setFixedSize(800, 1000)
|
||||
|
||||
mainWidget = QWidget()
|
||||
window.setCentralWidget(mainWidget)
|
||||
|
||||
layout = QGridLayout()
|
||||
mainWidget.setLayout(layout)
|
||||
|
||||
reactionGroup = QGroupBox("Reaction", window)
|
||||
layout.addWidget(reactionGroup, 0, 0)
|
||||
reactionLayout = QVBoxLayout(reactionGroup)
|
||||
|
||||
bDetGeo = QPushButton("Detector Geo", reactionGroup)
|
||||
reactionLayout.addWidget(bDetGeo)
|
||||
bDetGeo.clicked.connect(lambda : LoadTxtToEditor("detectorGeo.txt"))
|
||||
|
||||
bReactionConfig = QPushButton("Reaction Config", reactionGroup)
|
||||
reactionLayout.addWidget(bReactionConfig)
|
||||
bReactionConfig.clicked.connect(lambda : LoadTxtToEditor("reactionConfig.txt"))
|
||||
|
||||
bSim = QPushButton("Simulation", reactionGroup)
|
||||
reactionLayout.addWidget(bSim)
|
||||
bSim.clicked.connect(RunSimulation)
|
||||
|
||||
bTest = QPushButton("Open Browser", reactionGroup)
|
||||
reactionLayout.addWidget(bTest)
|
||||
bTest.clicked.connect(OpenHttpServer)
|
||||
|
||||
layout.addWidget(editor, 0, 1, 5, 5)
|
||||
LoadTxtToEditor("detectorGeo.txt")
|
||||
|
||||
# # Create PyQtGraph plot
|
||||
# plot = PlotWidget()
|
||||
# plot_item = plot.getPlotItem()
|
||||
# plot_item.plot(x=[1, 2, 3], y=[4, 6, 2])
|
||||
# layout.addWidget(plot)
|
||||
|
||||
# Show the window and start the event loop
|
||||
window.show()
|
||||
sys.exit(app.exec())
|
|
@ -1,181 +0,0 @@
|
|||
#include "../Cleopatra/ClassHelios.h"
|
||||
#include "TROOT.h"
|
||||
#include "TBenchmark.h"
|
||||
#include "TLorentzVector.h"
|
||||
#include "TMath.h"
|
||||
#include "TFile.h"
|
||||
#include "TF1.h"
|
||||
#include "TTree.h"
|
||||
#include "TRandom.h"
|
||||
#include <stdlib.h>
|
||||
#include <vector>
|
||||
#include <fstream>
|
||||
#include <TObjArray.h>
|
||||
|
||||
//----------- usage
|
||||
// $root transfer.C+ | tee output.txt
|
||||
// this will same the massage to output.txt
|
||||
|
||||
const double ma = 3727.3792; // alpha mass
|
||||
|
||||
void alpha( int numEvent = 100000){
|
||||
|
||||
//================================================= User Setting
|
||||
std::string heliosDetGeoFile = "detectorGeo.txt";
|
||||
int geoID = 0;
|
||||
|
||||
//std::vector<double> energy = {3.18, 5.16, 5.49, 5.81};
|
||||
std::vector<double> energy = {5.34, 5.42, 5.68, 6.05, 6.23, 6.77, 8.78}; //228Th
|
||||
|
||||
//---- Over-ride HELIOS detector geometry
|
||||
// double BField = 2.5; // T
|
||||
// double BFieldTheta = 0.; // direction of B-field
|
||||
// bool isCoincidentWithRecoil = false;
|
||||
// double eSigma = 0.040 ; // detector energy sigma MeV
|
||||
// double zSigma = 0.500 ; // detector position sigma mm
|
||||
|
||||
//---- save root file name
|
||||
TString saveFileName = "SimAlpha.root";
|
||||
|
||||
//=============================================================
|
||||
//=============================================================
|
||||
|
||||
printf("===================================================\n");
|
||||
printf("============= Alpha source in HELIOS ============\n");
|
||||
printf("===================================================\n");
|
||||
|
||||
int numEnergy = energy.size();
|
||||
printf("========= Alpha Enegry : \n");
|
||||
for( int i = 0; i < numEnergy ; i++){
|
||||
printf("%2d | %6.2f MeV\n", i, energy[i]);
|
||||
}
|
||||
|
||||
|
||||
//======== Set HELIOS
|
||||
printf("############################################## HELIOS configuration\n");
|
||||
HELIOS helios;
|
||||
// helios.OverrideMagneticFieldDirection(BFieldTheta);
|
||||
// helios.OverrideFirstPos(-700);
|
||||
//helios.OverrideDetectorDistance(5);
|
||||
// bool sethelios = helios.SetDetectorGeometry(heliosDetGeoFile, geoID);
|
||||
// if( !sethelios){
|
||||
// helios.OverrideMagneticField(BField);
|
||||
// printf("======== B-field : %5.2f T, Theta : %6.2f deg\n", BField, BFieldTheta);
|
||||
// }
|
||||
// helios.SetCoincidentWithRecoil(isCoincidentWithRecoil);
|
||||
// printf("========== energy resol.: %f MeV\n", eSigma);
|
||||
// printf("=========== pos-Z resol.: %f mm \n", zSigma);
|
||||
helios.SetDetectorGeometry(heliosDetGeoFile, geoID);
|
||||
helios.PrintGeometry();
|
||||
|
||||
//====================== build tree
|
||||
TFile * saveFile = new TFile(saveFileName, "recreate");
|
||||
TTree * tree = new TTree("tree", "tree");
|
||||
|
||||
double theta, phi, T;
|
||||
|
||||
int hit; // the output of Helios.CalHit
|
||||
double e, z, x, t;
|
||||
int loop, detID;
|
||||
double dphi, rho; //rad of rotation, and radius
|
||||
int energyID;
|
||||
double xHit, yHit;
|
||||
|
||||
tree->Branch("hit", &hit, "hit/I");
|
||||
tree->Branch("theta", &theta, "theta/D");
|
||||
tree->Branch("phi", &phi, "phi/D");
|
||||
tree->Branch("T", &T, "T/D");
|
||||
tree->Branch("energy", &energy, "energy/D");
|
||||
tree->Branch("energyID", &energyID, "energyID/I");
|
||||
|
||||
tree->Branch("e", &e, "e/D");
|
||||
tree->Branch("z", &z, "z/D");
|
||||
tree->Branch("t", &t, "t/D");
|
||||
tree->Branch("detID", &detID, "detID/I");
|
||||
tree->Branch("loop", &loop, "loop/I");
|
||||
tree->Branch("dphi", &dphi, "dphi/D");
|
||||
tree->Branch("rho", &rho, "rho/D");
|
||||
tree->Branch("xHit", &xHit, "xHit/D");
|
||||
tree->Branch("yHit", &yHit, "yHit/D");
|
||||
|
||||
//========timer
|
||||
TBenchmark clock;
|
||||
bool shown ;
|
||||
clock.Reset();
|
||||
clock.Start("timer");
|
||||
shown = false;
|
||||
printf("############################################## generating %d events \n", numEvent);
|
||||
|
||||
//====================================================== calculate
|
||||
int count = 0;
|
||||
TLorentzVector P;
|
||||
TVector3 v;
|
||||
for( int i = 0; i < numEvent; i++){
|
||||
//==== generate alpha
|
||||
theta = TMath::ACos(2 * gRandom->Rndm() - 1) ;
|
||||
phi = TMath::TwoPi() * gRandom->Rndm();
|
||||
|
||||
energyID = gRandom->Integer(numEnergy);
|
||||
T = energy[energyID];
|
||||
|
||||
double p = TMath::Sqrt( ( ma + T )*(ma + T) - ma* ma);
|
||||
|
||||
v.SetMagThetaPhi(p, theta, phi);
|
||||
|
||||
P.SetVectM(v, ma);
|
||||
P.SetUniqueID(2); //alpha particle has charge 2
|
||||
|
||||
//################################### tree branches
|
||||
|
||||
//==== Helios
|
||||
helios.CalArrayHit(P);
|
||||
hit = helios.CheckDetAcceptance();
|
||||
|
||||
e = helios.GetEnergy() + gRandom->Gaus(0, helios.GetDetectorGeometry().array[geoID].eSigma);
|
||||
|
||||
trajectory orb = helios.GetTrajectory_b();
|
||||
|
||||
z = orb.z + gRandom->Gaus(0, helios.GetDetectorGeometry().array[geoID].zSigma);
|
||||
t = orb.t;
|
||||
loop = orb.effLoop;
|
||||
detID = orb.detID;
|
||||
dphi = orb.phi;
|
||||
rho = orb.rho;
|
||||
xHit = orb.x;
|
||||
yHit = orb.y;
|
||||
|
||||
if( hit == 1) {
|
||||
count ++;
|
||||
}
|
||||
|
||||
tree->Fill();
|
||||
|
||||
//#################################################################### Timer
|
||||
clock.Stop("timer");
|
||||
Double_t time = clock.GetRealTime("timer");
|
||||
clock.Start("timer");
|
||||
|
||||
if ( !shown ) {
|
||||
if (fmod(time, 10) < 1 ){
|
||||
printf( "%10d[%2d%%]| %8.2f sec | expect: %5.1f min \n", i, TMath::Nint((i+1)*100./numEvent), time , numEvent*time/(i+1)/60);
|
||||
shown = 1;
|
||||
}
|
||||
}else{
|
||||
if (fmod(time, 10) > 9 ){
|
||||
shown = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
saveFile->Write();
|
||||
saveFile->Close();
|
||||
|
||||
printf("=============== done. saved as %s. count(hit==1) : %d\n", saveFileName.Data(), count);
|
||||
gROOT->ProcessLine(".q");
|
||||
}
|
||||
|
||||
int main(){
|
||||
|
||||
alpha();
|
||||
return 0;
|
||||
}
|
|
@ -1,235 +0,0 @@
|
|||
#include <TFile.h>
|
||||
#include <TTree.h>
|
||||
#include <TCanvas.h>
|
||||
#include <TROOT.h>
|
||||
#include <TObjArray.h>
|
||||
#include <TStyle.h>
|
||||
#include <TH2F.h>
|
||||
#include <TH1F.h>
|
||||
#include <TF1.h>
|
||||
#include <TArc.h>
|
||||
#include <TMath.h>
|
||||
#include <TLine.h>
|
||||
#include <TSpectrum.h>
|
||||
#include <TGraph.h>
|
||||
#include <TLegend.h>
|
||||
#include <TLatex.h>
|
||||
#include <TMacro.h>
|
||||
#include <TObjArray.h>
|
||||
#include <fstream>
|
||||
#include <TCutG.h>
|
||||
#include "../Armory/AnalysisLib.h"
|
||||
#include "../Armory/ClassDetGeo.h"
|
||||
#include "../Armory/ClassReactionConfig.h"
|
||||
#include "../Cleopatra/ClassIsotope.h"
|
||||
#include "../Cleopatra/ClassTransfer.h"
|
||||
#include "../Cleopatra/ClassSimPlotter.h"
|
||||
|
||||
plotID StringToPlotID(TString str);
|
||||
|
||||
void SimChecker(TString filename = "transfer.root",
|
||||
TString configFile = "../working/SimCheckerConfig.txt",
|
||||
Int_t padSize = 500,
|
||||
bool outputCanvas = false){
|
||||
|
||||
printf("=================================================================\n");
|
||||
printf("==================== Simulate Checker ==================\n");
|
||||
printf("=================================================================\n");
|
||||
|
||||
TFile * file = new TFile(filename, "read");
|
||||
TTree * tree = (TTree*) file->Get("tree");
|
||||
|
||||
//*================= Get reactions and Ex
|
||||
TMacro * ListOfReactions = (TMacro *) file->FindObjectAny("ListOfReactions");
|
||||
const short numReact = ListOfReactions->GetListOfLines()->GetEntries();
|
||||
|
||||
printf(">>>>> %d reactions found.\n", numReact);
|
||||
|
||||
std::string reactionList[numReact];
|
||||
for( int i = 0; i < numReact; i++ ){
|
||||
std::string haha = ListOfReactions->GetListOfLines()->At(i)->GetName();
|
||||
std::vector<std::string> kaka = AnalysisLib::SplitStr(haha, "|");
|
||||
reactionList[i]= kaka[1];
|
||||
}
|
||||
|
||||
ExcitedEnergies reactEx[numReact]; //2-D array [i][j] = i-reaction, j-Ex
|
||||
TMacro * AllExList = (TMacro *) file->FindObjectAny("AllExList");
|
||||
|
||||
TMacro * ExID_ReactID_List = (TMacro *) file->FindObjectAny("ExID_ReactID_List");
|
||||
const short numEx = ExID_ReactID_List->GetListOfLines()->GetEntries()-1;
|
||||
|
||||
for( int i = 1; i <= numEx; i++){
|
||||
std::string haha = ExID_ReactID_List->GetListOfLines()->At(i)->GetName();
|
||||
std::vector<std::string> kaka = AnalysisLib::SplitStr(haha, " ");
|
||||
|
||||
std::string dudu = AllExList->GetListOfLines()->At(i)->GetName();
|
||||
std::vector<std::string> dada = AnalysisLib::SplitStr(dudu, " ");
|
||||
|
||||
short rID = atoi(kaka[1].c_str());
|
||||
reactEx[rID].Add(atof(dada[0].c_str()),
|
||||
atof(dada[1].c_str()),
|
||||
atof(dada[2].c_str()),
|
||||
atof(dada[3].c_str()));
|
||||
}
|
||||
|
||||
for( int i = 0; i < numReact; i++ ){
|
||||
printf("=========== %s\n", reactionList[i].c_str());
|
||||
reactEx[i].Print();
|
||||
}
|
||||
|
||||
//*================== detGeoID
|
||||
TMacro * detGeotxt = (TMacro *) file->FindObjectAny("detGeo");
|
||||
DetGeo detGeo(detGeotxt);
|
||||
detGeo.Print(true);
|
||||
|
||||
//*================== Get EZ-curve
|
||||
TObjArray * ezList = (TObjArray *) file->FindObjectAny("EZCurve");
|
||||
|
||||
//*================== Get thetaCM = 0
|
||||
TObjArray * thetaCM0List = (TObjArray *) file->FindObjectAny("thetaCM_Z");
|
||||
|
||||
//^################################################ Find e-range, z-range
|
||||
|
||||
double zRange[numReact][2];
|
||||
double eMax[numReact];
|
||||
|
||||
int count = 0;
|
||||
for( int i = 0; i < numReact; i++ ){
|
||||
zRange[i][0] = detGeo.array[i].zMin-50;
|
||||
zRange[i][1] = detGeo.array[i].zMax+50;
|
||||
|
||||
eMax[i] = -1;
|
||||
for( size_t j = 0; j < reactEx[i].ExList.size() ; j ++){
|
||||
TGraph * func = (TGraph *) ezList->At(count);
|
||||
double aaa = func->Eval(zRange[i][1]);
|
||||
// printf(" xxxxxxxxxxxx %d, %d | %d %.3f\n", i, j, count, aaa);
|
||||
if( aaa > eMax[i] ) eMax[i] = aaa;
|
||||
count++;
|
||||
}
|
||||
|
||||
eMax[i] = TMath::Ceil( eMax[i] * 1.1 );
|
||||
}
|
||||
|
||||
// for( int i = 0; i < numReact; i++ ){
|
||||
// printf(" %d | eMax : %.2f, zRange : %.2f, %.2f \n", i, eMax[i], zRange[i][0], zRange[i][1]);
|
||||
// }
|
||||
|
||||
// //^################################################
|
||||
TMacro * config = new TMacro(configFile);
|
||||
int numLine = config->GetListOfLines()->GetSize();
|
||||
|
||||
TString gate;
|
||||
std::vector<plotID> padPlotID;
|
||||
|
||||
float elumMax = 60;
|
||||
float thetaCMMax = 60; //TODO add thetaCM curves in transfer, so that it can be determinated automatically
|
||||
|
||||
int rowCount = 0;
|
||||
int colCount = 0;
|
||||
|
||||
bool startCanvasConfig = false;
|
||||
bool startGateConfig = false;
|
||||
bool startExtra = false;
|
||||
for( int i = 0; i < numLine ; i++){
|
||||
std::string haha = config->GetListOfLines()->At(i)->GetName();
|
||||
std::vector<std::string> dudu = AnalysisLib::SplitStr(haha, ",");
|
||||
TString lala = haha;
|
||||
lala.Remove(3);
|
||||
if( (lala == " " || lala == "// " || lala == "//=") && dudu.size() == 0) continue;
|
||||
if( lala == "//#" ) break;
|
||||
if( lala == "//*" ) {
|
||||
startCanvasConfig = true;
|
||||
// rowCount ++;
|
||||
continue;
|
||||
}
|
||||
if( lala == "//^" ) {
|
||||
startCanvasConfig = false;
|
||||
startGateConfig = true;
|
||||
continue;
|
||||
}
|
||||
if( lala == "//@" ) {
|
||||
startGateConfig = false;
|
||||
startExtra = true;
|
||||
}
|
||||
|
||||
if( startCanvasConfig ){
|
||||
rowCount ++;
|
||||
// printf("|%s|\n", haha.c_str());
|
||||
if( dudu.size() > colCount ) colCount = dudu.size();
|
||||
|
||||
for( size_t k = 0; k < dudu.size() ; k++){
|
||||
padPlotID.push_back(StringToPlotID(dudu[k]));
|
||||
}
|
||||
}
|
||||
|
||||
if( startGateConfig ){
|
||||
gate = haha;
|
||||
}
|
||||
|
||||
if( startExtra ){
|
||||
if( dudu[0] == "elum_Max" ) elumMax = atof(dudu[2].c_str());
|
||||
if( dudu[0] == "thetaCM_Max" ) thetaCMMax = atof(dudu[2].c_str());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
gStyle->SetOptStat("");
|
||||
gStyle->SetStatY(0.9);
|
||||
gStyle->SetStatX(0.9);
|
||||
gStyle->SetStatW(0.4);
|
||||
gStyle->SetStatH(0.2);
|
||||
gStyle->SetLabelSize(0.05, "XY");
|
||||
gStyle->SetTitleFontSize(0.1);
|
||||
|
||||
printf(" Canvas division | col : %d, row : %d \n", colCount, rowCount);
|
||||
count = 0;
|
||||
for( int i = 0; i < rowCount; i++){
|
||||
for( int j = 0; j < colCount; j++){
|
||||
printf("%6d", padPlotID[count]);
|
||||
count++;
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
printf("Gate : %s \n", gate.Data());
|
||||
printf("elum Max : %.2f mm\n", elumMax);
|
||||
printf("thetaCM Max : %.2f deg\n", thetaCMMax);
|
||||
|
||||
printf("#####################################################\n");
|
||||
|
||||
Plotter * plotter[numReact];
|
||||
|
||||
for( int i = 0; i < numReact; i++){
|
||||
plotter[i] = new Plotter(tree, i, reactionList[i], detGeo, reactEx[i], gate, padPlotID);
|
||||
plotter[i]->SetRanges(zRange[i][0], zRange[i][1], eMax[i], elumMax, thetaCMMax);
|
||||
plotter[i]->SetCanvas(colCount, rowCount, 500, padPlotID);
|
||||
plotter[i]->Plot();
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
|
||||
plotID StringToPlotID(TString str){
|
||||
|
||||
if( str == "pEZ") return plotID::pEZ; /// 0
|
||||
if( str == "pRecoilXY") return plotID::pRecoilXY; /// 1
|
||||
if( str == "pThetaCM" ) return plotID::pThetaCM; /// 2
|
||||
if( str == "pExCal" ) return plotID::pExCal; /// 3
|
||||
if( str == "pArrayXY" ) return plotID::pArrayXY; /// 4
|
||||
if( str == "pInfo" ) return plotID::pInfo; /// 5
|
||||
if( str == "pElum1XY" ) return plotID::pElum1XY; /// 6
|
||||
if( str == "pRecoilXY1" ) return plotID::pRecoilXY1; /// 7
|
||||
if( str == "pRecoilXY2" ) return plotID::pRecoilXY2; /// 8
|
||||
if( str == "pTDiffZ" ) return plotID::pTDiffZ; /// 9
|
||||
if( str == "pRecoilRThetaCM" ) return plotID::pRecoilRThetaCM; /// 10
|
||||
if( str == "pRecoilRZ" ) return plotID::pRecoilRZ; /// 11
|
||||
if( str == "pEElum1R" ) return plotID::pEElum1R; /// 12
|
||||
if( str == "pRecoilRTR" ) return plotID::pRecoilRTR; /// 13
|
||||
if( str == "pThetaCM_Z" ) return plotID::pThetaCM_Z; /// 14
|
||||
if( str == "pElum1RThetaCM" ) return plotID::pElum1RThetaCM; /// 15
|
||||
if( str == "pEmpty" ) return plotID::pEmpty ; /// 16
|
||||
|
||||
return plotID::pEmpty;
|
||||
}
|
|
@ -1,810 +0,0 @@
|
|||
#include "TROOT.h"
|
||||
#include "TBenchmark.h"
|
||||
#include "TLorentzVector.h"
|
||||
#include "TMath.h"
|
||||
#include "TFile.h"
|
||||
#include "TF1.h"
|
||||
#include "TTree.h"
|
||||
#include "TRandom.h"
|
||||
#include "TGraph.h"
|
||||
#include "TMacro.h"
|
||||
#include <stdlib.h>
|
||||
#include <vector>
|
||||
#include <fstream>
|
||||
#include <TObjArray.h>
|
||||
|
||||
#include "../Armory/ClassDetGeo.h"
|
||||
#include "ClassTargetScattering.h"
|
||||
#include "ClassDecay.h"
|
||||
#include "ClassTransfer.h"
|
||||
#include "ClassHelios.h"
|
||||
|
||||
void PrintEZPlotPara(TransferReaction tran, HELIOS helios){
|
||||
|
||||
printf("==================================== E-Z plot slope\n");
|
||||
double betaRect = tran.GetReactionBeta() ;
|
||||
double gamma = tran.GetReactionGamma();
|
||||
double mb = tran.GetMass_b();
|
||||
double pCM = tran.GetMomentumbCM();
|
||||
double q = TMath::Sqrt(mb*mb + pCM*pCM); ///energy of light recoil in center of mass
|
||||
double slope = tran.GetEZSlope(helios.GetBField()); /// MeV/mm
|
||||
printf(" e-z slope : %f MeV/mm\n", slope);
|
||||
// double intercept = q/gamma - mb; // MeV
|
||||
// printf(" e-z intercept (ground state) : %f MeV\n", intercept);
|
||||
}
|
||||
|
||||
void Transfer(
|
||||
std::string basicConfig = "reactionConfig.txt",
|
||||
std::string detGeoFile = "detectorGeo.txt",
|
||||
TString ptolemyRoot = "DWBA.root",
|
||||
TString saveFileName = "transfer.root"){
|
||||
|
||||
//*############################################# Set Reaction
|
||||
|
||||
// std::vector<double> kbCM; /// momentum of b in CM frame
|
||||
// TF1 * exDistribution = nullptr;
|
||||
|
||||
DetGeo detGeoConfig;
|
||||
ReactionConfig reactionConfig;
|
||||
|
||||
detGeoConfig.LoadDetectorGeo(detGeoFile, false);
|
||||
reactionConfig.LoadReactionConfig(basicConfig);
|
||||
|
||||
const unsigned short numDetGeo = detGeoConfig.array.size();
|
||||
const unsigned short numReact = reactionConfig.recoil.size();
|
||||
|
||||
if( numDetGeo != numReact ){
|
||||
printf("\e[31m !!!!!! number of array is not equal to number of reaction.!!! \e[0m\n");
|
||||
printf("Abort\n");
|
||||
return;
|
||||
}
|
||||
|
||||
unsigned short numTransfer = 0;
|
||||
|
||||
for( int i = 0; i < std::min(numDetGeo, numReact); i++){
|
||||
if( detGeoConfig.array[i].enable ) numTransfer ++;
|
||||
}
|
||||
|
||||
TransferReaction * transfer = new TransferReaction[numTransfer];
|
||||
Decay * decay = new Decay[numTransfer];
|
||||
HELIOS * helios = new HELIOS[numTransfer];
|
||||
|
||||
int count = 0;
|
||||
for( unsigned short i = 0 ; i < numDetGeo; i++){
|
||||
if( detGeoConfig.array[i].enable ){
|
||||
transfer[count].SetReactionFromReactionConfigClass(reactionConfig, i);
|
||||
if(transfer[count].GetRecoil().isDecay) {
|
||||
decay[count].SetMotherDaugther(transfer[count].GetRecoil());
|
||||
}
|
||||
helios[count].SetDetectorGeometry(detGeoFile, i);
|
||||
|
||||
count ++;
|
||||
}
|
||||
}
|
||||
|
||||
printf("----- loading reaction setting from %s. \n", basicConfig.c_str());
|
||||
printf("----- loading geometry setting from %s. \n", detGeoFile.c_str());
|
||||
|
||||
printf("\e[32m#################################### Reaction & HELIOS configuration\e[0m\n");
|
||||
|
||||
//*############################################# Load DWBAroot for thetaCM distribution
|
||||
TFile * distFile = new TFile(ptolemyRoot, "read");
|
||||
TObjArray * distList = nullptr;
|
||||
TMacro * dwbaExList = nullptr;
|
||||
TMacro * dwbaReactList = nullptr;
|
||||
|
||||
TMacro dwbaExList_Used;
|
||||
TMacro dwbaReactList_Used;
|
||||
|
||||
bool useDWBA[numTransfer];
|
||||
for( int i = 0; i < numTransfer; i++ ) useDWBA[i] = false;
|
||||
|
||||
if( distFile->IsOpen() ) {
|
||||
printf("\e[32m#################################### Load DWBA input : %s \e[0m\n", ptolemyRoot.Data());
|
||||
printf("--------- Found DWBA thetaCM distributions.\n");
|
||||
printf(" Checking DWBA matches withe %s.\n", basicConfig.c_str());
|
||||
|
||||
distList = (TObjArray *) distFile->FindObjectAny("thetaCM_TF1"); // the function List
|
||||
dwbaExList = (TMacro *) distFile->FindObjectAny("ExList");
|
||||
dwbaExList_Used.AddLine(dwbaExList->GetListOfLines()->At(0)->GetName());
|
||||
dwbaReactList = (TMacro *) distFile->FindObjectAny("ReactionList");
|
||||
|
||||
int numEx = dwbaExList->GetListOfLines()->GetSize() - 1 ;
|
||||
|
||||
ExcitedEnergies dwbaExTemp[numTransfer];
|
||||
|
||||
for( int i = 1; i <= numEx ; i++){
|
||||
std::string reactionName = dwbaReactList->GetListOfLines()->At(i-1)->GetName();
|
||||
printf(" %d | Checking %s from DWBA \n", i, reactionName.c_str());
|
||||
for( int j = 0; j < numTransfer; j++){
|
||||
//Check DWBA reaction is same as transfer setting
|
||||
if( reactionName.find( transfer[j].GetReactionName().Data() ) != std::string::npos) {
|
||||
printf(" >>> found %s in %s\n", transfer[j].GetReactionName().Data(), basicConfig.c_str());
|
||||
std::string temp = dwbaExList->GetListOfLines()->At(i)->GetName();
|
||||
dwbaReactList_Used.AddLine((reactionName + " | " + std::to_string(j)).c_str());
|
||||
dwbaExList_Used.AddLine(temp.c_str());
|
||||
if( temp[0] == '/' ) continue;
|
||||
std::vector<std::string> tempStr = AnalysisLib::SplitStr(temp, " ");
|
||||
dwbaExTemp[j].Add( atof(tempStr[0].c_str()), atof(tempStr[1].c_str()), 1.0, 0.00);
|
||||
}else{
|
||||
printf(" XXX Not found\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for( int i = 0; i < numTransfer; i++ ){
|
||||
if( dwbaExTemp[i].ExList.size() > 0 ) {
|
||||
transfer[i].GetExList()->Clear();
|
||||
for( size_t j = 0 ; j < dwbaExTemp[i].ExList.size(); j ++ ){
|
||||
transfer[i].GetExList()->Add( dwbaExTemp[i].ExList[j].Ex, dwbaExTemp[i].ExList[j].xsec, 1.0, 0.00);
|
||||
}
|
||||
useDWBA[i] = true;
|
||||
}else{
|
||||
printf("Cannot match %s with DWBA, use Reaction Ex List\n", transfer[i].GetReactionName().Data());
|
||||
useDWBA[i] = false;
|
||||
}
|
||||
}
|
||||
|
||||
}else{
|
||||
printf("------- no DWBA input. Use the ExList from %s\n", basicConfig.c_str());
|
||||
}
|
||||
|
||||
std::vector<bool> listOfTransfer(numTransfer, false);
|
||||
|
||||
for( int i = 0; i < numTransfer; i++){
|
||||
if( transfer[i].GetExList()->ExList.size() > 0 ){
|
||||
|
||||
listOfTransfer[i] = true;
|
||||
|
||||
transfer[i].PrintReaction(false);
|
||||
transfer[i].GetExList()->Print();
|
||||
helios[i].PrintGeometry();
|
||||
transfer[i].CreateExDistribution();
|
||||
// PrintEZPlotPara(transfer[i], helios[i]);
|
||||
}else{
|
||||
printf(" Reaction : %s has no excited energy. Skipped. \n", transfer[i].GetReactionName().Data());
|
||||
}
|
||||
}
|
||||
|
||||
//*############################################# build tree
|
||||
printf("\e[32m#################################### building Tree in %s\e[0m\n", saveFileName.Data());
|
||||
TFile * saveFile = new TFile(saveFileName, "recreate");
|
||||
TTree * tree = new TTree("tree", "tree");
|
||||
|
||||
TMacro config(basicConfig.c_str());
|
||||
TMacro detGeoTxt(detGeoFile.c_str());
|
||||
config.SetName("ReactionConfig");
|
||||
config.Write("reactionConfig");
|
||||
detGeoTxt.Write("detGeo");
|
||||
|
||||
if( distList != NULL ) distList->Write("DWBA", 1);
|
||||
if( dwbaExList != NULL ) {
|
||||
dwbaExList_Used.Write("DWBA_ExList", 1);
|
||||
dwbaReactList_Used.Write("DWBA_ReactionList", 1);
|
||||
}
|
||||
|
||||
TMacro allExList;
|
||||
allExList.AddLine("#---Ex relative_xsec SF sigma_in_MeV");
|
||||
TMacro exIDReactIDList; //list of all ex and corresponding Reaction ID
|
||||
exIDReactIDList.AddLine("#-- ExID ReactionID");
|
||||
for( int i = 0; i < numTransfer; i++){
|
||||
std::vector<EnergyLevel> tempExList = transfer[i].GetExList()->ExList;
|
||||
for( size_t j = 0; j < tempExList.size(); j++){
|
||||
allExList.AddLine(Form("%9.5f %9.5f %3.1f %5.3f", tempExList[j].Ex, tempExList[j].xsec, tempExList[j].SF, tempExList[j].sigma));
|
||||
exIDReactIDList.AddLine(Form("%ld %d", j, i));
|
||||
}
|
||||
}
|
||||
|
||||
allExList.Write("AllExList");
|
||||
exIDReactIDList.Write("ExID_ReactID_List");
|
||||
|
||||
TMacro hitMeaning;
|
||||
hitMeaning.AddLine("======================= meaning of Hit\n");
|
||||
for( int code = -15 ; code <= 1; code ++ ){
|
||||
hitMeaning.AddLine( Form( "%4d = %s", code, helios[0].AcceptanceCodeToMsg(code).Data() ));
|
||||
}
|
||||
hitMeaning.AddLine(" other = unknown\n");
|
||||
hitMeaning.AddLine("===========================================\n");
|
||||
hitMeaning.Write("hitMeaning");
|
||||
|
||||
int hit; /// the output of Helios.CalHit
|
||||
tree->Branch("hit", &hit, "hit/I");
|
||||
|
||||
int rID; /// reaction ID
|
||||
tree->Branch("rID", &rID, "reactionID/I");
|
||||
|
||||
double thetab, phib, Tb;
|
||||
double thetaB, phiB, TB;
|
||||
tree->Branch("thetab", &thetab, "thetab/D");
|
||||
tree->Branch("phib", &phib, "phib/D");
|
||||
tree->Branch("Tb", &Tb, "Tb/D");
|
||||
tree->Branch("thetaB", &thetaB, "thetaB/D");
|
||||
tree->Branch("phiB", &phiB, "phiB/D");
|
||||
tree->Branch("TB", &TB, "TB/D");
|
||||
|
||||
double thetaCM;
|
||||
tree->Branch("thetaCM", &thetaCM, "thetaCM/D");
|
||||
|
||||
double e, z, detX, t, z0, tB;
|
||||
tree->Branch("e", &e, "energy_light/D");
|
||||
tree->Branch("x", &detX, "detector_x/D");
|
||||
tree->Branch("z", &z, "array_hit_z/D");
|
||||
tree->Branch("z0", &z0, "z-cycle/D");
|
||||
tree->Branch("t", &t, "cycle_time_light/D");
|
||||
tree->Branch("tB", &tB, "recoil_hit_time/D"); /// hit time for recoil on the recoil detector
|
||||
|
||||
int loop, detID, detRowID;
|
||||
tree->Branch("detID", &detID, "detID/I");
|
||||
tree->Branch("detRowID", &detRowID, "detRowID/I");
|
||||
tree->Branch("loop", &loop, "loop/I");
|
||||
|
||||
double rho, rhoB; ///orbit radius
|
||||
tree->Branch("rho", &rho, "orbit_radius_light/D");
|
||||
tree->Branch("rhoB", &rhoB, "orbit_radius_heavy/D");
|
||||
|
||||
int ExID;
|
||||
double Ex;
|
||||
tree->Branch("ExID", &ExID, "ExID/I");
|
||||
tree->Branch("Ex", &Ex, "Ex/D");
|
||||
|
||||
double ExCal, thetaCMCal;
|
||||
tree->Branch("ExCal", &ExCal, "ExCal/D");
|
||||
tree->Branch("thetaCMCal", &thetaCMCal, "thetaCMCal/D");
|
||||
|
||||
// double TbLoss; /// energy loss of particle-b from target scattering
|
||||
// double KEAnew; ///beam energy after target scattering
|
||||
// double depth; /// reaction depth;
|
||||
// double Ecm;
|
||||
// if( reactConfig.isTargetScattering ){
|
||||
// tree->Branch("depth", &depth, "depth/D");
|
||||
// tree->Branch("TbLoss", &TbLoss, "TbLoss/D");
|
||||
// tree->Branch("KEAnew", &KEAnew, "KEAnew/D");
|
||||
// tree->Branch("Ecm", &Ecm, "Ecm/D");
|
||||
// }
|
||||
|
||||
double decayTheta; /// the change of thetaB due to decay
|
||||
double xRecoil_d, yRecoil_d, rhoRecoil_d, Td;
|
||||
|
||||
bool isAnyDecay = false;
|
||||
for( int i = 0; i < numTransfer; i++ ){
|
||||
if( !listOfTransfer[i] ) continue;
|
||||
isAnyDecay |= transfer[i].GetRecoil().isDecay;
|
||||
}
|
||||
|
||||
if( isAnyDecay ) {
|
||||
tree->Branch("decayTheta", &decayTheta, "decayTheta/D");
|
||||
tree->Branch("xRecoil_d", &xRecoil_d, "xRecoil_d/D");
|
||||
tree->Branch("yRecoil_d", &yRecoil_d, "yRecoil_d/D");
|
||||
tree->Branch("rhoRecoil_d", &rhoRecoil_d, "rhoRecoil_d/D");
|
||||
tree->Branch("Td", &Td, "Td/D");
|
||||
}
|
||||
|
||||
double xArray, yArray, rhoArray; ///x, y, rho positon of particle-b on PSD
|
||||
tree->Branch("xArray", &xArray, "xArray/D");
|
||||
tree->Branch("yArray", &yArray, "yArray/D");
|
||||
tree->Branch("rhoArray", &rhoArray, "rhoArray/D");
|
||||
|
||||
double xRecoil, yRecoil, rhoRecoil; /// x, y, rho position of particle-B on recoil-detector
|
||||
tree->Branch("xRecoil", &xRecoil, "xRecoil/D");
|
||||
tree->Branch("yRecoil", &yRecoil, "yRecoil/D");
|
||||
tree->Branch("rhoRecoil", &rhoRecoil, "rhoRecoil/D");
|
||||
|
||||
|
||||
///in case need ELUM
|
||||
double xElum1, yElum1, rhoElum1;
|
||||
bool isAnyElum1 = false;
|
||||
for( int i = 0; i < numTransfer; i++ ){
|
||||
if( !listOfTransfer[i] ) continue;
|
||||
isAnyElum1 |= (helios[i].GetAuxGeometry().elumPos1 != 0);
|
||||
}
|
||||
if( isAnyElum1 ) {
|
||||
tree->Branch("xElum1", &xElum1, "xElum1/D");
|
||||
tree->Branch("yElum1", &yElum1, "yElum1/D");
|
||||
tree->Branch("rhoElum1", &rhoElum1, "rhoElum1/D");
|
||||
}
|
||||
|
||||
double xElum2, yElum2, rhoElum2;
|
||||
bool isAnyElum2 = false;
|
||||
for( int i = 0; i < numTransfer; i++ ){
|
||||
if( !listOfTransfer[i] ) continue;
|
||||
isAnyElum2 |= (helios[i].GetAuxGeometry().elumPos2 != 0);
|
||||
}
|
||||
if( isAnyElum2 ) {
|
||||
tree->Branch("xElum2", &xElum2, "xElum2/D");
|
||||
tree->Branch("yElum2", &yElum2, "yElum2/D");
|
||||
tree->Branch("rhoElum2", &rhoElum2, "rhoElum2/D");
|
||||
}
|
||||
|
||||
///in case need other recoil detector.
|
||||
double xRecoil1, yRecoil1, rhoRecoil1;
|
||||
bool isAnyRecoil1 = false;
|
||||
for( int i = 0; i < numTransfer; i++ ){
|
||||
if( !listOfTransfer[i] ) continue;
|
||||
isAnyRecoil1 |= (helios[i].GetAuxGeometry().detPos1 != 0);
|
||||
}
|
||||
if( isAnyRecoil1 != 0 ){
|
||||
tree->Branch("xRecoil1", &xRecoil1, "xRecoil1/D");
|
||||
tree->Branch("yRecoil1", &yRecoil1, "yRecoil1/D");
|
||||
tree->Branch("rhoRecoil1", &rhoRecoil1, "rhoRecoil1/D");
|
||||
}
|
||||
|
||||
double xRecoil2, yRecoil2, rhoRecoil2;
|
||||
bool isAnyRecoil2 = false;
|
||||
for( int i = 0; i < numTransfer; i++ ){
|
||||
if( !listOfTransfer[i] ) continue;
|
||||
isAnyRecoil2 |= (helios[i].GetAuxGeometry().detPos2 != 0);
|
||||
}
|
||||
if( isAnyRecoil2 != 0 ){
|
||||
tree->Branch("xRecoil2", &xRecoil2, "xRecoil2/D");
|
||||
tree->Branch("yRecoil2", &yRecoil2, "yRecoil2/D");
|
||||
tree->Branch("rhoRecoil2", &rhoRecoil2, "rhoRecoil2/D");
|
||||
}
|
||||
|
||||
//======= list of reaction used.
|
||||
TMacro listOfReaction;
|
||||
for( int i = 0; i < numTransfer ; i++){
|
||||
if( !listOfTransfer[i] ) continue;
|
||||
listOfReaction.AddLine(Form("%2d | %s", i, transfer[i].GetReactionName_Latex().Data()));
|
||||
}
|
||||
|
||||
listOfReaction.Write("ListOfReactions");
|
||||
|
||||
//======= function for e-z plot for ideal case
|
||||
printf("++++ generate functions\n");
|
||||
TObjArray * gList = new TObjArray();
|
||||
gList->SetName("Constant thetaCM = 0 lines");
|
||||
const int gxSize = numTransfer;
|
||||
TF1 ** gx = new TF1*[gxSize];
|
||||
TString name;
|
||||
|
||||
for( int i = 0; i < gxSize; i++){
|
||||
double mb = transfer[i].GetMass_b();
|
||||
double betaRect = transfer[i].GetReactionBeta();
|
||||
double gamma = transfer[i].GetReactionGamma();
|
||||
double slope = transfer[i].GetEZSlope(helios[0].GetBField()); /// MeV/mm
|
||||
|
||||
name.Form("g%d", i);
|
||||
gx[i] = new TF1(name, "([0]*TMath::Sqrt([1]+[2]*x*x)+[5]*x)/([3]) - [4]", -1000, 1000);
|
||||
double thetacm = i * TMath::DegToRad();
|
||||
double gS2 = TMath::Power(TMath::Sin(thetacm)*gamma,2);
|
||||
gx[i]->SetParameter(0, TMath::Cos(thetacm));
|
||||
gx[i]->SetParameter(1, mb*mb*(1-gS2));
|
||||
gx[i]->SetParameter(2, TMath::Power(slope/betaRect,2));
|
||||
gx[i]->SetParameter(3, 1-gS2);
|
||||
gx[i]->SetParameter(4, mb);
|
||||
gx[i]->SetParameter(5, -gS2*slope);
|
||||
gx[i]->SetNpx(1000);
|
||||
gList->Add(gx[i]);
|
||||
printf("/");
|
||||
if( i > 1 && i % 40 == 0 ) printf("\n");
|
||||
}
|
||||
gList->Write("EZ_thetaCM", TObject::kSingleKey);
|
||||
printf(" %d constant thetaCM functions\n", gxSize);
|
||||
|
||||
for( int i = 0; i < gxSize; i++){
|
||||
delete gx[i];
|
||||
}
|
||||
delete [] gx;
|
||||
delete gList;
|
||||
|
||||
//--- cal E-Z curve with finite detector correction
|
||||
int numEx = 0;
|
||||
for( int i = 0; i < numTransfer; i++){
|
||||
if( !listOfTransfer[i] ) continue;
|
||||
numEx += transfer[i].GetExList()->ExList.size();
|
||||
}
|
||||
|
||||
TObjArray * fxList = new TObjArray();
|
||||
TGraph ** fx = new TGraph*[numEx];
|
||||
std::vector<double> px, py;
|
||||
int countfx = 0;
|
||||
|
||||
count = 0;
|
||||
for( int i = 0; i < numTransfer; i++ ){
|
||||
if( !listOfTransfer[i] ) continue;
|
||||
double mb = transfer[i].GetMass_b();
|
||||
double betaRect = transfer[i].GetReactionBeta();
|
||||
double gamma = transfer[i].GetReactionGamma();
|
||||
double slope = transfer[i].GetEZSlope(helios[0].GetBField()); /// MeV/mm
|
||||
|
||||
for( size_t j = 0 ; j < transfer[i].GetExList()->ExList.size(); j++){
|
||||
double Ex = transfer[i].GetExList()->ExList[j].Ex;
|
||||
double kbCM = transfer[i].CalkCM(Ex);
|
||||
double a = helios[i].GetDetRadius();
|
||||
double q = TMath::Sqrt(mb*mb + kbCM * kbCM );
|
||||
px.clear();
|
||||
py.clear();
|
||||
countfx = 0;
|
||||
for(int i = 0; i < 100; i++){
|
||||
double thetacm = TMath::Pi()/TMath::Log(100) * (TMath::Log(100) - TMath::Log(100-i)) ;//using log scale, for more point in small angle.
|
||||
double temp = TMath::TwoPi() * slope / betaRect / kbCM * a / TMath::Sin(thetacm);
|
||||
double pxTemp = betaRect /slope * (gamma * betaRect * q - gamma * kbCM * TMath::Cos(thetacm)) * (1 - TMath::ASin(temp)/TMath::TwoPi()) ;
|
||||
double pyTemp = gamma * q - mb - gamma * betaRect * kbCM * TMath::Cos(thetacm);
|
||||
if( TMath::IsNaN(pxTemp) || TMath::IsNaN(pyTemp) ) continue;
|
||||
px.push_back(pxTemp);
|
||||
py.push_back(pyTemp);
|
||||
countfx ++;
|
||||
}
|
||||
|
||||
fx[count] = new TGraph(countfx, &px[0], &py[0]);
|
||||
name.Form("fx%d_%ld", i, j);
|
||||
fx[count]->SetName(name);
|
||||
fx[count]->SetLineColor(4);
|
||||
fxList->Add(fx[count]);
|
||||
printf(",");
|
||||
count ++;
|
||||
}
|
||||
}
|
||||
fxList->Write("EZCurve", TObject::kSingleKey);
|
||||
printf(" %d (%d) e-z finite-size detector functions\n", numEx, count);
|
||||
|
||||
for( int i = 0 ; i < numEx; i++) delete fx[i];
|
||||
delete [] fx;
|
||||
delete fxList;
|
||||
|
||||
// //--- cal modified thetaCM vs z
|
||||
// TObjArray * txList = new TObjArray();
|
||||
// TGraph ** tx = new TGraph*[numEx];
|
||||
// for( int j = 0 ; j < numEx; j++){
|
||||
// double a = helios.GetDetRadius();
|
||||
// double q = TMath::Sqrt(mb*mb + kbCM[j] * kbCM[j] );
|
||||
// px.clear();
|
||||
// py.clear();
|
||||
// countfx = 0;
|
||||
// for(int i = 0; i < 100; i++){
|
||||
// double thetacm = (i + 8.) * TMath::DegToRad();
|
||||
// double temp = TMath::TwoPi() * slope / betaRect / kbCM[j] * a / TMath::Sin(thetacm);
|
||||
// double pxTemp = betaRect /slope * (gamma * betaRect * q - gamma * kbCM[j] * TMath::Cos(thetacm)) * (1 - TMath::ASin(temp)/TMath::TwoPi());
|
||||
// double pyTemp = thetacm * TMath::RadToDeg();
|
||||
// if( TMath::IsNaN(pxTemp) || TMath::IsNaN(pyTemp) ) continue;
|
||||
// px.push_back(pxTemp);
|
||||
// py.push_back(pyTemp);
|
||||
// countfx ++;
|
||||
// }
|
||||
|
||||
// tx[j] = new TGraph(countfx, &px[0], &py[0]);
|
||||
// name.Form("tx%d", j);
|
||||
// tx[j]->SetName(name);
|
||||
// tx[j]->SetLineColor(4);
|
||||
// txList->Add(tx[j]);
|
||||
// printf("*");
|
||||
// }
|
||||
// txList->Write("thetaCM_Z", TObject::kSingleKey);
|
||||
// printf(" %d thetaCM-z for finite-size detector functions\n", numEx);
|
||||
|
||||
//========timer
|
||||
TBenchmark clock;
|
||||
bool shown ;
|
||||
clock.Reset();
|
||||
clock.Start("timer");
|
||||
shown = false;
|
||||
|
||||
//change the number of event into human easy-to-read form
|
||||
int numEvent = reactionConfig.numEvents;
|
||||
int digitLen = TMath::Floor(TMath::Log10(numEvent));
|
||||
TString numEventStr;
|
||||
if( 3 <= digitLen && digitLen < 6 ){
|
||||
numEventStr.Form("%5.1f kilo", numEvent/1000.);
|
||||
}else if ( 6<= digitLen && digitLen < 9 ){
|
||||
numEventStr.Form("%6.2f million", numEvent/1e6);
|
||||
}else if ( 9<= digitLen ){
|
||||
numEventStr.Form("%6.2f billion", numEvent/1e9);
|
||||
}
|
||||
printf("\e[32m#################################### generating %s events \e[0m\n", numEventStr.Data());
|
||||
|
||||
double KEA = reactionConfig.beamEnergy;
|
||||
double theta = reactionConfig.beamTheta;
|
||||
double phi = 0.0;
|
||||
|
||||
TF1 * angDist = nullptr;
|
||||
|
||||
//*====================================================== calculate event
|
||||
count = 0;
|
||||
for( int i = 0; i < numEvent; i++){
|
||||
bool redoFlag = true;
|
||||
if( !reactionConfig.isRedo ) redoFlag = false;
|
||||
do{
|
||||
|
||||
rID = gRandom->Integer( numTransfer );
|
||||
if( !listOfTransfer[rID] ) continue;
|
||||
|
||||
//==== Set Ex of B
|
||||
ExID = transfer[rID].GetRandomExID();
|
||||
double sigma = transfer[rID].GetExList()->ExList[ExID].sigma;
|
||||
Ex = transfer[rID].GetExList()->ExList[ExID].Ex + gRandom->Gaus(0, sigma);
|
||||
|
||||
transfer[rID].SetExB(Ex);
|
||||
|
||||
//==== Set incident beam
|
||||
if( reactionConfig.beamEnergySigma != 0 ){
|
||||
KEA = gRandom->Gaus(reactionConfig.beamEnergy, reactionConfig.beamEnergySigma);
|
||||
}
|
||||
if( reactionConfig.beamThetaSigma != 0 ){
|
||||
theta = gRandom->Gaus(reactionConfig.beamTheta, reactionConfig.beamThetaSigma);
|
||||
}
|
||||
|
||||
//==== for taregt scattering
|
||||
transfer[rID].SetIncidentEnergyAngle(KEA, theta, 0.);
|
||||
transfer[rID].CalReactionConstant();
|
||||
|
||||
// TLorentzVector PA = transfer.GetPA();
|
||||
//depth = 0;
|
||||
// if( isTargetScattering ){
|
||||
// //==== Target scattering, only energy loss
|
||||
// depth = targetThickness * gRandom->Rndm();
|
||||
// msA.SetTarget(density, depth);
|
||||
// TLorentzVector PAnew = msA.Scattering(PA);
|
||||
// KEAnew = msA.GetKE()/reactConfig.beamA;
|
||||
// transfer.SetIncidentEnergyAngle(KEAnew, theta, phi);
|
||||
// transfer.CalReactionConstant();
|
||||
// Ecm = transfer.GetCMTotalKE();
|
||||
// }
|
||||
|
||||
//==== Calculate thetaCM, phiCM
|
||||
if( distFile->IsOpen() && useDWBA[rID] ){
|
||||
angDist = (TF1 *) distList->At(ExID);
|
||||
thetaCM = angDist->GetRandom() / 180. * TMath::Pi();
|
||||
}else{
|
||||
thetaCM = TMath::ACos(2 * gRandom->Rndm() - 1) ;
|
||||
}
|
||||
|
||||
double phiCM = TMath::TwoPi() * gRandom->Rndm();
|
||||
|
||||
//==== Calculate reaction
|
||||
transfer[rID].Event(thetaCM, phiCM);
|
||||
TLorentzVector Pb = transfer[rID].GetPb();
|
||||
TLorentzVector PB = transfer[rID].GetPB();
|
||||
|
||||
// //==== Calculate energy loss of scattered and recoil in target
|
||||
// if( isTargetScattering ){
|
||||
// if( Pb.Theta() < TMath::PiOver2() ){
|
||||
// msb.SetTarget(density, targetThickness - depth);
|
||||
// }else{
|
||||
// msb.SetTarget(density, depth);
|
||||
// }
|
||||
// Pb = msb.Scattering(Pb);
|
||||
// TbLoss = msb.GetKELoss();
|
||||
// msB.SetTarget(density, targetThickness - depth);
|
||||
// PB = msB.Scattering(PB);
|
||||
// }else{
|
||||
// TbLoss = 0;
|
||||
// }
|
||||
|
||||
//======= Decay of particle-B
|
||||
int decayID = 0;
|
||||
if( transfer[rID].GetRecoil().isDecay){
|
||||
|
||||
decayID = decay[rID].CalDecay(PB, Ex, 0, phiCM + TMath::Pi()/2); // decay to ground state
|
||||
if( decayID == 1 ){
|
||||
PB = decay[rID].GetDaugther_D();
|
||||
//decayTheta = decay.GetAngleChange();
|
||||
decayTheta = decay[rID].GetThetaCM();
|
||||
PB.SetUniqueID(transfer[rID].GetRecoil().decayZ);
|
||||
}else{
|
||||
decayTheta = TMath::QuietNaN();
|
||||
}
|
||||
}
|
||||
|
||||
//################################### tree branches
|
||||
//===== reaction
|
||||
thetab = Pb.Theta() * TMath::RadToDeg();
|
||||
thetaB = PB.Theta() * TMath::RadToDeg();
|
||||
|
||||
Tb = Pb.E() - Pb.M();
|
||||
TB = PB.E() - PB.M();
|
||||
|
||||
phib = Pb.Phi() * TMath::RadToDeg();
|
||||
phiB = PB.Phi() * TMath::RadToDeg();
|
||||
|
||||
//==== Helios
|
||||
|
||||
// printf(" thetaCM : %f, Tb : %f\n", thetaCM * TMath::RadToDeg(), Pb.M());
|
||||
|
||||
if( Tb > 0 || TB > 0 ){
|
||||
|
||||
helios[rID].CalArrayHit(Pb);
|
||||
helios[rID].CalRecoilHit(PB);
|
||||
hit = 2;
|
||||
while( hit > 1 ){ hit = helios[rID].CheckDetAcceptance(); } /// while hit > 1, goto next loop;
|
||||
|
||||
trajectory orb_b = helios[rID].GetTrajectory_b();
|
||||
trajectory orb_B = helios[rID].GetTrajectory_B();
|
||||
|
||||
e = helios[rID].GetEnergy() + gRandom->Gaus(0, helios[rID].GetArrayGeometry().eSigma );
|
||||
|
||||
double ranX = gRandom->Gaus(0, helios[rID].GetArrayGeometry().zSigma);
|
||||
z = orb_b.z + ranX;
|
||||
detX = helios[rID].GetDetX() + ranX;
|
||||
|
||||
z0 = orb_b.z0;
|
||||
t = orb_b.t;
|
||||
loop = orb_b.loop;
|
||||
detID = orb_b.detID;
|
||||
detRowID = orb_b.detRowID;
|
||||
rho = orb_b.rho;
|
||||
rhoArray = orb_b.R;
|
||||
|
||||
xArray = orb_b.x;
|
||||
yArray = orb_b.y;
|
||||
|
||||
//ELUM
|
||||
double elumPos1 = helios[rID].GetAuxGeometry().elumPos1;
|
||||
if( elumPos1 != 0 ){
|
||||
xElum1 = helios[rID].GetXPos(elumPos1);
|
||||
yElum1 = helios[rID].GetYPos(elumPos1);
|
||||
rhoElum1 = helios[rID].GetR (elumPos1);
|
||||
}
|
||||
double elumPos2 = helios[rID].GetAuxGeometry().elumPos2;
|
||||
if( elumPos2 ){
|
||||
xElum2 = helios[rID].GetXPos(elumPos2);
|
||||
yElum2 = helios[rID].GetYPos(elumPos2);
|
||||
rhoElum2 = helios[rID].GetR (elumPos2);
|
||||
}
|
||||
|
||||
//Recoil
|
||||
rhoRecoil = orb_B.R;
|
||||
tB = orb_B.t;
|
||||
xRecoil = orb_B.x;
|
||||
yRecoil = orb_B.y;
|
||||
rhoB = orb_B.rho;
|
||||
|
||||
//other recoil detectors
|
||||
double recoilPos1 = helios[rID].GetAuxGeometry().detPos1;
|
||||
if ( recoilPos1 != 0 ){
|
||||
xRecoil1 = helios[rID].GetRecoilXPos(recoilPos1);
|
||||
yRecoil1 = helios[rID].GetRecoilYPos(recoilPos1);
|
||||
rhoRecoil1 = helios[rID].GetRecoilR (recoilPos1);
|
||||
}
|
||||
double recoilPos2 = helios[rID].GetAuxGeometry().detPos2;
|
||||
if ( recoilPos2 != 0 ){
|
||||
xRecoil2 = helios[rID].GetRecoilXPos(recoilPos2);
|
||||
yRecoil2 = helios[rID].GetRecoilYPos(recoilPos2);
|
||||
rhoRecoil2 = helios[rID].GetRecoilR (recoilPos2);
|
||||
}
|
||||
|
||||
std::pair<double,double> ExThetaCM = transfer[rID].CalExThetaCM(e, z, helios[rID].GetBField(), helios[rID].GetDetRadius());
|
||||
ExCal = ExThetaCM.first;
|
||||
thetaCMCal = ExThetaCM.second;
|
||||
|
||||
//change thetaCM into deg
|
||||
thetaCM = thetaCM * TMath::RadToDeg();
|
||||
|
||||
//if decay, get the light decay particle on the recoil;
|
||||
if( transfer[rID].GetRecoil().isDecay ){
|
||||
if( decayID == 1 ){
|
||||
TLorentzVector Pd = decay[rID].GetDaugther_d();
|
||||
|
||||
Td = Pd.E() - Pd.M();
|
||||
|
||||
helios[rID].CalRecoilHit(Pd);
|
||||
|
||||
trajectory orb_d = helios[rID].GetTrajectory_B();
|
||||
rhoRecoil_d = orb_d.R;
|
||||
xRecoil_d = orb_d.x;
|
||||
yRecoil_d = orb_d.y;
|
||||
|
||||
}else{
|
||||
rhoRecoil_d = TMath::QuietNaN();
|
||||
xRecoil_d = TMath::QuietNaN();
|
||||
yRecoil_d = TMath::QuietNaN();
|
||||
}
|
||||
}
|
||||
|
||||
}else{
|
||||
hit = -404;
|
||||
}
|
||||
|
||||
if( hit == 1) count ++;
|
||||
|
||||
if( reactionConfig.isRedo ){
|
||||
if( hit == 1) {
|
||||
redoFlag = false;
|
||||
}else{
|
||||
redoFlag = true;
|
||||
//printf("%d, %2d, thetaCM : %f, theta : %f, z0: %f \n", i, hit, thetaCM * TMath::RadToDeg(), thetab, helios.GetZ0());
|
||||
}
|
||||
}else{
|
||||
redoFlag = false;
|
||||
}
|
||||
|
||||
}while( redoFlag );
|
||||
tree->Fill();
|
||||
|
||||
//#################################################################### Timer
|
||||
clock.Stop("timer");
|
||||
Double_t time = clock.GetRealTime("timer");
|
||||
clock.Start("timer");
|
||||
|
||||
if ( !shown ) {
|
||||
if (fmod(time, 10) < 1 ){
|
||||
printf( "%10d[%2d%%]| %8.2f sec | expect: %5.1f min \n", i, TMath::Nint((i+1)*100./numEvent), time , numEvent*time/(i+1)/60);
|
||||
shown = 1;
|
||||
}
|
||||
}else{
|
||||
if (fmod(time, 10) > 9 ){
|
||||
shown = 0;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
saveFile->Write();
|
||||
saveFile->Close();
|
||||
|
||||
distFile->Close();
|
||||
delete angDist;
|
||||
|
||||
printf("=============== done. saved as %s. count(hit==1) : %d\n", saveFileName.Data(), count);
|
||||
//gROOT->ProcessLine(".q");
|
||||
|
||||
delete [] transfer;
|
||||
delete [] decay;
|
||||
delete [] helios;
|
||||
|
||||
distFile->Close();
|
||||
delete distFile;
|
||||
delete distList;
|
||||
delete dwbaExList;
|
||||
delete dwbaReactList;
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
|
||||
int main (int argc, char *argv[]) {
|
||||
|
||||
printf("=================================================================\n");
|
||||
printf("========== Simulate Transfer reaction in HELIOS ==========\n");
|
||||
printf("=================================================================\n");
|
||||
|
||||
if(argc == 2 || argc > 6 ) {
|
||||
printf("Usage: ./Transfer [1] [2] [3] [4] [5]\n");
|
||||
printf(" default file name \n");
|
||||
printf(" [1] reactionConfig.txt (input) reaction Setting \n");
|
||||
printf(" [2] detectorGeo.txt (input) detector Setting \n");
|
||||
printf(" [3] DWBA.root (input) thetaCM distribution from DWBA \n");
|
||||
printf(" [4] transfer.root (output) rootFile name for output \n");
|
||||
printf(" [5] 1 (input) 0 = no plot, 1 = plot \n");
|
||||
|
||||
printf("-----------------------------------------------------------------\n");
|
||||
printf(" When DWBA.root provided.\n");
|
||||
printf(" The excitation energies from the DWBA are used.\n");
|
||||
printf(" And the excitation energies in reactionConfig.txt will be ignored\n");
|
||||
printf("=================================================================\n");
|
||||
return 0 ;
|
||||
}
|
||||
|
||||
std::string basicConfig = "reactionConfig.txt";
|
||||
std::string detGeoFile = "detectorGeo.txt";
|
||||
TString ptolemyRoot = "DWBA.root"; // when no file, use isotropic distribution of thetaCM
|
||||
TString saveFileName = "transfer.root";
|
||||
bool isPlot = true;
|
||||
|
||||
if( argc >= 2) basicConfig = argv[1];
|
||||
if( argc >= 3) detGeoFile = argv[2];
|
||||
if( argc >= 4) ptolemyRoot = argv[3];
|
||||
if( argc >= 5) saveFileName = argv[4];
|
||||
if( argc >= 6) isPlot = atoi(argv[5]);
|
||||
|
||||
Transfer( basicConfig, detGeoFile, ptolemyRoot, saveFileName);
|
||||
|
||||
//run Cleopatra/SimChecker.C
|
||||
if( isPlot ){
|
||||
std::ifstream file_in;
|
||||
file_in.open("../Cleopatra/SimChecker.C", std::ios::in);
|
||||
if( file_in){
|
||||
printf("---- running ../Cleopatra/SimChecker.C on %s \n", saveFileName.Data());
|
||||
TString cmd;
|
||||
cmd.Form("root -l '../Cleopatra/SimChecker.C(\"%s\")'", saveFileName.Data());
|
||||
|
||||
system(cmd.Data());
|
||||
}else{
|
||||
printf("cannot find ../Cleopatra/SimChecker.C \n");
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
|
@ -1,722 +0,0 @@
|
|||
#include "TROOT.h"
|
||||
#include "TBenchmark.h"
|
||||
#include "TLorentzVector.h"
|
||||
#include "TMath.h"
|
||||
#include "TFile.h"
|
||||
#include "TF1.h"
|
||||
#include "TTree.h"
|
||||
#include "TRandom.h"
|
||||
#include "TGraph.h"
|
||||
#include "TMacro.h"
|
||||
#include <stdlib.h>
|
||||
#include <vector>
|
||||
#include <fstream>
|
||||
#include <TObjArray.h>
|
||||
|
||||
#include "../Armory/ClassDetGeo.h"
|
||||
#include "ClassTargetScattering.h"
|
||||
#include "ClassDecay.h"
|
||||
#include "ClassTransfer.h"
|
||||
#include "ClassHelios.h"
|
||||
|
||||
double exDistFunc(Double_t *x, Double_t * par){
|
||||
return par[(int) x[0]];
|
||||
}
|
||||
|
||||
void PrintEZPlotPara(TransferReaction tran, HELIOS helios){
|
||||
|
||||
printf("==================================== E-Z plot slope\n");
|
||||
double betaRect = tran.GetReactionBeta() ;
|
||||
double gamma = tran.GetReactionGamma();
|
||||
double mb = tran.GetMass_b();
|
||||
double pCM = tran.GetMomentumbCM();
|
||||
double q = TMath::Sqrt(mb*mb + pCM*pCM); ///energy of light recoil in center of mass
|
||||
double slope = tran.GetEZSlope(helios.GetBField()); /// MeV/mm
|
||||
printf(" e-z slope : %f MeV/mm\n", slope);
|
||||
double intercept = q/gamma - mb; // MeV
|
||||
printf(" e-z intercept (ground state) : %f MeV\n", intercept);
|
||||
|
||||
}
|
||||
|
||||
void Transfer(
|
||||
std::string basicConfig = "reactionConfig.txt",
|
||||
std::string heliosDetGeoFile = "detectorGeo.txt",
|
||||
unsigned short ID = 0, // this is the ID for the array
|
||||
TString ptolemyRoot = "DWBA.root",
|
||||
TString saveFileName = "transfer.root"){
|
||||
|
||||
//*############################################# Set Reaction
|
||||
TransferReaction transfer;
|
||||
HELIOS helios;
|
||||
Decay decay;
|
||||
|
||||
std::vector<double> kbCM; /// momentum of b in CM frame
|
||||
TF1 * exDist = nullptr;
|
||||
|
||||
transfer.SetReactionFromFile(basicConfig, ID);
|
||||
helios.SetDetectorGeometry(heliosDetGeoFile, ID);
|
||||
|
||||
printf("*****************************************************************\n");
|
||||
printf("*\e[1m\e[33m %27s \e[0m*\n", transfer.GetReactionName().Data());
|
||||
printf("*****************************************************************\n");
|
||||
printf("----- loading reaction setting from %s. \n", basicConfig.c_str());
|
||||
printf("----- loading geometry setting from %s. \n", heliosDetGeoFile.c_str());
|
||||
|
||||
printf("\e[32m#################################### Reaction & HELIOS configuration\e[0m\n");
|
||||
|
||||
transfer.PrintReaction(false);
|
||||
|
||||
if(transfer.GetRecoil().isDecay) {
|
||||
decay.SetMotherDaugther(transfer.GetRecoil());
|
||||
}
|
||||
|
||||
helios.PrintGeometry();
|
||||
PrintEZPlotPara(transfer, helios);
|
||||
|
||||
|
||||
DetGeo detGeo = helios.GetDetectorGeometry();
|
||||
Array array = helios.GetArrayGeometry();
|
||||
Auxillary aux = helios.GetAuxGeometry();
|
||||
ReactionConfig reactConfig = transfer.GetRectionConfig();
|
||||
Recoil recoil = transfer.GetRecoil();
|
||||
|
||||
//*############################################# save reaction.dat
|
||||
// if( filename != "" ) {
|
||||
// FILE * keyParaOut;
|
||||
// keyParaOut = fopen (filename.Data(), "w+");
|
||||
|
||||
// printf("=========== save key reaction constants to %s \n", filename.Data());
|
||||
// fprintf(keyParaOut, "%-15.4f //%s\n", transfer.GetMass_b(), "mass_b");
|
||||
// fprintf(keyParaOut, "%-15d //%s\n", reactConfig.recoilLightZ, "charge_b");
|
||||
// fprintf(keyParaOut, "%-15.8f //%s\n", transfer.GetReactionBeta(), "betaCM");
|
||||
// fprintf(keyParaOut, "%-15.4f //%s\n", transfer.GetCMTotalEnergy(), "Ecm");
|
||||
// fprintf(keyParaOut, "%-15.4f //%s\n", transfer.GetMass_B(), "mass_B");
|
||||
// fprintf(keyParaOut, "%-15.4f //%s\n", slope/betaRect, "alpha=slope/betaRect");
|
||||
|
||||
// fflush(keyParaOut);
|
||||
// fclose(keyParaOut);
|
||||
// }
|
||||
|
||||
//*############################################# Target scattering, only energy loss
|
||||
// bool isTargetScattering = reactConfig.isTargetScattering;
|
||||
// float density = reactConfig.targetDensity;
|
||||
// float targetThickness = reactConfig.targetThickness;
|
||||
|
||||
// if(isTargetScattering) printf("\e[32m#################################### Target Scattering\e[0m\n");
|
||||
// TargetScattering msA;
|
||||
// TargetScattering msB;
|
||||
// TargetScattering msb;
|
||||
|
||||
// if(reactConfig.isTargetScattering) printf("======== Target : (thickness : %6.2f um) x (density : %6.2f g/cm3) = %6.2f ug/cm2\n",
|
||||
// targetThickness * 1e+4,
|
||||
// density,
|
||||
// targetThickness * density * 1e+6);
|
||||
|
||||
// if( reactConfig.isTargetScattering ){
|
||||
// msA.LoadStoppingPower(reactConfig.beamStoppingPowerFile);
|
||||
// msb.LoadStoppingPower(reactConfig.recoilLightStoppingPowerFile);
|
||||
// msB.LoadStoppingPower(reactConfig.recoilHeavyStoppingPowerFile);
|
||||
// }
|
||||
|
||||
ExcitedEnergies exList = transfer.GetRectionConfig().exList[ID];
|
||||
|
||||
//*############################################# Load DWBAroot for thetaCM distribution
|
||||
printf("\e[32m#################################### Load DWBA input : %s \e[0m\n", ptolemyRoot.Data());
|
||||
TF1 * dist = NULL;
|
||||
TFile * distFile = new TFile(ptolemyRoot, "read");
|
||||
TObjArray * distList = nullptr;
|
||||
TMacro * dwbaExList = nullptr;
|
||||
TMacro * dwbaReactList = nullptr;
|
||||
|
||||
TMacro dwbaExList_Used;
|
||||
|
||||
if( distFile->IsOpen() ) {
|
||||
printf("--------- Found DWBA thetaCM distributions. Use the ExList from DWBA.\n");
|
||||
|
||||
distList = (TObjArray *) distFile->FindObjectAny("thetaCM_TF1"); // the function List
|
||||
dwbaExList = (TMacro *) distFile->FindObjectAny("ExList");
|
||||
dwbaExList_Used.AddLine(dwbaExList->GetListOfLines()->At(0)->GetName());
|
||||
dwbaReactList = (TMacro *) distFile->FindObjectAny("ReactionList");
|
||||
exList.Clear();
|
||||
|
||||
int numEx = dwbaExList->GetListOfLines()->GetSize() - 1 ;
|
||||
for(int i = 1; i <= numEx ; i++){
|
||||
std::string reactionName = dwbaReactList->GetListOfLines()->At(i-1)->GetName();
|
||||
if( reactionName.find( transfer.GetReactionName().Data() ) != std::string::npos) {
|
||||
std::string temp = dwbaExList->GetListOfLines()->At(i)->GetName();
|
||||
dwbaExList_Used.AddLine(temp.c_str());
|
||||
if( temp[0] == '/' ) continue;
|
||||
std::vector<std::string> tempStr = AnalysisLib::SplitStr(temp, " ");
|
||||
exList.Add( atof(tempStr[0].c_str()), atof(tempStr[1].c_str()), 1.0, 0.00);
|
||||
}
|
||||
}
|
||||
|
||||
}else{
|
||||
printf("------- no DWBA input. Use the ExList from %s\n", basicConfig.c_str());
|
||||
}
|
||||
|
||||
|
||||
printf("------------------------------ Heavy Recoil excitation\n");
|
||||
printf("Energy[MeV] Rel.Xsec SF sigma\n");
|
||||
|
||||
int numEx = exList.ExList.size();
|
||||
|
||||
for( int j = 0; j < numEx; j++){
|
||||
double ex = exList.ExList[j].Ex;
|
||||
kbCM.push_back(transfer.CalkCM(ex));
|
||||
int decayID = decay.CalDecay(TLorentzVector (0,0,0,0), ex, 0);
|
||||
exList.ExList[j].Print(decayID == 1 ? "-->Decay" : "\n");
|
||||
}
|
||||
|
||||
//---- create Ex-distribution
|
||||
if( exList.ExList.size() > 1 ) {
|
||||
printf("---- creating Ex-distribution \n");
|
||||
exDist = new TF1("exDist", exDistFunc, 0, numEx, numEx);
|
||||
for(int q = 0; q < numEx; q++){
|
||||
exDist->SetParameter(q, exList.ExList[q].xsec*exList.ExList[q].SF);
|
||||
}
|
||||
}
|
||||
|
||||
//*############################################# build tree
|
||||
printf("\e[32m#################################### building Tree in %s\e[0m\n", saveFileName.Data());
|
||||
TFile * saveFile = new TFile(saveFileName, "recreate");
|
||||
TTree * tree = new TTree("tree", "tree");
|
||||
|
||||
TMacro config(basicConfig.c_str());
|
||||
TMacro detGeoTxt(heliosDetGeoFile.c_str());
|
||||
config.SetName(transfer.GetReactionName_Latex().Data());
|
||||
config.Write("reactionConfig");
|
||||
detGeoTxt.Write("detGeo");
|
||||
|
||||
if( distList != NULL ) distList->Write("DWBA", 1);
|
||||
if( dwbaExList != NULL ) dwbaExList_Used.Write("DWBA_ExList", 1);
|
||||
|
||||
|
||||
TMacro idMacro;
|
||||
idMacro.AddLine(Form("%d", ID));
|
||||
idMacro.Write("detGeoID");
|
||||
|
||||
TMacro hitMeaning;
|
||||
hitMeaning.AddLine("======================= meaning of Hit\n");
|
||||
for( int code = -15 ; code <= 1; code ++ ){
|
||||
hitMeaning.AddLine( Form( "%4d = %s", code, helios.AcceptanceCodeToMsg(code).Data() ));
|
||||
}
|
||||
hitMeaning.AddLine(" other = unknown\n");
|
||||
hitMeaning.AddLine("===========================================\n");
|
||||
hitMeaning.Write("hitMeaning");
|
||||
|
||||
int hit; /// the output of Helios.CalHit
|
||||
tree->Branch("hit", &hit, "hit/I");
|
||||
|
||||
double thetab, phib, Tb;
|
||||
double thetaB, phiB, TB;
|
||||
tree->Branch("thetab", &thetab, "thetab/D");
|
||||
tree->Branch("phib", &phib, "phib/D");
|
||||
tree->Branch("Tb", &Tb, "Tb/D");
|
||||
tree->Branch("thetaB", &thetaB, "thetaB/D");
|
||||
tree->Branch("phiB", &phiB, "phiB/D");
|
||||
tree->Branch("TB", &TB, "TB/D");
|
||||
|
||||
double thetaCM;
|
||||
tree->Branch("thetaCM", &thetaCM, "thetaCM/D");
|
||||
|
||||
double e, z, detX, t, z0, tB;
|
||||
tree->Branch("e", &e, "energy_light/D");
|
||||
tree->Branch("x", &detX, "detector_x/D");
|
||||
tree->Branch("z", &z, "array_hit_z/D");
|
||||
tree->Branch("z0", &z0, "z-cycle/D");
|
||||
tree->Branch("t", &t, "cycle_time_light/D");
|
||||
tree->Branch("tB", &tB, "recoil_hit_time/D"); /// hit time for recoil on the recoil detector
|
||||
|
||||
int loop, detID, detRowID;
|
||||
tree->Branch("detID", &detID, "detID/I");
|
||||
tree->Branch("detRowID", &detRowID, "detRowID/I");
|
||||
tree->Branch("loop", &loop, "loop/I");
|
||||
|
||||
double rho, rhoB; ///orbit radius
|
||||
tree->Branch("rho", &rho, "orbit_radius_light/D");
|
||||
tree->Branch("rhoB", &rhoB, "orbit_radius_heavy/D");
|
||||
|
||||
int ExID;
|
||||
double Ex;
|
||||
tree->Branch("ExID", &ExID, "ExID/I");
|
||||
tree->Branch("Ex", &Ex, "Ex/D");
|
||||
|
||||
double ExCal, thetaCMCal;
|
||||
tree->Branch("ExCal", &ExCal, "ExCal/D");
|
||||
tree->Branch("thetaCMCal", &thetaCMCal, "thetaCMCal/D");
|
||||
|
||||
// double TbLoss; /// energy loss of particle-b from target scattering
|
||||
// double KEAnew; ///beam energy after target scattering
|
||||
// double depth; /// reaction depth;
|
||||
// double Ecm;
|
||||
// if( reactConfig.isTargetScattering ){
|
||||
// tree->Branch("depth", &depth, "depth/D");
|
||||
// tree->Branch("TbLoss", &TbLoss, "TbLoss/D");
|
||||
// tree->Branch("KEAnew", &KEAnew, "KEAnew/D");
|
||||
// tree->Branch("Ecm", &Ecm, "Ecm/D");
|
||||
// }
|
||||
|
||||
double decayTheta; /// the change of thetaB due to decay
|
||||
double xRecoil_d, yRecoil_d, rhoRecoil_d, Td;
|
||||
if( recoil.isDecay ) {
|
||||
tree->Branch("decayTheta", &decayTheta, "decayTheta/D");
|
||||
tree->Branch("xRecoil_d", &xRecoil_d, "xRecoil_d/D");
|
||||
tree->Branch("yRecoil_d", &yRecoil_d, "yRecoil_d/D");
|
||||
tree->Branch("rhoRecoil_d", &rhoRecoil_d, "rhoRecoil_d/D");
|
||||
tree->Branch("Td", &Td, "Td/D");
|
||||
}
|
||||
|
||||
double xArray, yArray, rhoArray; ///x, y, rho positon of particle-b on PSD
|
||||
tree->Branch("xArray", &xArray, "xArray/D");
|
||||
tree->Branch("yArray", &yArray, "yArray/D");
|
||||
tree->Branch("rhoArray", &rhoArray, "rhoArray/D");
|
||||
|
||||
double xRecoil, yRecoil, rhoRecoil; /// x, y, rho position of particle-B on recoil-detector
|
||||
tree->Branch("xRecoil", &xRecoil, "xRecoil/D");
|
||||
tree->Branch("yRecoil", &yRecoil, "yRecoil/D");
|
||||
tree->Branch("rhoRecoil", &rhoRecoil, "rhoRecoil/D");
|
||||
|
||||
|
||||
///in case need ELUM
|
||||
double xElum1, yElum1, rhoElum1;
|
||||
if( aux.elumPos1 != 0 ) {
|
||||
tree->Branch("xElum1", &xElum1, "xElum1/D");
|
||||
tree->Branch("yElum1", &yElum1, "yElum1/D");
|
||||
tree->Branch("rhoElum1", &rhoElum1, "rhoElum1/D");
|
||||
}
|
||||
|
||||
double xElum2, yElum2, rhoElum2;
|
||||
if( aux.elumPos2 != 0 ) {
|
||||
tree->Branch("xElum2", &xElum2, "xElum2/D");
|
||||
tree->Branch("yElum2", &yElum2, "yElum2/D");
|
||||
tree->Branch("rhoElum2", &rhoElum2, "rhoElum2/D");
|
||||
}
|
||||
|
||||
///in case need other recoil detector.
|
||||
double xRecoil1, yRecoil1, rhoRecoil1;
|
||||
if( aux.detPos1 != 0 ){
|
||||
tree->Branch("xRecoil1", &xRecoil1, "xRecoil1/D");
|
||||
tree->Branch("yRecoil1", &yRecoil1, "yRecoil1/D");
|
||||
tree->Branch("rhoRecoil1", &rhoRecoil1, "rhoRecoil1/D");
|
||||
}
|
||||
double xRecoil2, yRecoil2, rhoRecoil2;
|
||||
if( aux.detPos2 != 0 ){
|
||||
tree->Branch("xRecoil2", &xRecoil2, "xRecoil2/D");
|
||||
tree->Branch("yRecoil2", &yRecoil2, "yRecoil2/D");
|
||||
tree->Branch("rhoRecoil2", &rhoRecoil2, "rhoRecoil2/D");
|
||||
}
|
||||
//======= function for e-z plot for ideal case
|
||||
printf("++++ generate functions\n");
|
||||
TObjArray * gList = new TObjArray();
|
||||
gList->SetName("Constant thetaCM lines");
|
||||
const int gxSize = 50;
|
||||
TF1 ** gx = new TF1*[gxSize];
|
||||
TString name;
|
||||
|
||||
double mb = transfer.GetMass_b();
|
||||
double betaRect = transfer.GetReactionBeta();
|
||||
double gamma = transfer.GetReactionGamma();
|
||||
double slope = transfer.GetEZSlope(helios.GetBField()); /// MeV/mm
|
||||
|
||||
for( int i = 0; i < gxSize; i++){
|
||||
name.Form("g%d", i);
|
||||
gx[i] = new TF1(name, "([0]*TMath::Sqrt([1]+[2]*x*x)+[5]*x)/([3]) - [4]", -1000, 1000);
|
||||
double thetacm = i * TMath::DegToRad();
|
||||
double gS2 = TMath::Power(TMath::Sin(thetacm)*gamma,2);
|
||||
gx[i]->SetParameter(0, TMath::Cos(thetacm));
|
||||
gx[i]->SetParameter(1, mb*mb*(1-gS2));
|
||||
gx[i]->SetParameter(2, TMath::Power(slope/betaRect,2));
|
||||
gx[i]->SetParameter(3, 1-gS2);
|
||||
gx[i]->SetParameter(4, mb);
|
||||
gx[i]->SetParameter(5, -gS2*slope);
|
||||
gx[i]->SetNpx(1000);
|
||||
gList->Add(gx[i]);
|
||||
printf("/");
|
||||
if( i > 1 && i % 40 == 0 ) printf("\n");
|
||||
}
|
||||
gList->Write("EZ_thetaCM", TObject::kSingleKey);
|
||||
printf(" %d constant thetaCM functions\n", gxSize);
|
||||
|
||||
//--- cal modified f
|
||||
TObjArray * fxList = new TObjArray();
|
||||
TGraph ** fx = new TGraph*[numEx];
|
||||
std::vector<double> px, py;
|
||||
int countfx = 0;
|
||||
for( int j = 0 ; j < numEx; j++){
|
||||
double a = helios.GetDetRadius();
|
||||
double q = TMath::Sqrt(mb*mb + kbCM[j] * kbCM[j] );
|
||||
px.clear();
|
||||
py.clear();
|
||||
countfx = 0;
|
||||
for(int i = 0; i < 100; i++){
|
||||
double thetacm = TMath::Pi()/TMath::Log(100) * (TMath::Log(100) - TMath::Log(100-i)) ;//using log scale, for more point in small angle.
|
||||
double temp = TMath::TwoPi() * slope / betaRect / kbCM[j] * a / TMath::Sin(thetacm);
|
||||
double pxTemp = betaRect /slope * (gamma * betaRect * q - gamma * kbCM[j] * TMath::Cos(thetacm)) * (1 - TMath::ASin(temp)/TMath::TwoPi()) ;
|
||||
double pyTemp = gamma * q - mb - gamma * betaRect * kbCM[j] * TMath::Cos(thetacm);
|
||||
if( TMath::IsNaN(pxTemp) || TMath::IsNaN(pyTemp) ) continue;
|
||||
px.push_back(pxTemp);
|
||||
py.push_back(pyTemp);
|
||||
countfx ++;
|
||||
}
|
||||
|
||||
fx[j] = new TGraph(countfx, &px[0], &py[0]);
|
||||
name.Form("fx%d", j);
|
||||
fx[j]->SetName(name);
|
||||
fx[j]->SetLineColor(4);
|
||||
fxList->Add(fx[j]);
|
||||
printf(",");
|
||||
}
|
||||
fxList->Write("EZCurve", TObject::kSingleKey);
|
||||
printf(" %d e-z finite-size detector functions\n", numEx);
|
||||
|
||||
//--- cal modified thetaCM vs z
|
||||
TObjArray * txList = new TObjArray();
|
||||
TGraph ** tx = new TGraph*[numEx];
|
||||
for( int j = 0 ; j < numEx; j++){
|
||||
double a = helios.GetDetRadius();
|
||||
double q = TMath::Sqrt(mb*mb + kbCM[j] * kbCM[j] );
|
||||
px.clear();
|
||||
py.clear();
|
||||
countfx = 0;
|
||||
for(int i = 0; i < 100; i++){
|
||||
double thetacm = (i + 8.) * TMath::DegToRad();
|
||||
double temp = TMath::TwoPi() * slope / betaRect / kbCM[j] * a / TMath::Sin(thetacm);
|
||||
double pxTemp = betaRect /slope * (gamma * betaRect * q - gamma * kbCM[j] * TMath::Cos(thetacm)) * (1 - TMath::ASin(temp)/TMath::TwoPi());
|
||||
double pyTemp = thetacm * TMath::RadToDeg();
|
||||
if( TMath::IsNaN(pxTemp) || TMath::IsNaN(pyTemp) ) continue;
|
||||
px.push_back(pxTemp);
|
||||
py.push_back(pyTemp);
|
||||
countfx ++;
|
||||
}
|
||||
|
||||
tx[j] = new TGraph(countfx, &px[0], &py[0]);
|
||||
name.Form("tx%d", j);
|
||||
tx[j]->SetName(name);
|
||||
tx[j]->SetLineColor(4);
|
||||
txList->Add(tx[j]);
|
||||
printf("*");
|
||||
}
|
||||
txList->Write("thetaCM_Z", TObject::kSingleKey);
|
||||
printf(" %d thetaCM-z for finite-size detector functions\n", numEx);
|
||||
|
||||
//========timer
|
||||
TBenchmark clock;
|
||||
bool shown ;
|
||||
clock.Reset();
|
||||
clock.Start("timer");
|
||||
shown = false;
|
||||
|
||||
//change the number of event into human easy-to-read form
|
||||
int numEvent = reactConfig.numEvents;
|
||||
int digitLen = TMath::Floor(TMath::Log10(numEvent));
|
||||
TString numEventStr;
|
||||
if( 3 <= digitLen && digitLen < 6 ){
|
||||
numEventStr.Form("%5.1f kilo", numEvent/1000.);
|
||||
}else if ( 6<= digitLen && digitLen < 9 ){
|
||||
numEventStr.Form("%6.2f million", numEvent/1e6);
|
||||
}else if ( 9<= digitLen ){
|
||||
numEventStr.Form("%6.2f billion", numEvent/1e9);
|
||||
}
|
||||
printf("\e[32m#################################### generating %s events \e[0m\n", numEventStr.Data());
|
||||
|
||||
double KEA = reactConfig.beamEnergy;
|
||||
double theta = reactConfig.beamTheta;
|
||||
double phi = 0.0;
|
||||
|
||||
//*====================================================== calculate event
|
||||
int count = 0;
|
||||
for( int i = 0; i < numEvent; i++){
|
||||
bool redoFlag = true;
|
||||
if( !reactConfig.isRedo ) redoFlag = false;
|
||||
do{
|
||||
|
||||
//==== Set Ex of B
|
||||
if( numEx == 1 ) {
|
||||
ExID = 0;
|
||||
Ex = exList.ExList[0].Ex + (exList.ExList[0].sigma == 0 ? 0 : gRandom->Gaus(0, exList.ExList[0].sigma));
|
||||
}else{
|
||||
ExID = exDist->GetRandom();
|
||||
Ex = exList.ExList[ExID].Ex + (exList.ExList[ExID].sigma == 0 ? 0 : gRandom->Gaus(0, exList.ExList[ExID].sigma));
|
||||
}
|
||||
transfer.SetExB(Ex);
|
||||
|
||||
//==== Set incident beam
|
||||
if( reactConfig.beamEnergySigma != 0 ){
|
||||
KEA = gRandom->Gaus(reactConfig.beamEnergy, reactConfig.beamEnergySigma);
|
||||
}
|
||||
if( reactConfig.beamThetaSigma != 0 ){
|
||||
theta = gRandom->Gaus(reactConfig.beamTheta, reactConfig.beamThetaSigma);
|
||||
}
|
||||
|
||||
//==== for taregt scattering
|
||||
transfer.SetIncidentEnergyAngle(KEA, theta, 0.);
|
||||
transfer.CalReactionConstant();
|
||||
|
||||
// TLorentzVector PA = transfer.GetPA();
|
||||
//depth = 0;
|
||||
// if( isTargetScattering ){
|
||||
// //==== Target scattering, only energy loss
|
||||
// depth = targetThickness * gRandom->Rndm();
|
||||
// msA.SetTarget(density, depth);
|
||||
// TLorentzVector PAnew = msA.Scattering(PA);
|
||||
// KEAnew = msA.GetKE()/reactConfig.beamA;
|
||||
// transfer.SetIncidentEnergyAngle(KEAnew, theta, phi);
|
||||
// transfer.CalReactionConstant();
|
||||
// Ecm = transfer.GetCMTotalKE();
|
||||
// }
|
||||
|
||||
//==== Calculate thetaCM, phiCM
|
||||
if( distFile->IsOpen()){
|
||||
dist = (TF1 *) distList->At(ExID);
|
||||
thetaCM = dist->GetRandom() / 180. * TMath::Pi();
|
||||
}else{
|
||||
thetaCM = TMath::ACos(2 * gRandom->Rndm() - 1) ;
|
||||
}
|
||||
|
||||
double phiCM = TMath::TwoPi() * gRandom->Rndm();
|
||||
|
||||
//==== Calculate reaction
|
||||
transfer.Event(thetaCM, phiCM);
|
||||
TLorentzVector Pb = transfer.GetPb();
|
||||
TLorentzVector PB = transfer.GetPB();
|
||||
|
||||
// //==== Calculate energy loss of scattered and recoil in target
|
||||
// if( isTargetScattering ){
|
||||
// if( Pb.Theta() < TMath::PiOver2() ){
|
||||
// msb.SetTarget(density, targetThickness - depth);
|
||||
// }else{
|
||||
// msb.SetTarget(density, depth);
|
||||
// }
|
||||
// Pb = msb.Scattering(Pb);
|
||||
// TbLoss = msb.GetKELoss();
|
||||
// msB.SetTarget(density, targetThickness - depth);
|
||||
// PB = msB.Scattering(PB);
|
||||
// }else{
|
||||
// TbLoss = 0;
|
||||
// }
|
||||
|
||||
//======= Decay of particle-B
|
||||
int decayID = 0;
|
||||
if( recoil.isDecay){
|
||||
|
||||
decayID = decay.CalDecay(PB, Ex, 0, phiCM + TMath::Pi()/2); // decay to ground state
|
||||
if( decayID == 1 ){
|
||||
PB = decay.GetDaugther_D();
|
||||
//decayTheta = decay.GetAngleChange();
|
||||
decayTheta = decay.GetThetaCM();
|
||||
PB.SetUniqueID(recoil.decayZ);
|
||||
}else{
|
||||
decayTheta = TMath::QuietNaN();
|
||||
}
|
||||
}
|
||||
|
||||
//################################### tree branches
|
||||
//===== reaction
|
||||
thetab = Pb.Theta() * TMath::RadToDeg();
|
||||
thetaB = PB.Theta() * TMath::RadToDeg();
|
||||
|
||||
Tb = Pb.E() - Pb.M();
|
||||
TB = PB.E() - PB.M();
|
||||
|
||||
phib = Pb.Phi() * TMath::RadToDeg();
|
||||
phiB = PB.Phi() * TMath::RadToDeg();
|
||||
|
||||
//==== Helios
|
||||
|
||||
// printf(" thetaCM : %f, Tb : %f\n", thetaCM * TMath::RadToDeg(), Pb.M());
|
||||
|
||||
if( Tb > 0 || TB > 0 ){
|
||||
|
||||
helios.CalArrayHit(Pb);
|
||||
helios.CalRecoilHit(PB);
|
||||
hit = 2;
|
||||
while( hit > 1 ){ hit = helios.CheckDetAcceptance(); } /// while hit > 1, goto next loop;
|
||||
|
||||
trajectory orb_b = helios.GetTrajectory_b();
|
||||
trajectory orb_B = helios.GetTrajectory_B();
|
||||
|
||||
e = helios.GetEnergy() + gRandom->Gaus(0, array.eSigma );
|
||||
|
||||
double ranX = gRandom->Gaus(0, array.zSigma);
|
||||
z = orb_b.z + ranX;
|
||||
detX = helios.GetDetX() + ranX;
|
||||
|
||||
z0 = orb_b.z0;
|
||||
t = orb_b.t;
|
||||
loop = orb_b.loop;
|
||||
detID = orb_b.detID;
|
||||
detRowID = orb_b.detRowID;
|
||||
rho = orb_b.rho;
|
||||
rhoArray = orb_b.R;
|
||||
|
||||
xArray = orb_b.x;
|
||||
yArray = orb_b.y;
|
||||
|
||||
|
||||
//ELUM
|
||||
if( aux.elumPos1 != 0 ){
|
||||
xElum1 = helios.GetXPos(aux.elumPos1);
|
||||
yElum1 = helios.GetYPos(aux.elumPos1);
|
||||
rhoElum1 = helios.GetR(aux.elumPos1);
|
||||
}
|
||||
if( aux.elumPos2 != 0 ){
|
||||
xElum2 = helios.GetXPos(aux.elumPos2);
|
||||
yElum2 = helios.GetYPos(aux.elumPos2);
|
||||
rhoElum2 = helios.GetR(aux.elumPos2);
|
||||
}
|
||||
|
||||
//Recoil
|
||||
rhoRecoil = orb_B.R;
|
||||
tB = orb_B.t;
|
||||
xRecoil = orb_B.x;
|
||||
yRecoil = orb_B.y;
|
||||
rhoB = orb_B.rho;
|
||||
|
||||
//other recoil detectors
|
||||
if ( aux.detPos1 != 0 ){
|
||||
xRecoil1 = helios.GetRecoilXPos(aux.detPos1);
|
||||
yRecoil1 = helios.GetRecoilYPos(aux.detPos1);
|
||||
rhoRecoil1 = helios.GetRecoilR(aux.detPos1);
|
||||
}
|
||||
if ( aux.detPos2 != 0 ){
|
||||
xRecoil2 = helios.GetRecoilXPos(aux.detPos2);
|
||||
yRecoil2 = helios.GetRecoilYPos(aux.detPos2);
|
||||
rhoRecoil2 = helios.GetRecoilR(aux.detPos2);
|
||||
}
|
||||
|
||||
std::pair<double,double> ExThetaCM = transfer.CalExThetaCM(e, z, helios.GetBField(), helios.GetDetRadius());
|
||||
ExCal = ExThetaCM.first;
|
||||
thetaCMCal = ExThetaCM.second;
|
||||
|
||||
//change thetaCM into deg
|
||||
thetaCM = thetaCM * TMath::RadToDeg();
|
||||
|
||||
//if decay, get the light decay particle on the recoil;
|
||||
if( recoil.isDecay ){
|
||||
if( decayID == 1 ){
|
||||
TLorentzVector Pd = decay.GetDaugther_d();
|
||||
|
||||
Td = Pd.E() - Pd.M();
|
||||
|
||||
helios.CalRecoilHit(Pd);
|
||||
|
||||
trajectory orb_d = helios.GetTrajectory_B();
|
||||
rhoRecoil_d = orb_d.R;
|
||||
xRecoil_d = orb_d.x;
|
||||
yRecoil_d = orb_d.y;
|
||||
|
||||
}else{
|
||||
rhoRecoil_d = TMath::QuietNaN();
|
||||
xRecoil_d = TMath::QuietNaN();
|
||||
yRecoil_d = TMath::QuietNaN();
|
||||
}
|
||||
}
|
||||
|
||||
}else{
|
||||
hit = -404;
|
||||
}
|
||||
|
||||
if( hit == 1) count ++;
|
||||
|
||||
if( reactConfig.isRedo ){
|
||||
if( hit == 1) {
|
||||
redoFlag = false;
|
||||
}else{
|
||||
redoFlag = true;
|
||||
//printf("%d, %2d, thetaCM : %f, theta : %f, z0: %f \n", i, hit, thetaCM * TMath::RadToDeg(), thetab, helios.GetZ0());
|
||||
}
|
||||
}else{
|
||||
redoFlag = false;
|
||||
}
|
||||
|
||||
}while( redoFlag );
|
||||
tree->Fill();
|
||||
|
||||
//#################################################################### Timer
|
||||
clock.Stop("timer");
|
||||
Double_t time = clock.GetRealTime("timer");
|
||||
clock.Start("timer");
|
||||
|
||||
if ( !shown ) {
|
||||
if (fmod(time, 10) < 1 ){
|
||||
printf( "%10d[%2d%%]| %8.2f sec | expect: %5.1f min \n", i, TMath::Nint((i+1)*100./numEvent), time , numEvent*time/(i+1)/60);
|
||||
shown = 1;
|
||||
}
|
||||
}else{
|
||||
if (fmod(time, 10) > 9 ){
|
||||
shown = 0;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
saveFile->Write();
|
||||
saveFile->Close();
|
||||
|
||||
distFile->Close();
|
||||
delete exDist;
|
||||
|
||||
printf("=============== done. saved as %s. count(hit==1) : %d\n", saveFileName.Data(), count);
|
||||
//gROOT->ProcessLine(".q");
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
|
||||
int main (int argc, char *argv[]) {
|
||||
|
||||
printf("=================================================================\n");
|
||||
printf("========== Simulate Transfer reaction in HELIOS ==========\n");
|
||||
printf("=================================================================\n");
|
||||
|
||||
if(argc == 2 || argc > 7) {
|
||||
printf("Usage: ./Transfer [1] [2] [3] [4] [5] [6]\n");
|
||||
printf(" default file name \n");
|
||||
printf(" [1] reactionConfig.txt (input) reaction Setting \n");
|
||||
printf(" [2] detectorGeo.txt (input) detector Setting \n");
|
||||
printf(" [3] ID (input) detector & reaction ID (default = 0 ) \n");
|
||||
printf(" [4] DWBA.root (input) thetaCM distribution from DWBA \n");
|
||||
printf(" [5] transfer.root (output) rootFile name for output \n");
|
||||
printf(" [6] plot (input) will it plot stuffs [1/0] \n");
|
||||
|
||||
printf("------------------------------------------------------\n");
|
||||
return 0 ;
|
||||
}
|
||||
|
||||
std::string basicConfig = "reactionConfig.txt";
|
||||
std::string heliosDetGeoFile = "detectorGeo.txt";
|
||||
int ID = 0;
|
||||
TString ptolemyRoot = "DWBA.root"; // when no file, use isotropic distribution of thetaCM
|
||||
TString saveFileName; // format based on ID;
|
||||
bool isPlot = false;
|
||||
|
||||
if( argc >= 2) basicConfig = argv[1];
|
||||
if( argc >= 3) heliosDetGeoFile = argv[2];
|
||||
if( argc >= 4) ID = atoi(argv[3]);
|
||||
if( argc >= 5) ptolemyRoot = argv[4];
|
||||
if( argc >= 6) saveFileName = argv[5];
|
||||
if( argc >= 7) isPlot = atoi(argv[7]);
|
||||
|
||||
saveFileName = Form("transfer_%d.root", ID);
|
||||
|
||||
Transfer( basicConfig, heliosDetGeoFile, ID, ptolemyRoot, saveFileName);
|
||||
|
||||
//run Armory/Check_Simulation
|
||||
if( isPlot ){
|
||||
std::ifstream file_in;
|
||||
file_in.open("../Cleopatra/Check_Simulation.C", std::ios::in);
|
||||
if( file_in){
|
||||
printf("---- running ../Cleopatra/Check_Simulation.C on %s \n", saveFileName.Data());
|
||||
TString cmd;
|
||||
cmd.Form("root -l '../Cleopatra/Check_Simulation.C(\"%s\")'", saveFileName.Data());
|
||||
|
||||
system(cmd.Data());
|
||||
}else{
|
||||
printf("cannot find ../Cleopatra/Check_Simulation.C \n");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,240 +0,0 @@
|
|||
#include "TString.h"
|
||||
#include "TFile.h"
|
||||
#include "TTree.h"
|
||||
#include "TH2.h"
|
||||
#include "TStyle.h"
|
||||
#include "TCanvas.h"
|
||||
#include "TArc.h"
|
||||
#include "TLine.h"
|
||||
#include "TLatex.h"
|
||||
#include "TMacro.h"
|
||||
|
||||
#include "../Armory/AnalysisLib.h"
|
||||
#include "../Armory/ClassDetGeo.h"
|
||||
#include "../Armory/ClassReactionConfig.h"
|
||||
#include "../Cleopatra/ClassIsotope.h"
|
||||
#include "../Cleopatra/ClassTransfer.h"
|
||||
|
||||
void SimulationChecker(TString transferRoot = "transfer.root"){
|
||||
|
||||
gStyle->SetOptStat("");
|
||||
gStyle->SetStatY(0.9);
|
||||
gStyle->SetStatX(0.9);
|
||||
gStyle->SetStatW(0.4);
|
||||
gStyle->SetStatH(0.2);
|
||||
gStyle->SetLabelSize(0.05, "XY");
|
||||
gStyle->SetTitleFontSize(0.1);
|
||||
|
||||
TFile * file = new TFile(transferRoot, "read");
|
||||
TTree * tree = (TTree*) file->Get("tree");
|
||||
|
||||
TObjArray * fxList = (TObjArray *) file->FindObjectAny("EZCurve");
|
||||
|
||||
//*================================== List Of Reactions
|
||||
TMacro * listOfReaction = (TMacro *) file->FindObjectAny("ListOfReactions");
|
||||
|
||||
int numReaction = listOfReaction->GetListOfLines()->GetSize();
|
||||
|
||||
std::vector<int> reactionIDList(numReaction, -1);
|
||||
std::vector<TString> reactionNameList(numReaction, "");
|
||||
for( int i = 0; i < numReaction; i++){
|
||||
std::vector<std::string> tempStr = AnalysisLib::SplitStr(listOfReaction->GetListOfLines()->At(i)->GetName(), "|");
|
||||
reactionIDList[i] = atoi(tempStr[0].c_str());
|
||||
reactionNameList[i] = tempStr[1];
|
||||
}
|
||||
|
||||
// for( int i = 0; i < numReaction; i++) printf("%2d | %s\n", reactionIDList[i], reactionNameList[i].Data());
|
||||
|
||||
//*================================== DWBA, if any
|
||||
TMacro * dwbaReaction = (TMacro *) file->FindObjectAny("DWBA_ReactionList");
|
||||
TMacro * dwbaExList = (TMacro *) file->FindObjectAny("DWBA_ExList");
|
||||
// dwbaReaction->Print();
|
||||
// dwbaExList->Print();
|
||||
|
||||
|
||||
//*================================== reactionConfig
|
||||
TMacro * reactionConfigTxt = (TMacro *) file->FindObjectAny("reactionConfig");
|
||||
|
||||
ReactionConfig reactionConfig(reactionConfigTxt);
|
||||
|
||||
int nEvent = reactionConfig.numEvents;
|
||||
printf("number of events generated : %d \n", nEvent);
|
||||
|
||||
//=== clear the Ex in reactionCondig if DWBA_ReactionList
|
||||
if( dwbaReaction || listOfReaction ){
|
||||
for( int i = 0; i < numReaction; i ++){
|
||||
reactionConfig.exList[reactionIDList[i]].Clear();
|
||||
|
||||
for( int j = 0; j < dwbaReaction->GetListOfLines()->GetSize(); j++){
|
||||
std::vector<std::string> haha = AnalysisLib::SplitStr(dwbaReaction->GetListOfLines()->At(j)->GetName(), "|");
|
||||
|
||||
if( atoi(haha[1].c_str()) == reactionIDList[i] ) {
|
||||
std::vector<std::string> dudu = AnalysisLib::SplitStr(dwbaExList->GetListOfLines()->At(j+1)->GetName(), " ");
|
||||
|
||||
reactionConfig.exList[reactionIDList[i]].Add(atof(dudu[0].c_str()), atof(dudu[1].c_str()), 1.0, 0.00);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
reactionConfig.Print(reactionIDList[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
//*================================== detector Geometry
|
||||
printf("=================================\n");
|
||||
printf(" loading detector Geometry.\n");
|
||||
TMacro * detGeoTxt = (TMacro *) file->FindObjectAny("detGeo");
|
||||
|
||||
DetGeo detGeo(detGeoTxt);
|
||||
|
||||
detGeo.Print(true);
|
||||
|
||||
printf("%f %f \n", detGeo.array[0].zMin, detGeo.array[0].zMax);
|
||||
|
||||
printf("=================================\n");
|
||||
|
||||
//*==================================
|
||||
|
||||
int padSize = 500;
|
||||
int Div[2] = {5, numReaction};
|
||||
Int_t size[2] = {padSize,padSize}; ///x,y, single Canvas size
|
||||
TCanvas * cCheck = new TCanvas("cCheck", "Check For Simulation", 0, 0, size[0]*Div[0], size[1]*Div[1]);
|
||||
if(cCheck->GetShowEditor() )cCheck->ToggleEditor();
|
||||
if(cCheck->GetShowToolBar() )cCheck->ToggleToolBar();
|
||||
cCheck->Divide(Div[0],Div[1]);
|
||||
|
||||
bool shownKELines = true;
|
||||
TString gate = "hit == 1 && loop <= 1 && thetaCM > 10";
|
||||
|
||||
//^-------------------------------
|
||||
cCheck->cd(1);
|
||||
{
|
||||
TH2F * hez = new TH2F("hez", Form("e-z [gated] @ %5.0f mm; z [mm]; e [MeV]", detGeo.array[0].firstPos),
|
||||
400, detGeo.array[0].zMin, detGeo.array[0].zMax,
|
||||
400, 0, 10);
|
||||
|
||||
tree->Draw("e:z>>hez", gate + " && rID == 0", "colz");
|
||||
}
|
||||
|
||||
//^-------------------------------
|
||||
cCheck->cd(2);
|
||||
{
|
||||
TH2F * hRecoilXY = new TH2F("hRecoilXY", Form("RecoilXY [gated] @ %4.0f mm; X [mm]; Y [mm]", detGeo.aux[0].detPos ),
|
||||
400, -detGeo.aux[0].outerRadius, detGeo.aux[0].outerRadius,
|
||||
400, -detGeo.aux[0].outerRadius, detGeo.aux[0].outerRadius);
|
||||
tree->Draw("yRecoil:xRecoil>>hRecoilXY", gate + " && rID == 0", "colz");
|
||||
TArc * detArc1 = new TArc(0,0, detGeo.aux[0].outerRadius);
|
||||
detArc1->SetLineColor(kBlue-8);
|
||||
detArc1->SetFillStyle(0);
|
||||
detArc1->Draw("same");
|
||||
TArc * detArc2 = new TArc(0,0, detGeo.aux[0].innerRadius);
|
||||
detArc2->SetLineColor(kBlue-8);
|
||||
detArc2->SetFillStyle(0);
|
||||
detArc2->Draw("same");
|
||||
|
||||
if( reactionConfig.beamX != 0. || reactionConfig.beamY != 0. ){
|
||||
TArc * arc = new TArc(reactionConfig.beamX, reactionConfig.beamY, 1);
|
||||
arc->SetLineColor(2);
|
||||
detArc1->SetFillStyle(0);
|
||||
arc->Draw("same");
|
||||
}
|
||||
}
|
||||
//^-------------------------------
|
||||
cCheck->cd(3);
|
||||
{
|
||||
// TH1F * hThetaCM[numEx];
|
||||
// TLegend * legend = new TLegend(0.8,0.2,0.99,0.8);
|
||||
// double maxCount = 0;
|
||||
// int startID = 0; // set the start ExID
|
||||
// for( int i = startID; i < numEx; i++){
|
||||
// hThetaCM[i] = new TH1F(Form("hThetaCM%d", i), Form("thetaCM [gated] (ExID=%d); thetaCM [deg]; count", i), 200, thetaCMRange[0], thetaCMRange[1]);
|
||||
// hThetaCM[i]->SetLineColor(i+1-startID);
|
||||
// hThetaCM[i]->SetFillColor(i+1-startID);
|
||||
// hThetaCM[i]->SetFillStyle(3000+i-startID);
|
||||
// tree->Draw(Form("thetaCM>>hThetaCM%d", i), gate + Form("&& ExID==%d", i), "");
|
||||
// legend->AddEntry(hThetaCM[i], Form("Ex=%5.1f MeV", exList.ExList[i].Ex));
|
||||
// double max = hThetaCM[i]->GetMaximum();
|
||||
// if( max > maxCount ) maxCount = max;
|
||||
// }
|
||||
|
||||
// for( int i = startID; i < numEx; i++){
|
||||
// hThetaCM[i]->GetYaxis()->SetRangeUser(1, maxCount * 1.2);
|
||||
// if( i == startID ) {
|
||||
// hThetaCM[i]->Draw();
|
||||
// }else{
|
||||
// hThetaCM[i]->Draw("same");
|
||||
// }
|
||||
// }
|
||||
// legend->Draw();
|
||||
}
|
||||
|
||||
//^-------------------------------
|
||||
cCheck->cd(4);
|
||||
{
|
||||
TLatex text;
|
||||
text.SetNDC();
|
||||
text.SetTextFont(82);
|
||||
text.SetTextSize(0.06);
|
||||
text.SetTextColor(2);
|
||||
|
||||
text.DrawLatex(0., 0.9, reactionNameList[0]);
|
||||
text.DrawLatex(0., 0.8, detGeo.Bfield > 0 ? "out of plan" : "into plan");
|
||||
text.SetTextColor(1);
|
||||
text.DrawLatex(0., 0.7, "gate:");
|
||||
|
||||
text.SetTextColor(2);
|
||||
//check gate text length, if > 30, break by "&&"
|
||||
int ll = gate.Length();
|
||||
if( ll > 30 ) {
|
||||
std::vector<string> strList = AnalysisLib::SplitStr( (std::string) gate.Data(), "&&");
|
||||
for( int i = 0; i < strList.size(); i++){
|
||||
text.DrawLatex(0., 0.6 - 0.05*i, (TString) strList[i]);
|
||||
}
|
||||
}else{
|
||||
text.DrawLatex(0., 0.6, gate);
|
||||
}
|
||||
|
||||
if( reactionConfig.beamX != 0.0 || reactionConfig.beamY != 0.0 ){
|
||||
text.DrawLatex(0.0, 0.1, Form("Bema pos: (%4.1f, %4.1f) mm", reactionConfig.beamX, reactionConfig.beamY));
|
||||
}
|
||||
}
|
||||
//^-------------------------------
|
||||
cCheck->cd(5);
|
||||
{
|
||||
TH1F * hExCal = new TH1F("hExCal", Form("calculated Ex [gated]; Ex [MeV]; count / %.2f keV", 10.), 400, -1, 3);
|
||||
tree->Draw("ExCal>>hExCal", gate + " && rID == 0", "");
|
||||
Isotope hRecoil(reactionConfig.recoil[0].heavyA, reactionConfig.recoil[0].heavyZ);
|
||||
double Sn = hRecoil.CalSp(0,1);
|
||||
double Sp = hRecoil.CalSp(1,0);
|
||||
double Sa = hRecoil.CalSp2(4,2);
|
||||
double S2n = hRecoil.CalSp(0, 2);
|
||||
|
||||
printf("Heavy recoil: %s \n", hRecoil.Name.c_str());
|
||||
printf("Sn : %f MeV/u \n", Sn);
|
||||
printf("Sp : %f MeV/u \n", Sp);
|
||||
printf("Sa : %f MeV/u \n", Sa);
|
||||
printf("S2n : %f MeV/u \n", S2n);
|
||||
|
||||
double yMax = hExCal->GetMaximum();
|
||||
TLine * lineSn = new TLine(Sn, 0, Sn, yMax); lineSn->SetLineColor(2); lineSn->Draw("");
|
||||
TLine * lineSp = new TLine(Sp, 0, Sp, yMax); lineSp->SetLineColor(4); lineSp->Draw("same");
|
||||
TLine * lineSa = new TLine(Sa, 0, Sa, yMax); lineSa->SetLineColor(6); lineSa->Draw("same");
|
||||
TLine * lineS2n = new TLine(S2n, 0, S2n, yMax); lineS2n->SetLineColor(8); lineS2n->Draw("same");
|
||||
|
||||
TLatex * text = new TLatex();
|
||||
text->SetTextFont(82);
|
||||
text->SetTextSize(0.06);
|
||||
text->SetTextColor(2); text->DrawLatex(Sn, yMax*0.9, "S_{n}");
|
||||
text->SetTextColor(4); text->DrawLatex(Sp, yMax*0.9, "S_{p}");
|
||||
text->SetTextColor(6); text->DrawLatex(Sa, yMax*0.9, "S_{a}");
|
||||
text->SetTextColor(8); text->DrawLatex(S2n, yMax*0.9, "S_{2n}");
|
||||
|
||||
}
|
||||
|
||||
cCheck->Modified();
|
||||
cCheck->Update();
|
||||
|
||||
}
|
|
@ -5,7 +5,6 @@
|
|||
#include <TGButton.h>
|
||||
#include <TGLabel.h>
|
||||
#include <TGFrame.h>
|
||||
#include <TGComboBox.h>
|
||||
#include <TGTextEditor.h>
|
||||
#include <TGNumberEntry.h>
|
||||
#include <TGComboBox.h>
|
||||
|
@ -13,13 +12,13 @@
|
|||
#include <RQ_OBJECT.h>
|
||||
|
||||
|
||||
#include "../Cleopatra/SimTransfer.C"
|
||||
#include "../Cleopatra/Transfer.h"
|
||||
#include "../Cleopatra/InFileCreator.h"
|
||||
#include "../Cleopatra/ExtractXSec.h"
|
||||
#include "../Cleopatra/PlotTGraphTObjArray.h"
|
||||
#include "../Armory/AutoFit.C"
|
||||
#include "../Armory/AnalysisLib.h"
|
||||
#include "../Cleopatra/SimChecker.C"
|
||||
#include "../armory/AutoFit.C"
|
||||
#include "../armory/AnalysisLib.h"
|
||||
#include "../Cleopatra/Check_Simulation.C"
|
||||
|
||||
#include <iostream>
|
||||
#include <stdexcept>
|
||||
|
@ -35,42 +34,45 @@
|
|||
TString isoFileName;
|
||||
|
||||
class MyMainFrame {
|
||||
RQ_OBJECT("MyMainFrame")
|
||||
|
||||
RQ_OBJECT("MyMainFrame")
|
||||
private:
|
||||
TGMainFrame *fMain;
|
||||
|
||||
TGTextEdit * editor;
|
||||
|
||||
TString fileName;
|
||||
|
||||
TGLabel * fileLabel;
|
||||
TGLabel * statusLabel;
|
||||
|
||||
TGNumberEntry * angMin;
|
||||
TGNumberEntry * angMax;
|
||||
TGNumberEntry * angStep;
|
||||
|
||||
TGCheckButton * withDWBA;
|
||||
|
||||
TGCheckButton * isInFile;
|
||||
TGCheckButton * isRun;
|
||||
TGCheckButton * isExtract;
|
||||
TGCheckButton * isPlot;
|
||||
|
||||
TGComboBox * extractFlag;
|
||||
|
||||
TGTextEntry * txtName ;
|
||||
TGTextEntry * txtEx ;
|
||||
TGMainFrame *fMain;
|
||||
|
||||
TGTextEdit * editor;
|
||||
|
||||
TString fileName;
|
||||
|
||||
TGLabel * fileLabel;
|
||||
TGLabel * statusLabel;
|
||||
|
||||
TGNumberEntry * angMin;
|
||||
TGNumberEntry * angMax;
|
||||
TGNumberEntry * angStep;
|
||||
|
||||
TGCheckButton * withDWBA;
|
||||
|
||||
TGCheckButton * isInFile;
|
||||
TGCheckButton * isRun;
|
||||
TGCheckButton * isExtract;
|
||||
TGCheckButton * isPlot;
|
||||
|
||||
TGComboBox * extractFlag;
|
||||
|
||||
|
||||
TGTextEntry * txtName ;
|
||||
TGTextEntry * txtEx ;
|
||||
|
||||
bool isUse2ndArray;
|
||||
|
||||
public:
|
||||
MyMainFrame(const TGWindow *p,UInt_t w,UInt_t h);
|
||||
virtual ~MyMainFrame();
|
||||
void Command(int);
|
||||
void OpenFile(int);
|
||||
void GetData();
|
||||
bool IsFileExist(TString filename);
|
||||
MyMainFrame(const TGWindow *p,UInt_t w,UInt_t h);
|
||||
virtual ~MyMainFrame();
|
||||
void Command(int);
|
||||
void OpenFile(int);
|
||||
void GetData();
|
||||
bool IsFileExist(TString filename);
|
||||
|
||||
void CheckIsUse2ndArray();
|
||||
};
|
||||
|
||||
|
||||
|
@ -84,7 +86,7 @@ MyMainFrame::MyMainFrame(const TGWindow *p,UInt_t w,UInt_t h) {
|
|||
TGVerticalFrame *hframe1 = new TGVerticalFrame(fMain,600,600 );
|
||||
hframe->AddFrame(hframe1);
|
||||
|
||||
TGVerticalFrame *hframe2 = new TGVerticalFrame(fMain,600,1000 );
|
||||
TGVerticalFrame *hframe2 = new TGVerticalFrame(fMain,600,800 );
|
||||
hframe->AddFrame(hframe2,new TGLayoutHints( kLHintsExpandX | kLHintsExpandY, 2,2,2,2));
|
||||
|
||||
fileName = "../working/detectorGeo.txt";
|
||||
|
@ -143,11 +145,18 @@ MyMainFrame::MyMainFrame(const TGWindow *p,UInt_t w,UInt_t h) {
|
|||
openRec->ChangeOptions( openRec->GetOptions() | kFixedSize );
|
||||
openRec->Connect("Clicked()","MyMainFrame",this, "OpenFile(=1)");
|
||||
simFrame->AddFrame(openRec,new TGLayoutHints(kLHintsRight, 5,5,3,4));
|
||||
|
||||
TGTextButton *openEx = new TGTextButton(simFrame, "Ex List");
|
||||
openEx->SetWidth(150);
|
||||
openEx->SetHeight(20);
|
||||
openEx->ChangeOptions( openEx->GetOptions() | kFixedSize );
|
||||
openEx->Connect("Clicked()","MyMainFrame",this, "OpenFile(=2)");
|
||||
simFrame->AddFrame(openEx,new TGLayoutHints(kLHintsRight, 5,5,3,4));
|
||||
|
||||
withDWBA = new TGCheckButton(simFrame, "Sim with DWBA");
|
||||
withDWBA = new TGCheckButton(simFrame, "Sim with DWBA\n+DWBA.root\n+DWBA.Ex.txt");
|
||||
withDWBA->SetWidth(140);
|
||||
withDWBA->ChangeOptions(kFixedSize );
|
||||
simFrame->AddFrame(withDWBA, new TGLayoutHints(kLHintsRight, 5,5,3,4));
|
||||
simFrame->AddFrame(withDWBA, new TGLayoutHints(kLHintsLeft, 5,5,3,4));
|
||||
|
||||
TGTextButton *Sim = new TGTextButton(simFrame,"Simulate");
|
||||
Sim->SetWidth(150);
|
||||
|
@ -288,32 +297,32 @@ MyMainFrame::MyMainFrame(const TGWindow *p,UInt_t w,UInt_t h) {
|
|||
}
|
||||
|
||||
|
||||
// {//====================== Nuclear data API
|
||||
// TGGroupFrame * dataFrame = new TGGroupFrame(hframe1, "Nuclear Data", kVerticalFrame);
|
||||
// hframe1->AddFrame(dataFrame, new TGLayoutHints(kLHintsCenterX, 5,5,3,4));
|
||||
{//====================== Nuclear data API
|
||||
TGGroupFrame * dataFrame = new TGGroupFrame(hframe1, "Nuclear Data", kVerticalFrame);
|
||||
hframe1->AddFrame(dataFrame, new TGLayoutHints(kLHintsCenterX, 5,5,3,4));
|
||||
|
||||
// TGHorizontalFrame * hfData = new TGHorizontalFrame(dataFrame); dataFrame->AddFrame(hfData, new TGLayoutHints(kLHintsNormal, 0, 0, 5, 0));
|
||||
TGHorizontalFrame * hfData = new TGHorizontalFrame(dataFrame); dataFrame->AddFrame(hfData, new TGLayoutHints(kLHintsNormal, 0, 0, 5, 0));
|
||||
|
||||
// TGVerticalFrame * vfLabel = new TGVerticalFrame(hfData, 200); hfData->AddFrame(vfLabel );
|
||||
// TGVerticalFrame * vfTxt = new TGVerticalFrame(hfData); hfData->AddFrame(vfTxt);
|
||||
TGVerticalFrame * vfLabel = new TGVerticalFrame(hfData, 200); hfData->AddFrame(vfLabel );
|
||||
TGVerticalFrame * vfTxt = new TGVerticalFrame(hfData); hfData->AddFrame(vfTxt);
|
||||
|
||||
// TGLayoutHints * haha = new TGLayoutHints(kLHintsRight | kLHintsCenterY, 5,5,5,2);
|
||||
// TGLayoutHints * kaka = new TGLayoutHints(kLHintsLeft | kLHintsCenterY, 5,5,0,0);
|
||||
TGLayoutHints * haha = new TGLayoutHints(kLHintsRight | kLHintsCenterY, 5,5,5,2);
|
||||
TGLayoutHints * kaka = new TGLayoutHints(kLHintsLeft | kLHintsCenterY, 5,5,0,0);
|
||||
|
||||
// TGLabel * lb1 = new TGLabel(vfLabel, "Nuclear Name :"); vfLabel->AddFrame(lb1, haha);
|
||||
// TGLabel * lb2 = new TGLabel(vfLabel, "Max Ex [MeV] :"); vfLabel->AddFrame(lb2, haha);
|
||||
TGLabel * lb1 = new TGLabel(vfLabel, "Nuclear Name :"); vfLabel->AddFrame(lb1, haha);
|
||||
TGLabel * lb2 = new TGLabel(vfLabel, "Max Ex [MeV] :"); vfLabel->AddFrame(lb2, haha);
|
||||
|
||||
|
||||
// txtName = new TGTextEntry(vfTxt, "25F"); vfTxt->AddFrame(txtName, kaka); txtName->Resize(50, 20);
|
||||
// txtEx = new TGTextEntry(vfTxt, "0"); vfTxt->AddFrame(txtEx, kaka); txtEx->Resize(50, 20);
|
||||
txtName = new TGTextEntry(vfTxt, "25F"); vfTxt->AddFrame(txtName, kaka); txtName->Resize(50, 20);
|
||||
txtEx = new TGTextEntry(vfTxt, "0"); vfTxt->AddFrame(txtEx, kaka); txtEx->Resize(50, 20);
|
||||
|
||||
// TGTextButton *GetData = new TGTextButton(dataFrame, "Get Data");
|
||||
// GetData->SetWidth(150);
|
||||
// GetData->SetHeight(40);
|
||||
// GetData->ChangeOptions( GetData->GetOptions() | kFixedSize );
|
||||
// GetData->Connect("Clicked()","MyMainFrame",this,"GetData()");
|
||||
// dataFrame->AddFrame(GetData,new TGLayoutHints(kLHintsRight, 5,5,3,4));
|
||||
// }
|
||||
TGTextButton *GetData = new TGTextButton(dataFrame, "Get Data");
|
||||
GetData->SetWidth(150);
|
||||
GetData->SetHeight(40);
|
||||
GetData->ChangeOptions( GetData->GetOptions() | kFixedSize );
|
||||
GetData->Connect("Clicked()","MyMainFrame",this,"GetData()");
|
||||
dataFrame->AddFrame(GetData,new TGLayoutHints(kLHintsRight, 5,5,3,4));
|
||||
}
|
||||
|
||||
TGTextButton *exit = new TGTextButton(hframe1,"Exit", "gApplication->Terminate(0)");
|
||||
exit->SetWidth(150);
|
||||
|
@ -347,6 +356,14 @@ bool MyMainFrame::IsFileExist(TString filename){
|
|||
return file.is_open();
|
||||
}
|
||||
|
||||
void MyMainFrame::CheckIsUse2ndArray(){
|
||||
|
||||
TMacro * haha = new TMacro("../working/detectorGeo.txt");
|
||||
AnalysisLib::DetGeo detGeo = AnalysisLib::LoadDetectorGeo(haha);
|
||||
delete haha;
|
||||
isUse2ndArray = detGeo.use2ndArray;
|
||||
|
||||
}
|
||||
|
||||
void MyMainFrame::OpenFile(int ID){
|
||||
|
||||
|
@ -356,13 +373,23 @@ void MyMainFrame::OpenFile(int ID){
|
|||
|
||||
if ( ID == 0 ) fileName = "../working/detectorGeo.txt";
|
||||
|
||||
if ( ID == 1 ) fileName = "../working/reactionConfig.txt";
|
||||
if ( ID == 3 ) fileName = "../working/DWBA";
|
||||
if ( ID == 5 ) fileName = "../working/DWBA.in";
|
||||
if ( ID == 6 ) fileName = "../working/DWBA.out";
|
||||
if ( ID == 7 ) fileName = "../working/DWBA.Xsec.txt";
|
||||
|
||||
if ( ID == 4 ) fileName = "../working/SimCheckerConfig.txt";
|
||||
CheckIsUse2ndArray();
|
||||
if( isUse2ndArray){
|
||||
if ( ID == 1 ) fileName = "../working/reactionConfig2.txt";
|
||||
if ( ID == 2 ) fileName = "../working/Ex2.txt";
|
||||
if ( ID == 3 ) fileName = "../working/DWBA2";
|
||||
if ( ID == 5 ) fileName = "../working/DWBA2.in";
|
||||
if ( ID == 6 ) fileName = "../working/DWBA2.out";
|
||||
if ( ID == 7 ) fileName = "../working/DWBA2.Xsec.txt";
|
||||
}else{
|
||||
if ( ID == 1 ) fileName = "../working/reactionConfig1.txt";
|
||||
if ( ID == 2 ) fileName = "../working/Ex1.txt";
|
||||
if ( ID == 3 ) fileName = "../working/DWBA1";
|
||||
if ( ID == 5 ) fileName = "../working/DWBA1.in";
|
||||
if ( ID == 6 ) fileName = "../working/DWBA1.out";
|
||||
if ( ID == 7 ) fileName = "../working/DWBA1.Xsec.txt";
|
||||
}
|
||||
if ( ID == 4 ) fileName = "../working/Check_Simulation_Config.txt";
|
||||
if ( ID == 8 ) fileName = isoFileName;
|
||||
|
||||
//test if file exist
|
||||
|
@ -415,6 +442,8 @@ void MyMainFrame::Command(int ID) {
|
|||
|
||||
editor->SaveFile(fileName);
|
||||
|
||||
CheckIsUse2ndArray();
|
||||
|
||||
if( ID == 0 ){
|
||||
|
||||
if( isInFile->GetState()) {
|
||||
|
@ -466,46 +495,61 @@ void MyMainFrame::Command(int ID) {
|
|||
|
||||
if( ID == 1 ){
|
||||
|
||||
string basicConfig = "reactionConfig.txt";
|
||||
string basicConfig = "reactionConfig1.txt";
|
||||
string heliosDetGeoFile = "detectorGeo.txt";
|
||||
string excitationFile = "Ex1.txt"; //when no file, only ground state
|
||||
TString ptolemyRoot = ""; // when no file, use isotropic distribution of thetaCM
|
||||
TString saveFileName = "transfer.root";
|
||||
TString saveFileName = "transfer1.root";
|
||||
TString filename = "reaction1.dat"; //when no file, no output
|
||||
|
||||
if( withDWBA->GetState() ) {
|
||||
ptolemyRoot = "DWBA.root";
|
||||
ptolemyRoot = "DWBA1.root";
|
||||
excitationFile = "DWBA1.Ex.txt";
|
||||
}
|
||||
|
||||
basicConfig = "reactionConfig.txt";
|
||||
heliosDetGeoFile = "detectorGeo.txt";
|
||||
ptolemyRoot = ""; // when no file, use isotropic distribution of thetaCM
|
||||
saveFileName = "transfer.root";
|
||||
|
||||
if( withDWBA->GetState() ) {
|
||||
ptolemyRoot = "DWBA.root";
|
||||
if( isUse2ndArray ){
|
||||
basicConfig = "reactionConfig2.txt";
|
||||
heliosDetGeoFile = "detectorGeo.txt";
|
||||
excitationFile = "Ex2.txt"; //when no file, only ground state
|
||||
ptolemyRoot = ""; // when no file, use isotropic distribution of thetaCM
|
||||
saveFileName = "transfer2.root";
|
||||
filename = "reaction2.dat"; //when no file, no output
|
||||
|
||||
if( withDWBA->GetState() ) {
|
||||
ptolemyRoot = "DWBA2.root";
|
||||
excitationFile = "DWBA2.Ex.txt";
|
||||
}
|
||||
}
|
||||
|
||||
statusLabel->SetText("Running simulation.......");
|
||||
|
||||
Transfer( basicConfig, heliosDetGeoFile, ptolemyRoot, saveFileName);
|
||||
Transfer( basicConfig, heliosDetGeoFile, excitationFile, ptolemyRoot, saveFileName, filename);
|
||||
|
||||
statusLabel->SetText("Plotting simulation.......");
|
||||
|
||||
SimChecker("transfer.root");
|
||||
if( isUse2ndArray ){
|
||||
Check_Simulation("transfer2.root");
|
||||
}else{
|
||||
Check_Simulation("transfer1.root");
|
||||
}
|
||||
|
||||
statusLabel->SetText("Plotted Simulation result");
|
||||
}
|
||||
|
||||
if( ID == 2 ){
|
||||
SimChecker("transfer.root");
|
||||
if( isUse2ndArray ){
|
||||
Check_Simulation("transfer2.root");
|
||||
}else{
|
||||
Check_Simulation("transfer1.root");
|
||||
}
|
||||
statusLabel->SetText(" Run Simulation first.");
|
||||
}
|
||||
|
||||
if( ID == 3 ){
|
||||
if( fileName != "" ){
|
||||
statusLabel->SetText(fileName + " saved.");
|
||||
}else{
|
||||
statusLabel->SetText("cannot save HELP page.");
|
||||
}
|
||||
if( fileName != "" ){
|
||||
statusLabel->SetText(fileName + " saved.");
|
||||
}else{
|
||||
statusLabel->SetText("cannot save HELP page.");
|
||||
}
|
||||
}
|
||||
|
||||
if( ID == 4 ){
|
||||
|
@ -570,14 +614,13 @@ void MyMainFrame::Command(int ID) {
|
|||
|
||||
if( ID == 5) {
|
||||
|
||||
//TODO fit all hExCal
|
||||
TH1F * temp = (TH1F*) gROOT->FindObjectAny("hExCal0");
|
||||
TH1F * temp = (TH1F*) gROOT->FindObjectAny("hExCal");
|
||||
|
||||
if( temp != NULL ){
|
||||
AutoFit::fitAuto(temp, -1);
|
||||
statusLabel->SetText("Auto Fit hExCal");
|
||||
}else{
|
||||
statusLabel->SetText("Cannot find historgram hExCal0. Please Run Plot Simulation first.");
|
||||
statusLabel->SetText("Cannot find historgram hExCal. Please Run Plot Simulation first.");
|
||||
}
|
||||
|
||||
//gROOT->ProcessLine("fitAuto(hExCal, -1)");
|
||||
|
@ -593,7 +636,7 @@ MyMainFrame::~MyMainFrame() {
|
|||
}
|
||||
|
||||
|
||||
void SimHelper() {
|
||||
void Simulation_Helper() {
|
||||
|
||||
new MyMainFrame(gClient->GetRoot(),800,1000);
|
||||
new MyMainFrame(gClient->GetRoot(),800,600);
|
||||
}
|
75
Cleopatra/Transfer.C
Normal file
|
@ -0,0 +1,75 @@
|
|||
/***********************************************************************
|
||||
*
|
||||
* This is Transfer.C for simulation of transfer reaction.
|
||||
*
|
||||
* -----------------------------------------------------
|
||||
* This program will call the root library and compile in g++
|
||||
* compilation:
|
||||
* g++ Transfer.C -o Transfer `root-config --cflags --glibs`
|
||||
*
|
||||
* ------------------------------------------------------
|
||||
* created by Ryan (Tsz Leung) Tang, Feb-4, 2019
|
||||
* email: goluckyryan@gmail.com
|
||||
* ********************************************************************/
|
||||
|
||||
#include <fstream>
|
||||
#include <stdlib.h>
|
||||
#include "Transfer.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
int main (int argc, char *argv[]) {
|
||||
|
||||
printf("=================================================================\n");
|
||||
printf("========== Simulate Transfer reaction in HELIOS ==========\n");
|
||||
printf("=================================================================\n");
|
||||
|
||||
if(argc == 2 || argc > 8) {
|
||||
printf("Usage: ./Transfer [1] [2] [3] [4] [5] [6] [7]\n");
|
||||
printf(" default file name \n");
|
||||
printf(" [1] reactionConfig.txt (input) reaction Setting \n");
|
||||
printf(" [2] detectorGeo.txt (input) detector Setting \n");
|
||||
printf(" [3] Ex.txt (input) Excitation energies \n");
|
||||
printf(" [4] DWBA.root (input) thetaCM distribution from DWBA \n");
|
||||
printf(" [5] transfer.root (output) rootFile name for output \n");
|
||||
printf(" [6] reaction.dat (output) Key reaction parameters \n");
|
||||
printf(" [7] plot (input) will it plot stuffs [1/0] \n");
|
||||
|
||||
printf("------------------------------------------------------\n");
|
||||
return 0 ;
|
||||
}
|
||||
|
||||
string basicConfig = "reactionConfig.txt";
|
||||
string heliosDetGeoFile = "detectorGeo.txt";
|
||||
string excitationFile = "Ex.txt"; //when no file, only ground state
|
||||
TString ptolemyRoot = "DWBA.root"; // when no file, use isotropic distribution of thetaCM
|
||||
TString saveFileName = "transfer.root";
|
||||
TString filename = "reaction.dat"; //when no file, no output
|
||||
bool isPlot = false;
|
||||
|
||||
if( argc >= 2) basicConfig = argv[1];
|
||||
if( argc >= 3) heliosDetGeoFile = argv[2];
|
||||
if( argc >= 4) excitationFile = argv[3];
|
||||
if( argc >= 5) ptolemyRoot = argv[4];
|
||||
if( argc >= 6) saveFileName = argv[5];
|
||||
if( argc >= 7) filename = argv[6];
|
||||
if( argc >= 8) isPlot = atoi(argv[7]);
|
||||
|
||||
Transfer( basicConfig, heliosDetGeoFile, excitationFile, ptolemyRoot, saveFileName, filename);
|
||||
|
||||
//run Armory/Check_Simulation
|
||||
if( isPlot ){
|
||||
ifstream file_in;
|
||||
file_in.open("../Armory/Check_Simulation.C", ios::in);
|
||||
if( file_in){
|
||||
printf("---- running ../Armory/Check_Simulation.C on %s \n", saveFileName.Data());
|
||||
TString cmd;
|
||||
cmd.Form("root -l '../Armory/Check_Simulation.C(\"%s\", 500)'", saveFileName.Data());
|
||||
|
||||
system(cmd.Data());
|
||||
}else{
|
||||
printf("cannot find ../Armory/Check_Simulation.C \n");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
722
Cleopatra/Transfer.h
Normal file
|
@ -0,0 +1,722 @@
|
|||
#include "TROOT.h"
|
||||
#include "TBenchmark.h"
|
||||
#include "TLorentzVector.h"
|
||||
#include "TMath.h"
|
||||
#include "TFile.h"
|
||||
#include "TF1.h"
|
||||
#include "TTree.h"
|
||||
#include "TRandom.h"
|
||||
#include "TGraph.h"
|
||||
#include "TMacro.h"
|
||||
#include <stdlib.h>
|
||||
#include <vector>
|
||||
#include <fstream>
|
||||
#include <TObjArray.h>
|
||||
|
||||
#include "HELIOS_LIB.h"
|
||||
|
||||
double exDistFunc(Double_t *x, Double_t * par){
|
||||
return par[(int) x[0]];
|
||||
}
|
||||
|
||||
void Transfer(
|
||||
string basicConfig = "reactionConfig.txt",
|
||||
string heliosDetGeoFile = "detectorGeo.txt",
|
||||
string excitationFile = "Ex.txt", ///when no file, only ground state
|
||||
TString ptolemyRoot = "DWBA.root", /// when no file, use isotropic distribution of thetaCM
|
||||
TString saveFileName = "transfer.root",
|
||||
TString filename = "reaction.dat"){ /// when no file, no output.
|
||||
|
||||
//############################################# Set Reaction
|
||||
TransferReaction reaction;
|
||||
reaction.SetReactionFromFile(basicConfig);
|
||||
|
||||
printf("*****************************************************************\n");
|
||||
printf("*\e[1m\e[33m %27s \e[0m*\n", reaction.GetReactionName().Data());
|
||||
printf("*****************************************************************\n");
|
||||
printf("----- loading reaction setting from %s. \n", basicConfig.c_str());
|
||||
printf("\e[32m#################################### Beam \e[0m\n");
|
||||
|
||||
const AnalysisLib::ReactionConfig reactionConfig = reaction.GetRectionConfig();
|
||||
|
||||
AnalysisLib::PrintReactionConfig(reactionConfig);
|
||||
|
||||
vector<float> ExAList = reactionConfig.beamEx;
|
||||
int nExA = (int) ExAList.size();
|
||||
|
||||
//############################################# Set HELIOS
|
||||
printf("\e[32m#################################### HELIOS configuration\e[0m\n");
|
||||
HELIOS helios;
|
||||
helios.SetDetectorGeometry(heliosDetGeoFile);
|
||||
|
||||
const AnalysisLib::DetGeo detGeo = helios.GetDetectorGeometry();
|
||||
|
||||
printf("==================================== E-Z plot slope\n");
|
||||
double betaRect = reaction.GetReactionBeta() ;
|
||||
double gamma = reaction.GetReactionGamma();
|
||||
double mb = reaction.GetMass_b();
|
||||
double pCM = reaction.GetMomentumbCM();
|
||||
double q = TMath::Sqrt(mb*mb + pCM*pCM); ///energy of light recoil in center of mass
|
||||
double slope = 299.792458 * reaction.GetCharge_b() * abs(helios.GetBField()) / TMath::TwoPi() * betaRect / 1000.; /// MeV/mm
|
||||
printf(" e-z slope : %f MeV/mm\n", slope);
|
||||
double intercept = q/gamma - mb; // MeV
|
||||
printf(" e-z intercept (ground state) : %f MeV\n", intercept);
|
||||
|
||||
//############################################# save reaction.dat
|
||||
if( filename != "" ) {
|
||||
FILE * keyParaOut;
|
||||
keyParaOut = fopen (filename.Data(), "w+");
|
||||
|
||||
printf("=========== save key reaction constants to %s \n", filename.Data());
|
||||
fprintf(keyParaOut, "%-15.4f //%s\n", reaction.GetMass_b(), "mass_b");
|
||||
fprintf(keyParaOut, "%-15d //%s\n", reaction.GetCharge_b(), "charge_b");
|
||||
fprintf(keyParaOut, "%-15.8f //%s\n", reaction.GetReactionBeta(), "betaCM");
|
||||
fprintf(keyParaOut, "%-15.4f //%s\n", reaction.GetCMTotalEnergy(), "Ecm");
|
||||
fprintf(keyParaOut, "%-15.4f //%s\n", reaction.GetMass_B(), "mass_B");
|
||||
fprintf(keyParaOut, "%-15.4f //%s\n", slope/betaRect, "alpha=slope/betaRect");
|
||||
|
||||
fflush(keyParaOut);
|
||||
fclose(keyParaOut);
|
||||
}
|
||||
|
||||
//############################################# Target scattering, only energy loss
|
||||
bool isTargetScattering = reactionConfig.isTargetScattering;
|
||||
float density = reactionConfig.targetDensity;
|
||||
float targetThickness = reactionConfig.targetThickness;
|
||||
|
||||
if(isTargetScattering) printf("\e[32m#################################### Target Scattering\e[0m\n");
|
||||
TargetScattering msA;
|
||||
TargetScattering msB;
|
||||
TargetScattering msb;
|
||||
|
||||
if(reactionConfig.isTargetScattering) printf("======== Target : (thickness : %6.2f um) x (density : %6.2f g/cm3) = %6.2f ug/cm2\n",
|
||||
targetThickness * 1e+4,
|
||||
density,
|
||||
targetThickness * density * 1e+6);
|
||||
|
||||
if( reactionConfig.isTargetScattering ){
|
||||
msA.LoadStoppingPower(reactionConfig.beamStoppingPowerFile);
|
||||
msb.LoadStoppingPower(reactionConfig.recoilLightStoppingPowerFile);
|
||||
msB.LoadStoppingPower(reactionConfig.recoilHeavyStoppingPowerFile);
|
||||
}
|
||||
|
||||
//############################################# Decay of particle-B
|
||||
Decay decay;
|
||||
if(reactionConfig.isDecay) {
|
||||
printf("\e[32m#################################### Decay\e[0m\n");
|
||||
decay.SetMotherDaugther(reactionConfig.recoilHeavyA,
|
||||
reactionConfig.recoilHeavyZ,
|
||||
reactionConfig.heavyDecayA,
|
||||
reactionConfig.heavyDecayZ);
|
||||
}
|
||||
//############################################# loading excitation energy
|
||||
printf("\e[32m#################################### excitation energies\e[0m\n");
|
||||
vector<double> ExKnown;
|
||||
vector<double> ExStrength;
|
||||
vector<double> ExWidth;
|
||||
vector<double> SF;
|
||||
vector<double> y0; /// intercept of e-z plot
|
||||
vector<double> kCM; /// momentum of b in CM frame
|
||||
printf("----- loading excitation energy levels (%s).", excitationFile.c_str());
|
||||
ifstream file;
|
||||
file.open(excitationFile.c_str());
|
||||
string isotopeName;
|
||||
if( file.is_open() ){
|
||||
string line;
|
||||
while( getline(file, line) ){
|
||||
///printf("%s \n", line.c_str());
|
||||
if( line.substr(0,2) == "//" ) continue;
|
||||
if( line.substr(0,2) == "#=" ) break;
|
||||
|
||||
vector<string> str = AnalysisLib::SplitStr(line, " ");
|
||||
|
||||
ExKnown.push_back(atof(str[0].c_str()));
|
||||
ExStrength.push_back(atof(str[1].c_str()));
|
||||
SF.push_back(atof(str[2].c_str()));
|
||||
ExWidth.push_back(atof(str[3].c_str()));
|
||||
|
||||
}
|
||||
file.close();
|
||||
printf("... done.\n");
|
||||
int n = (int) ExKnown.size();
|
||||
|
||||
printf("%3s | %7s | %5s | %3s | %10s | %5s \n", "", "Ex[MeV]", "Xsec", "SF", "sigma[MeV]", "y0[MeV]");
|
||||
printf("----+---------+------+-----+------------+--------\n");
|
||||
for(int i = 0; i < n ; i++){
|
||||
reaction.SetExB(ExKnown[i]);
|
||||
reaction.CalReactionConstant();
|
||||
kCM.push_back(reaction.GetMomentumbCM());
|
||||
y0.push_back(TMath::Sqrt(mb*mb + kCM[i]*kCM[i])/gamma - mb);
|
||||
if( reactionConfig.isDecay ) {
|
||||
TLorentzVector temp(0,0,0,0);
|
||||
int decayID = decay.CalDecay(temp, ExKnown[i], 0);
|
||||
if( decayID == 1) {
|
||||
printf("%3d | %7.2f | %5.2f | %3.1f | %5.3f | %5.2f --> Decay. \n", i, ExKnown[i], ExStrength[i], SF[i], ExWidth[i], y0[i]);
|
||||
}else{
|
||||
printf("%3d | %7.2f | %5.2f | %3.1f | %5.3f | %5.2f \n", i, ExKnown[i], ExStrength[i], SF[i], ExWidth[i], y0[i]);
|
||||
}
|
||||
}else{
|
||||
printf("%3d | %7.2f | %5.2f | %3.1f | %5.3f | %5.2f \n", i, ExKnown[i], ExStrength[i], SF[i], ExWidth[i], y0[i]);
|
||||
}
|
||||
}
|
||||
printf("----+---------+-------+-----+------------+--------\n");
|
||||
}else{
|
||||
printf("... fail ------> only ground state.\n");
|
||||
ExKnown.push_back(0.0);
|
||||
ExStrength.push_back(1.0);
|
||||
ExWidth.push_back(0.0);
|
||||
reaction.SetExB(ExKnown[0]);
|
||||
reaction.CalReactionConstant();
|
||||
kCM.push_back(reaction.GetMomentumbCM());
|
||||
y0.push_back(TMath::Sqrt(mb*mb + kCM[0]*kCM[0])/gamma - mb);
|
||||
}
|
||||
|
||||
//---- create Ex-distribution
|
||||
TF1 * exDist = NULL;
|
||||
if( ExKnown.size() > 1 ) {
|
||||
printf("---- creating Ex-distribution \n");
|
||||
int exSize = ExKnown.size();
|
||||
exDist = new TF1("exDist", exDistFunc, 0, exSize, exSize);
|
||||
for(int i = 0; i < exSize; i++){
|
||||
exDist->SetParameter(i, ExStrength[i]*SF[i]);
|
||||
}
|
||||
}
|
||||
|
||||
//############################################# Load DWBAroot for thetaCM distribution
|
||||
printf("\e[32m#################################### Load DWBA input : %s \e[0m\n", ptolemyRoot.Data());
|
||||
TF1 * dist = NULL;
|
||||
TFile * distFile = new TFile(ptolemyRoot, "read");
|
||||
TObjArray * distList = NULL;
|
||||
if( distFile->IsOpen() ) {
|
||||
distList = (TObjArray *) distFile->FindObjectAny("pList"); // the function List
|
||||
int distSize = distList->GetLast() + 1;
|
||||
if( distSize != ExKnown.size() ) {
|
||||
printf(" The number of distribution from Ptolmey Calculation is not equal to number of Ex input \n");
|
||||
printf(" --> the Ptolmey calculation is probably not matched with Ex input.\n");
|
||||
printf(" .... not use DWBA input. \n");
|
||||
distFile->Close();
|
||||
}
|
||||
}else{
|
||||
printf("------- no DWBA input. \n");
|
||||
}
|
||||
|
||||
//############################################# build tree
|
||||
printf("\e[32m#################################### building Tree in %s\e[0m\n", saveFileName.Data());
|
||||
TFile * saveFile = new TFile(saveFileName, "recreate");
|
||||
TTree * tree = new TTree("tree", "tree");
|
||||
|
||||
TMacro config(basicConfig.c_str());
|
||||
TMacro detGeoTxt(heliosDetGeoFile.c_str());
|
||||
TMacro exList(excitationFile.c_str());
|
||||
TMacro reactionData(filename.Data());
|
||||
double KEAmean = reactionConfig.beamEnergy;
|
||||
TString str;
|
||||
str.Form("%s @ %.2f MeV/u", reaction.GetReactionName_Latex().Data(), KEAmean);
|
||||
config.SetName(str.Data());
|
||||
config.Write("reactionConfig");
|
||||
detGeoTxt.Write("detGeo");
|
||||
exList.Write("ExList");
|
||||
reactionData.Write("reactionData");
|
||||
|
||||
if( distList != NULL ) distList->Write("DWBA", 1);
|
||||
|
||||
TMacro hitMeaning;
|
||||
str = "=======================meaning of Hit ID\n"; hitMeaning.AddLine(str.Data());
|
||||
str = " 1 = light recoil hit array & heavy recoil hit recoil\n"; hitMeaning.AddLine(str.Data());
|
||||
str = " 0 = no detector\n"; hitMeaning.AddLine(str.Data());
|
||||
str = " -1 = light recoil go opposite side of array\n"; hitMeaning.AddLine(str.Data());
|
||||
str = " -2 = light recoil hit > det width\n"; hitMeaning.AddLine(str.Data());
|
||||
str = " -3 = light recoil hit > array \n"; hitMeaning.AddLine(str.Data());
|
||||
str = " -4 = light recoil hit blocker \n"; hitMeaning.AddLine(str.Data());
|
||||
str = " -10 = light recoil orbit radius too big \n"; hitMeaning.AddLine(str.Data());
|
||||
str = " -11 = light recoil orbit radius too small\n"; hitMeaning.AddLine(str.Data());
|
||||
str = " -12 = when reocol at the same side of array, light recoil blocked by recoil detector\n"; hitMeaning.AddLine(str.Data());
|
||||
str = " -13 = more than 3 loops\n"; hitMeaning.AddLine(str.Data());
|
||||
str = " -14 = heavy recoil did not hit recoil \n"; hitMeaning.AddLine(str.Data());
|
||||
str = " -15 = cannot find hit on array\n"; hitMeaning.AddLine(str.Data());
|
||||
str = " -20 = unknown\n"; hitMeaning.AddLine(str.Data());
|
||||
str = "===========================================\n"; hitMeaning.AddLine(str.Data());
|
||||
|
||||
hitMeaning.Write("hitMeaning");
|
||||
|
||||
int hit; /// the output of Helios.CalHit
|
||||
tree->Branch("hit", &hit, "hit/I");
|
||||
|
||||
double thetab, phib, Tb;
|
||||
double thetaB, phiB, TB;
|
||||
tree->Branch("thetab", &thetab, "thetab/D");
|
||||
tree->Branch("phib", &phib, "phib/D");
|
||||
tree->Branch("Tb", &Tb, "Tb/D");
|
||||
tree->Branch("thetaB", &thetaB, "thetaB/D");
|
||||
tree->Branch("phiB", &phiB, "phiB/D");
|
||||
tree->Branch("TB", &TB, "TB/D");
|
||||
|
||||
double thetaCM;
|
||||
tree->Branch("thetaCM", &thetaCM, "thetaCM/D");
|
||||
|
||||
double e, z, detX, t, z0, tB;
|
||||
tree->Branch("e", &e, "energy_light/D");
|
||||
tree->Branch("x", &detX, "detector_x/D");
|
||||
tree->Branch("z", &z, "array_hit_z/D");
|
||||
tree->Branch("z0", &z0, "z-cycle/D");
|
||||
tree->Branch("t", &t, "cycle_time_light/D");
|
||||
tree->Branch("tB", &tB, "recoil_hit_time/D"); /// hit time for recoil on the recoil detector
|
||||
|
||||
int loop, detID, detRowID;
|
||||
tree->Branch("detID", &detID, "detID/I");
|
||||
tree->Branch("detRowID", &detRowID, "detRowID/I");
|
||||
tree->Branch("loop", &loop, "loop/I");
|
||||
|
||||
double rho, rhoB; ///orbit radius
|
||||
tree->Branch("rho", &rho, "orbit_radius_light/D");
|
||||
tree->Branch("rhoB", &rhoB, "orbit_radius_heavy/D");
|
||||
|
||||
int ExAID;
|
||||
double ExA;
|
||||
tree->Branch("ExAID", &ExAID, "ExAID/I");
|
||||
tree->Branch("ExA", &ExA, "ExA/D");
|
||||
|
||||
int ExID;
|
||||
double Ex;
|
||||
tree->Branch("ExID", &ExID, "ExID/I");
|
||||
tree->Branch("Ex", &Ex, "Ex/D");
|
||||
|
||||
double ExCal, thetaCMCal;
|
||||
tree->Branch("ExCal", &ExCal, "ExCal/D");
|
||||
tree->Branch("thetaCMCal", &thetaCMCal, "thetaCMCal/D");
|
||||
|
||||
double KEA, theta, phi;
|
||||
tree->Branch("beamTheta", &theta, "beamTheta/D");
|
||||
tree->Branch("beamPhi", &phi, "beamPhi/D");
|
||||
tree->Branch("beamKEA", &KEA, "beamKEA/D");
|
||||
|
||||
double TbLoss; /// energy loss of particle-b from target scattering
|
||||
double KEAnew; ///beam energy after target scattering
|
||||
double depth; /// reaction depth;
|
||||
double Ecm;
|
||||
if( reactionConfig.isTargetScattering ){
|
||||
tree->Branch("depth", &depth, "depth/D");
|
||||
tree->Branch("TbLoss", &TbLoss, "TbLoss/D");
|
||||
tree->Branch("KEAnew", &KEAnew, "KEAnew/D");
|
||||
tree->Branch("Ecm", &Ecm, "Ecm/D");
|
||||
}
|
||||
|
||||
double decayTheta; /// the change of thetaB due to decay
|
||||
double xRecoil_d, yRecoil_d, rhoRecoil_d, Td;
|
||||
if( reactionConfig.isDecay ) {
|
||||
tree->Branch("decayTheta", &decayTheta, "decayTheta/D");
|
||||
tree->Branch("xRecoil_d", &xRecoil_d, "xRecoil_d/D");
|
||||
tree->Branch("yRecoil_d", &yRecoil_d, "yRecoil_d/D");
|
||||
tree->Branch("rhoRecoil_d", &rhoRecoil_d, "rhoRecoil_d/D");
|
||||
tree->Branch("Td", &Td, "Td/D");
|
||||
}
|
||||
|
||||
double xArray, yArray, rhoArray; ///x, y, rho positon of particle-b on PSD
|
||||
tree->Branch("xArray", &xArray, "xArray/D");
|
||||
tree->Branch("yArray", &yArray, "yArray/D");
|
||||
tree->Branch("rhoArray", &rhoArray, "rhoArray/D");
|
||||
|
||||
double xRecoil, yRecoil, rhoRecoil; /// x, y, rho position of particle-B on recoil-detector
|
||||
tree->Branch("xRecoil", &xRecoil, "xRecoil/D");
|
||||
tree->Branch("yRecoil", &yRecoil, "yRecoil/D");
|
||||
tree->Branch("rhoRecoil", &rhoRecoil, "rhoRecoil/D");
|
||||
|
||||
///in case need ELUM
|
||||
double xElum1, yElum1, rhoElum1;
|
||||
if( detGeo.elumPos1 != 0 ) {
|
||||
tree->Branch("xElum1", &xElum1, "xElum1/D");
|
||||
tree->Branch("yElum1", &yElum1, "yElum1/D");
|
||||
tree->Branch("rhoElum1", &rhoElum1, "rhoElum1/D");
|
||||
}
|
||||
|
||||
double xElum2, yElum2, rhoElum2;
|
||||
if( detGeo.elumPos2 != 0 ) {
|
||||
tree->Branch("xElum2", &xElum2, "xElum2/D");
|
||||
tree->Branch("yElum2", &yElum2, "yElum2/D");
|
||||
tree->Branch("rhoElum2", &rhoElum2, "rhoElum2/D");
|
||||
}
|
||||
|
||||
///in case need other recoil detector.
|
||||
double xRecoil1, yRecoil1, rhoRecoil1;
|
||||
if( detGeo.recoilPos1 != 0 ){
|
||||
tree->Branch("xRecoil1", &xRecoil1, "xRecoil1/D");
|
||||
tree->Branch("yRecoil1", &yRecoil1, "yRecoil1/D");
|
||||
tree->Branch("rhoRecoil1", &rhoRecoil1, "rhoRecoil1/D");
|
||||
}
|
||||
double xRecoil2, yRecoil2, rhoRecoil2;
|
||||
if( detGeo.recoilPos2 != 0 ){
|
||||
tree->Branch("xRecoil2", &xRecoil2, "xRecoil2/D");
|
||||
tree->Branch("yRecoil2", &yRecoil2, "yRecoil2/D");
|
||||
tree->Branch("rhoRecoil2", &rhoRecoil2, "rhoRecoil2/D");
|
||||
}
|
||||
//======= function for e-z plot for ideal case
|
||||
printf("++++ generate functions\n");
|
||||
TObjArray * gList = new TObjArray();
|
||||
gList->SetName("Constant thetaCM lines");
|
||||
const int gxSize = 50;
|
||||
TF1 ** gx = new TF1*[gxSize];
|
||||
TString name;
|
||||
for( int i = 0; i < gxSize; i++){
|
||||
name.Form("g%d", i);
|
||||
gx[i] = new TF1(name, "([0]*TMath::Sqrt([1]+[2]*x*x)+[5]*x)/([3]) - [4]", -1000, 1000);
|
||||
double thetacm = i * TMath::DegToRad();
|
||||
double gS2 = TMath::Power(TMath::Sin(thetacm)*gamma,2);
|
||||
gx[i]->SetParameter(0, TMath::Cos(thetacm));
|
||||
gx[i]->SetParameter(1, mb*mb*(1-gS2));
|
||||
gx[i]->SetParameter(2, TMath::Power(slope/betaRect,2));
|
||||
gx[i]->SetParameter(3, 1-gS2);
|
||||
gx[i]->SetParameter(4, mb);
|
||||
gx[i]->SetParameter(5, -gS2*slope);
|
||||
gx[i]->SetNpx(1000);
|
||||
gList->Add(gx[i]);
|
||||
printf("/");
|
||||
if( i > 1 && i % 40 == 0 ) printf("\n");
|
||||
}
|
||||
gList->Write("gList", TObject::kSingleKey);
|
||||
printf(" %d constant thetaCM functions\n", gxSize);
|
||||
|
||||
int n = ExKnown.size();
|
||||
TObjArray * fList = new TObjArray();
|
||||
TF1** f = new TF1*[n];
|
||||
for( int i = 0; i< n ; i++){
|
||||
name.Form("f%d", i);
|
||||
f[i] = new TF1(name, "[0] + [1] * x", -1000, 1000);
|
||||
f[i]->SetParameter(0, y0[i]);
|
||||
f[i]->SetParameter(1, slope);
|
||||
f[i]->SetNpx(1000);
|
||||
fList->Add(f[i]);
|
||||
printf(".");
|
||||
}
|
||||
fList->Write("fList", TObject::kSingleKey);
|
||||
printf(" %d e-z infinte-small detector functions\n", n);
|
||||
|
||||
//--- cal modified f
|
||||
TObjArray * fxList = new TObjArray();
|
||||
TGraph ** fx = new TGraph*[n];
|
||||
vector<double> px, py;
|
||||
int countfx = 0;
|
||||
for( int j = 0 ; j < n; j++){
|
||||
double a = helios.GetDetRadius();
|
||||
double q = TMath::Sqrt(mb*mb + kCM[j] * kCM[j] );
|
||||
px.clear();
|
||||
py.clear();
|
||||
countfx = 0;
|
||||
for(int i = 0; i < 100; i++){
|
||||
double thetacm = TMath::Pi()/TMath::Log(100) * (TMath::Log(100) - TMath::Log(100-i)) ;//using log scale, for more point in small angle.
|
||||
double temp = TMath::TwoPi() * slope / betaRect / kCM[j] * a / TMath::Sin(thetacm);
|
||||
double pxTemp = betaRect /slope * (gamma * betaRect * q - gamma * kCM[j] * TMath::Cos(thetacm)) * (1 - TMath::ASin(temp)/TMath::TwoPi()) ;
|
||||
double pyTemp = gamma * q - mb - gamma * betaRect * kCM[j] * TMath::Cos(thetacm);
|
||||
if( TMath::IsNaN(pxTemp) || TMath::IsNaN(pyTemp) ) continue;
|
||||
px.push_back(pxTemp);
|
||||
py.push_back(pyTemp);
|
||||
countfx ++;
|
||||
}
|
||||
|
||||
fx[j] = new TGraph(countfx, &px[0], &py[0]);
|
||||
name.Form("fx%d", j);
|
||||
fx[j]->SetName(name);
|
||||
fx[j]->SetLineColor(4);
|
||||
fxList->Add(fx[j]);
|
||||
printf(",");
|
||||
}
|
||||
fxList->Write("fxList", TObject::kSingleKey);
|
||||
printf(" %d e-z finite-size detector functions\n", n);
|
||||
|
||||
//--- cal modified thetaCM vs z
|
||||
TObjArray * txList = new TObjArray();
|
||||
TGraph ** tx = new TGraph*[n];
|
||||
for( int j = 0 ; j < n; j++){
|
||||
double a = helios.GetDetRadius();
|
||||
double q = TMath::Sqrt(mb*mb + kCM[j] * kCM[j] );
|
||||
px.clear();
|
||||
py.clear();
|
||||
countfx = 0;
|
||||
for(int i = 0; i < 100; i++){
|
||||
double thetacm = (i + 8.) * TMath::DegToRad();
|
||||
double temp = TMath::TwoPi() * slope / betaRect / kCM[j] * a / TMath::Sin(thetacm);
|
||||
double pxTemp = betaRect /slope * (gamma * betaRect * q - gamma * kCM[j] * TMath::Cos(thetacm)) * (1 - TMath::ASin(temp)/TMath::TwoPi());
|
||||
double pyTemp = thetacm * TMath::RadToDeg();
|
||||
if( TMath::IsNaN(pxTemp) || TMath::IsNaN(pyTemp) ) continue;
|
||||
px.push_back(pxTemp);
|
||||
py.push_back(pyTemp);
|
||||
countfx ++;
|
||||
}
|
||||
|
||||
tx[j] = new TGraph(countfx, &px[0], &py[0]);
|
||||
name.Form("tx%d", j);
|
||||
tx[j]->SetName(name);
|
||||
tx[j]->SetLineColor(4);
|
||||
txList->Add(tx[j]);
|
||||
printf("*");
|
||||
}
|
||||
txList->Write("txList", TObject::kSingleKey);
|
||||
printf(" %d thetaCM-z for finite-size detector functions\n", n);
|
||||
|
||||
//========timer
|
||||
TBenchmark clock;
|
||||
bool shown ;
|
||||
clock.Reset();
|
||||
clock.Start("timer");
|
||||
shown = false;
|
||||
|
||||
//change the number of event into human easy-to-read form
|
||||
int numEvent = reactionConfig.numEvents;
|
||||
int digitLen = TMath::Floor(TMath::Log10(numEvent));
|
||||
TString numEventStr;
|
||||
if( 3 <= digitLen && digitLen < 6 ){
|
||||
numEventStr.Form("%5.1f kilo", numEvent/1000.);
|
||||
}else if ( 6<= digitLen && digitLen < 9 ){
|
||||
numEventStr.Form("%6.2f million", numEvent/1e6);
|
||||
}else if ( 9<= digitLen ){
|
||||
numEventStr.Form("%6.2f billion", numEvent/1e9);
|
||||
}
|
||||
printf("\e[32m#################################### generating %s events \e[0m\n", numEventStr.Data());
|
||||
|
||||
//====================================================== calculate event
|
||||
int count = 0;
|
||||
for( int i = 0; i < numEvent; i++){
|
||||
bool redoFlag = true;
|
||||
if( !reactionConfig.isRedo ) redoFlag = false;
|
||||
do{
|
||||
|
||||
//==== Set Ex of A
|
||||
ExAID = gRandom->Integer(nExA);
|
||||
ExA = ExAList[ExAID];
|
||||
reaction.SetExA(ExA);
|
||||
|
||||
//==== Set Ex of B
|
||||
if( ExKnown.size() == 1 ) {
|
||||
ExID = 0;
|
||||
Ex = ExKnown[0] + (ExWidth[0] == 0 ? 0 : gRandom->Gaus(0, ExWidth[0]));
|
||||
}else{
|
||||
ExID = exDist->GetRandom();
|
||||
Ex = ExKnown[ExID]+ (ExWidth[ExID] == 0 ? 0 : gRandom->Gaus(0, ExWidth[ExID]));
|
||||
}
|
||||
reaction.SetExB(Ex);
|
||||
|
||||
//==== Set incident beam
|
||||
KEA = reactionConfig.beamEnergy;
|
||||
if( reactionConfig.beamEnergySigma == 0 ){
|
||||
KEA = reactionConfig.beamEnergy;
|
||||
}else{
|
||||
KEA = gRandom->Gaus(reactionConfig.beamEnergy, reactionConfig.beamEnergySigma);
|
||||
}
|
||||
theta = 0.0;
|
||||
if( reactionConfig.beamAngleSigma == 0 ){
|
||||
theta = reactionConfig.beamAngle;
|
||||
}else{
|
||||
theta = gRandom->Gaus(reactionConfig.beamAngle, reactionConfig.beamAngleSigma);
|
||||
}
|
||||
phi = 0.0;
|
||||
|
||||
//==== for taregt scattering
|
||||
reaction.SetIncidentEnergyAngle(KEA, theta, 0.);
|
||||
reaction.CalReactionConstant();
|
||||
TLorentzVector PA = reaction.GetPA();
|
||||
|
||||
//depth = 0;
|
||||
if( isTargetScattering ){
|
||||
//==== Target scattering, only energy loss
|
||||
depth = targetThickness * gRandom->Rndm();
|
||||
msA.SetTarget(density, depth);
|
||||
TLorentzVector PAnew = msA.Scattering(PA);
|
||||
KEAnew = msA.GetKE()/reactionConfig.beamA;
|
||||
reaction.SetIncidentEnergyAngle(KEAnew, theta, phi);
|
||||
reaction.CalReactionConstant();
|
||||
Ecm = reaction.GetCMTotalKE();
|
||||
}
|
||||
|
||||
//==== Calculate thetaCM, phiCM
|
||||
if( distFile->IsOpen()){
|
||||
dist = (TF1 *) distList->At(ExID);
|
||||
thetaCM = dist->GetRandom() / 180. * TMath::Pi();
|
||||
}else{
|
||||
thetaCM = TMath::ACos(2 * gRandom->Rndm() - 1) ;
|
||||
}
|
||||
|
||||
double phiCM = TMath::TwoPi() * gRandom->Rndm();
|
||||
|
||||
//==== Calculate reaction
|
||||
TLorentzVector * output = reaction.Event(thetaCM, phiCM);
|
||||
TLorentzVector Pb = output[2];
|
||||
TLorentzVector PB = output[3];
|
||||
|
||||
//==== Calculate energy loss of scattered and recoil in target
|
||||
if( isTargetScattering ){
|
||||
if( Pb.Theta() < TMath::PiOver2() ){
|
||||
msb.SetTarget(density, targetThickness - depth);
|
||||
}else{
|
||||
msb.SetTarget(density, depth);
|
||||
}
|
||||
Pb = msb.Scattering(Pb);
|
||||
TbLoss = msb.GetKELoss();
|
||||
msB.SetTarget(density, targetThickness - depth);
|
||||
PB = msB.Scattering(PB);
|
||||
}else{
|
||||
TbLoss = 0;
|
||||
}
|
||||
|
||||
//======= Decay of particle-B
|
||||
int decayID = 0;
|
||||
int new_zB = reactionConfig.recoilHeavyZ;
|
||||
if( reactionConfig.isDecay){
|
||||
|
||||
//decayID = decay.CalDecay(PB, Ex, 0, phiCM + TMath::Pi()/2.); // decay to ground state
|
||||
decayID = decay.CalDecay(PB, Ex, 0, phiCM + TMath::Pi()/2); // decay to ground state
|
||||
if( decayID == 1 ){
|
||||
PB = decay.GetDaugther_D();
|
||||
//decayTheta = decay.GetAngleChange();
|
||||
decayTheta = decay.GetThetaCM();
|
||||
new_zB = reactionConfig.heavyDecayZ;
|
||||
}else{
|
||||
decayTheta = TMath::QuietNaN();
|
||||
}
|
||||
}
|
||||
|
||||
//################################### tree branches
|
||||
//===== reaction
|
||||
thetab = Pb.Theta() * TMath::RadToDeg();
|
||||
thetaB = PB.Theta() * TMath::RadToDeg();
|
||||
|
||||
Tb = Pb.E() - Pb.M();
|
||||
TB = PB.E() - PB.M();
|
||||
|
||||
phib = Pb.Phi() * TMath::RadToDeg();
|
||||
phiB = PB.Phi() * TMath::RadToDeg();
|
||||
|
||||
//==== Helios
|
||||
|
||||
///printf(" thetaCM : %f \n", thetaCM * TMath::RadToDeg());
|
||||
|
||||
if( Tb > 0 || TB > 0 ){
|
||||
helios.CalArrayHit(Pb, reaction.GetCharge_b());
|
||||
helios.CalRecoilHit(PB, new_zB);
|
||||
hit = 2;
|
||||
while( hit > 1 ){ hit = helios.DetAcceptance(); } /// while hit > 1, goto next loop;
|
||||
|
||||
trajectory orb_b = helios.GetTrajectory_b();
|
||||
trajectory orb_B = helios.GetTrajectory_B();
|
||||
|
||||
e = helios.GetEnergy() + gRandom->Gaus(0, detGeo.array1.eSigma);
|
||||
|
||||
double ranX = gRandom->Gaus(0, detGeo.array1.zSigma);
|
||||
z = orb_b.z + ranX;
|
||||
detX = helios.GetDetX() + ranX;
|
||||
|
||||
z0 = orb_b.z0;
|
||||
t = orb_b.t;
|
||||
loop = orb_b.loop;
|
||||
detID = orb_b.detID;
|
||||
detRowID = orb_b.detRowID;
|
||||
rho = orb_b.rho;
|
||||
rhoArray = orb_b.R;
|
||||
|
||||
xArray = orb_b.x;
|
||||
yArray = orb_b.y;
|
||||
|
||||
|
||||
//ELUM
|
||||
if( detGeo.elumPos1 != 0 ){
|
||||
xElum1 = helios.GetXPos(detGeo.elumPos1);
|
||||
yElum1 = helios.GetYPos(detGeo.elumPos1);
|
||||
rhoElum1 = helios.GetR(detGeo.elumPos1);
|
||||
}
|
||||
if( detGeo.elumPos2 != 0 ){
|
||||
xElum2 = helios.GetXPos(detGeo.elumPos2);
|
||||
yElum2 = helios.GetYPos(detGeo.elumPos2);
|
||||
rhoElum2 = helios.GetR(detGeo.elumPos2);
|
||||
}
|
||||
|
||||
//Recoil
|
||||
rhoRecoil = orb_B.R;
|
||||
tB = orb_B.t;
|
||||
xRecoil = orb_B.x;
|
||||
yRecoil = orb_B.y;
|
||||
rhoB = orb_B.rho;
|
||||
|
||||
//other recoil detectors
|
||||
if ( detGeo.recoilPos1 != 0 ){
|
||||
xRecoil1 = helios.GetRecoilXPos(detGeo.recoilPos1);
|
||||
yRecoil1 = helios.GetRecoilYPos(detGeo.recoilPos1);
|
||||
rhoRecoil1 = helios.GetRecoilR(detGeo.recoilPos1);
|
||||
}
|
||||
if ( detGeo.recoilPos2 != 0 ){
|
||||
xRecoil2 = helios.GetRecoilXPos(detGeo.recoilPos2);
|
||||
yRecoil2 = helios.GetRecoilYPos(detGeo.recoilPos2);
|
||||
rhoRecoil2 = helios.GetRecoilR(detGeo.recoilPos2);
|
||||
}
|
||||
|
||||
reaction.CalExThetaCM(e, z, helios.GetBField(), helios.GetDetRadius());
|
||||
ExCal = reaction.GetEx();
|
||||
thetaCMCal = reaction.GetThetaCM();
|
||||
|
||||
//change thetaCM into deg
|
||||
thetaCM = thetaCM * TMath::RadToDeg();
|
||||
|
||||
//if decay, get the light decay particle on the recoil;
|
||||
if( reactionConfig.isDecay ){
|
||||
if( decayID == 1 ){
|
||||
TLorentzVector Pd = decay.GetDaugther_d();
|
||||
|
||||
Td = Pd.E() - Pd.M();
|
||||
|
||||
helios.CalRecoilHit(Pd, reactionConfig.heavyDecayZ);
|
||||
|
||||
trajectory orb_d = helios.GetTrajectory_B();
|
||||
rhoRecoil_d = orb_d.R;
|
||||
xRecoil_d = orb_d.x;
|
||||
yRecoil_d = orb_d.y;
|
||||
|
||||
}else{
|
||||
rhoRecoil_d = TMath::QuietNaN();
|
||||
xRecoil_d = TMath::QuietNaN();
|
||||
yRecoil_d = TMath::QuietNaN();
|
||||
}
|
||||
}
|
||||
|
||||
}else{
|
||||
hit = -404;
|
||||
}
|
||||
|
||||
if( hit == 1) count ++;
|
||||
|
||||
if( reactionConfig.isRedo ){
|
||||
if( hit == 1) {
|
||||
redoFlag = false;
|
||||
}else{
|
||||
redoFlag = true;
|
||||
//printf("%d, %2d, thetaCM : %f, theta : %f, z0: %f \n", i, hit, thetaCM * TMath::RadToDeg(), thetab, helios.GetZ0());
|
||||
}
|
||||
}else{
|
||||
redoFlag = false;
|
||||
}
|
||||
|
||||
}while( redoFlag );
|
||||
tree->Fill();
|
||||
|
||||
//#################################################################### Timer
|
||||
clock.Stop("timer");
|
||||
Double_t time = clock.GetRealTime("timer");
|
||||
clock.Start("timer");
|
||||
|
||||
if ( !shown ) {
|
||||
if (fmod(time, 10) < 1 ){
|
||||
printf( "%10d[%2d%%]| %8.2f sec | expect: %5.1f min \n", i, TMath::Nint((i+1)*100./numEvent), time , numEvent*time/(i+1)/60);
|
||||
shown = 1;
|
||||
}
|
||||
}else{
|
||||
if (fmod(time, 10) > 9 ){
|
||||
shown = 0;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
saveFile->Write();
|
||||
saveFile->Close();
|
||||
|
||||
distFile->Close();
|
||||
|
||||
printf("=============== done. saved as %s. count(hit==1) : %d\n", saveFileName.Data(), count);
|
||||
//gROOT->ProcessLine(".q");
|
||||
}
|
172
Cleopatra/alpha.C
Normal file
|
@ -0,0 +1,172 @@
|
|||
#include "HELIOS_LIB.h"
|
||||
#include "TROOT.h"
|
||||
#include "TBenchmark.h"
|
||||
#include "TLorentzVector.h"
|
||||
#include "TMath.h"
|
||||
#include "TFile.h"
|
||||
#include "TF1.h"
|
||||
#include "TTree.h"
|
||||
#include "TRandom.h"
|
||||
#include <stdlib.h>
|
||||
#include <vector>
|
||||
#include <fstream>
|
||||
#include <TObjArray.h>
|
||||
|
||||
//----------- usage
|
||||
// $root transfer.C+ | tee output.txt
|
||||
// this will same the massage to output.txt
|
||||
|
||||
const double ma = 3727.3792; // alpha mass
|
||||
|
||||
void alpha(){
|
||||
|
||||
//================================================= User Setting
|
||||
const int numEnergy = 4;
|
||||
double energy [numEnergy] = {3.18, 5.16, 5.49, 5.81};
|
||||
|
||||
int numEvent = 1000000;
|
||||
|
||||
//---- HELIOS detector geometry
|
||||
//string heliosDetGeoFile = "detectorGeo.txt";
|
||||
string heliosDetGeoFile = "";
|
||||
double BField = 2.5; // T
|
||||
double BFieldTheta = 0.; // direction of B-field
|
||||
bool isCoincidentWithRecoil = false;
|
||||
double eSigma = 0.040 ; // detector energy sigma MeV
|
||||
double zSigma = 0.500 ; // detector position sigma mm
|
||||
|
||||
//---- save root file name
|
||||
TString saveFileName = "alpha.root";
|
||||
|
||||
//=============================================================
|
||||
//=============================================================
|
||||
|
||||
printf("===================================================\n");
|
||||
printf("============= Alpha source in HELIOS ============\n");
|
||||
printf("===================================================\n");
|
||||
|
||||
printf("========= Alpha Enegry : \n");
|
||||
for( int i = 0; i < numEnergy ; i++){
|
||||
printf("%2d | %6.2f MeV\n", i, energy[i]);
|
||||
}
|
||||
|
||||
|
||||
//======== Set HELIOS
|
||||
printf("############################################## HELIOS configuration\n");
|
||||
HELIOS helios;
|
||||
helios.OverrideMagneticFieldDirection(BFieldTheta);
|
||||
helios.OverrideFirstPos(-700);
|
||||
//helios.OverrideDetectorDistance(5);
|
||||
bool sethelios = helios.SetDetectorGeometry(heliosDetGeoFile);
|
||||
if( !sethelios){
|
||||
helios.OverrideMagneticField(BField);
|
||||
printf("======== B-field : %5.2f T, Theta : %6.2f deg\n", BField, BFieldTheta);
|
||||
}
|
||||
helios.SetCoincidentWithRecoil(isCoincidentWithRecoil);
|
||||
printf("========== energy resol.: %f MeV\n", eSigma);
|
||||
printf("=========== pos-Z resol.: %f mm \n", zSigma);
|
||||
|
||||
//====================== build tree
|
||||
TFile * saveFile = new TFile(saveFileName, "recreate");
|
||||
TTree * tree = new TTree("tree", "tree");
|
||||
|
||||
double theta, phi, T;
|
||||
|
||||
int hit; // the output of Helios.CalHit
|
||||
double e, z, x, t;
|
||||
int loop, detID;
|
||||
double dphi, rho; //rad of rotation, and radius
|
||||
int energyID;
|
||||
double xHit, yHit;
|
||||
|
||||
tree->Branch("hit", &hit, "hit/I");
|
||||
tree->Branch("theta", &theta, "theta/D");
|
||||
tree->Branch("phi", &phi, "phi/D");
|
||||
tree->Branch("T", &T, "T/D");
|
||||
tree->Branch("energy", &energy, "energy/D");
|
||||
tree->Branch("energyID", &energyID, "energyID/I");
|
||||
|
||||
tree->Branch("e", &e, "e/D");
|
||||
tree->Branch("x", &x, "x/D");
|
||||
tree->Branch("z", &z, "z/D");
|
||||
tree->Branch("t", &t, "t/D");
|
||||
tree->Branch("detID", &detID, "detID/I");
|
||||
tree->Branch("loop", &loop, "loop/I");
|
||||
tree->Branch("dphi", &dphi, "dphi/D");
|
||||
tree->Branch("rho", &rho, "rho/D");
|
||||
tree->Branch("xHit", &xHit, "xHit/D");
|
||||
tree->Branch("yHit", &yHit, "yHit/D");
|
||||
|
||||
//========timer
|
||||
TBenchmark clock;
|
||||
bool shown ;
|
||||
clock.Reset();
|
||||
clock.Start("timer");
|
||||
shown = false;
|
||||
printf("############################################## generating %d events \n", numEvent);
|
||||
|
||||
//====================================================== calculate
|
||||
int count = 0;
|
||||
TLorentzVector P;
|
||||
TVector3 v;
|
||||
for( int i = 0; i < numEvent; i++){
|
||||
//==== generate alpha
|
||||
theta = TMath::ACos(2 * gRandom->Rndm() - 1) ;
|
||||
phi = TMath::TwoPi() * gRandom->Rndm();
|
||||
|
||||
energyID = gRandom->Integer(numEnergy);
|
||||
T = energy[energyID];
|
||||
|
||||
double p = TMath::Sqrt( ( ma + T )*(ma + T) - ma* ma);
|
||||
|
||||
v.SetMagThetaPhi(p, theta, phi);
|
||||
|
||||
P.SetVectM(v, ma);
|
||||
|
||||
//################################### tree branches
|
||||
|
||||
//==== Helios
|
||||
hit = helios.CalHit(P, 2, P, 2);
|
||||
|
||||
e = helios.GetEnergy() + gRandom->Gaus(0, eSigma);
|
||||
z = helios.GetZ() ;
|
||||
x = helios.GetX() + gRandom->Gaus(0, zSigma);
|
||||
t = helios.GetTime();
|
||||
loop = helios.GetLoop();
|
||||
detID = helios.GetDetID();
|
||||
dphi = helios.GetdPhi();
|
||||
rho = helios.GetRho();
|
||||
xHit = helios.GetXPos(z);
|
||||
yHit = helios.GetYPos(z);
|
||||
z += gRandom->Gaus(0, zSigma);
|
||||
|
||||
|
||||
if( hit == 1) {
|
||||
count ++;
|
||||
}
|
||||
|
||||
tree->Fill();
|
||||
|
||||
//#################################################################### Timer
|
||||
clock.Stop("timer");
|
||||
Double_t time = clock.GetRealTime("timer");
|
||||
clock.Start("timer");
|
||||
|
||||
if ( !shown ) {
|
||||
if (fmod(time, 10) < 1 ){
|
||||
printf( "%10d[%2d%%]| %8.2f sec | expect: %5.1f min \n", i, TMath::Nint((i+1)*100./numEvent), time , numEvent*time/(i+1)/60);
|
||||
shown = 1;
|
||||
}
|
||||
}else{
|
||||
if (fmod(time, 10) > 9 ){
|
||||
shown = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
saveFile->Write();
|
||||
saveFile->Close();
|
||||
|
||||
printf("=============== done. saved as %s. count(hit==1) : %d\n", saveFileName.Data(), count);
|
||||
gROOT->ProcessLine(".q");
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
#include "ClassHelio.h"
|
||||
#include "HELIOS_LIB.h"
|
||||
#include "TROOT.h"
|
||||
#include "TBenchmark.h"
|
||||
#include "TLorentzVector.h"
|
||||
|
@ -98,7 +98,7 @@ void knockout(){
|
|||
bool sethelios1 = helios1.SetDetectorGeometry(heliosDetGeoFile);
|
||||
bool sethelios2 = helios2.SetDetectorGeometry(heliosDetGeoFile);
|
||||
if( sethelios1 && sethelios2 ) {
|
||||
int rowDet = helios1.GetNumberOfDetectorsInSamePos();
|
||||
int mDet = helios1.GetNumberOfDetectorsInSamePos();
|
||||
printf("========== energy resol.: %f MeV\n", eSigma);
|
||||
printf("=========== pos-Z resol.: %f mm \n", zSigma);
|
||||
}else{
|
|
@ -1,41 +1,38 @@
|
|||
CC = g++
|
||||
CFLAG = -O2
|
||||
CC=g++
|
||||
|
||||
depend = ClassTransfer.h ClassHelios.h ClassIsotope.h ClassDecay.h constant.h potentials.h
|
||||
|
||||
ALL = Isotope InFileCreator ExtractXSec ExtractXSecFromText PlotTGraphTObjArray Cleopatra FindThetaCM SimTransfer SimAlpha
|
||||
ALL = Isotope InFileCreator ExtractXSec ExtractXSecFromText PlotTGraphTObjArray FindThetaCM Transfer PlotSimulation IsotopeShort
|
||||
|
||||
all: $(ALL)
|
||||
|
||||
Isotope: ClassIsotope.h Isotope.C
|
||||
$(CC) $(CFLAG) Isotope.C -o Isotope
|
||||
#Cleopatra: Cleopatra.C ../Simulation/Isotope.h ../Simulation/constant.h potentials.h InFileCreator.h ExtractXSec.h PlotTGraphTObjArray.h
|
||||
# $(CC) Cleopatra.C -o Cleopatra `root-config --cflags --glibs`
|
||||
|
||||
InFileCreator: InFileCreator.C InFileCreator.h $(depend)
|
||||
$(CC) $(CFLAG) InFileCreator.C -o InFileCreator `root-config --cflags --glibs`
|
||||
InFileCreator: InFileCreator.C InFileCreator.h ../Cleopatra/Isotope.h ../Cleopatra/constant.h potentials.h
|
||||
$(CC) InFileCreator.C -o InFileCreator `root-config --cflags --glibs`
|
||||
|
||||
ExtractXSec: ExtractXSec.C ExtractXSec.h
|
||||
$(CC) $(CFLAG) ExtractXSec.C -o ExtractXSec `root-config --cflags --glibs`
|
||||
$(CC) ExtractXSec.C -o ExtractXSec `root-config --cflags --glibs`
|
||||
|
||||
ExtractXSecFromText: ExtractXSecFromText.C ExtractXSec.h
|
||||
$(CC) $(CFLAG) ExtractXSecFromText.C -o ExtractXSecFromText `root-config --cflags --glibs`
|
||||
$(CC) ExtractXSecFromText.C -o ExtractXSecFromText `root-config --cflags --glibs`
|
||||
|
||||
PlotTGraphTObjArray: PlotTGraphTObjArray.C PlotTGraphTObjArray.h
|
||||
$(CC) $(CFLAG) PlotTGraphTObjArray.C -o PlotTGraphTObjArray `root-config --cflags --glibs`
|
||||
$(CC) PlotTGraphTObjArray.C -o PlotTGraphTObjArray `root-config --cflags --glibs`
|
||||
|
||||
Cleopatra: Cleopatra.C InFileCreator.h ExtractXSec.h
|
||||
$(CC) $(CFLAG) Cleopatra.C -o Cleopatra `root-config --cflags --glibs`
|
||||
FindThetaCM: FindThetaCM.C FindThetaCM.h ../Cleopatra/HELIOS_LIB.h ../Cleopatra/Isotope.h ../Cleopatra/constant.h
|
||||
$(CC) FindThetaCM.C -o FindThetaCM `root-config --cflags --glibs`
|
||||
|
||||
FindThetaCM: FindThetaCM.C FindThetaCM.h $(depend)
|
||||
$(CC) $(CFLAG) FindThetaCM.C -o FindThetaCM `root-config --cflags --glibs`
|
||||
Transfer: Transfer.C Transfer.h ../Cleopatra/HELIOS_LIB.h ../Cleopatra/Isotope.h ../Cleopatra/constant.h
|
||||
$(CC) Transfer.C -o Transfer `root-config --cflags --glibs`
|
||||
|
||||
SimTransfer: SimTransfer.C ClassTransfer.h $(depend) ../Armory/ClassReactionConfig.h ../Armory/ClassDetGeo.h
|
||||
$(CC) $(CFLAG) SimTransfer.C -o SimTransfer `root-config --cflags --glibs`
|
||||
PlotSimulation: PlotSimulation.C Check_Simulation.C
|
||||
$(CC) PlotSimulation.C -o PlotSimulation `root-config --cflags --glibs`
|
||||
|
||||
SimTransfer_single: SimTransfer_single.C $(depend) ../Armory/ClassReactionConfig.h ../Armory/ClassDetGeo.h
|
||||
$(CC) $(CFLAG) SimTransfer_single.C -o SimTransfer_single `root-config --cflags --glibs`
|
||||
|
||||
SimAlpha: SimAlpha.C ClassHelios.h
|
||||
$(CC) $(CFLAG) SimAlpha.C -o SimAlpha `root-config --cflags --glibs`
|
||||
Isotope: ../Cleopatra/Isotope.h ../Cleopatra/Isotope.C
|
||||
$(CC) Isotope.C -o Isotope
|
||||
|
||||
IsotopeShort: ../Cleopatra/Isotope.h ../Cleopatra/IsotopeShort.C
|
||||
$(CC) IsotopeShort.C -o IsotopeShort
|
||||
|
||||
clean:
|
||||
/bin/rm -f $(ALL)
|
|
@ -45,7 +45,7 @@ def FindSym(Z):
|
|||
return 'na'
|
||||
def Mass(A, Z):
|
||||
try :
|
||||
BEA = float(haha['binding'][haha['z']==Z][haha['n']==(A-Z)].iloc[0])/1000
|
||||
BEA = float(haha['binding'][haha['z']==Z][haha['n']==(A-Z)])/1000
|
||||
return (A-Z)*mn + Z*mp - A * BEA
|
||||
except :
|
||||
return -404
|
||||
|
@ -87,7 +87,7 @@ def Info(AZ):
|
|||
try :
|
||||
Z = temp['z'][0]
|
||||
N = temp['n'][0]
|
||||
mass = float(Z*mp + N*mn - (Z+N)*temp['binding'].iloc[0]/1000)
|
||||
mass = Z*mp + N*mn - (Z+N)*temp['binding']/1000
|
||||
halfLife = temp['half_life_sec'][0]
|
||||
print(" A : %3d, Z : %3d, N : %3d, Mass : %.4f MeV" % (Z+N, Z, N, mass))
|
||||
print("Jpi : %3s, half-live : %s sec" % (temp['jp'][0], halfLife))
|
||||
|
|
|
@ -26,7 +26,7 @@ void PrintPotential(){
|
|||
|
||||
/// A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
|
||||
/// 1 1 1 1 0 0 1 1 0 0 1 1 1 0 0 1 1 0 0 0 0 1 0 1 1 1
|
||||
std::string potentialRef(std::string name){
|
||||
string potentialRef(string name){
|
||||
|
||||
//======== Deuteron
|
||||
if( name == "A" ){
|
||||
|
@ -1034,7 +1034,7 @@ bool BassaniPicardPotential(int A, int Z, double E){
|
|||
return true;
|
||||
}
|
||||
|
||||
bool CallPotential(std::string potName, int A, int Z, double E, int Zproj){
|
||||
bool CallPotential(string potName, int A, int Z, double E, int Zproj){
|
||||
bool okFlag = false;
|
||||
|
||||
if( potName == "A") okFlag = AnCaiPotential(A, Z, E);
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
#!/bin/bash
|
||||
docker run --rm --platform linux/amd64 -i -w $PWD tehatanlgov/ptolemy
|
||||
docker run --rm -i -w $PWD tehatanlgov/ptolemy
|
||||
|
|
77
Cleopatra/transfer_test.C
Normal file
|
@ -0,0 +1,77 @@
|
|||
#include "HELIOS_LIB.h"
|
||||
#include "TROOT.h"
|
||||
#include "TBenchmark.h"
|
||||
#include "TLorentzVector.h"
|
||||
#include "TMath.h"
|
||||
#include "TFile.h"
|
||||
#include "TF1.h"
|
||||
#include "TTree.h"
|
||||
#include "TRandom.h"
|
||||
#include "TGraph.h"
|
||||
#include "TMacro.h"
|
||||
#include <stdlib.h>
|
||||
#include <vector>
|
||||
#include <fstream>
|
||||
#include <TObjArray.h>
|
||||
|
||||
void transfer_test(double t, double p, double bField, bool fromOutSide){
|
||||
|
||||
TransferReaction reaction;
|
||||
reaction.SetA(14, 6);
|
||||
reaction.Seta( 2, 1);
|
||||
reaction.Setb( 1, 1);
|
||||
reaction.SetB(15, 6);
|
||||
|
||||
reaction.SetExB(0);
|
||||
|
||||
reaction.SetIncidentEnergyAngle(10, 0, 0);
|
||||
reaction.CalReactionConstant();
|
||||
|
||||
HELIOS helios;
|
||||
helios.SetDetectorGeometry("../working/detectorGeo.txt");
|
||||
helios.OverrideMagneticField(bField);
|
||||
helios.SetDetectorOutside(fromOutSide);
|
||||
|
||||
double beta = reaction.GetReactionBeta() ;
|
||||
|
||||
double slope = 299.792458 * abs(helios.GetBField()) / TMath::TwoPi() * beta / 1000.; // MeV/mm
|
||||
|
||||
double alpha = slope / beta;
|
||||
|
||||
printf("===================================\n");
|
||||
printf("Mass A : %8.2f MeV/c2\n", reaction.GetMass_A());
|
||||
printf("Mass a : %8.2f MeV/c2\n", reaction.GetMass_a());
|
||||
printf("Mass b : %8.2f MeV/c2\n", reaction.GetMass_b());
|
||||
printf("Mass B : %8.2f MeV/c2\n", reaction.GetMass_B());
|
||||
printf("CM Mass : %8.2f MeV\n", reaction.GetCMTotalEnergy());
|
||||
printf("CM beta : %8.6f \n", beta);
|
||||
printf("slope : %8.6f MeV\n", alpha * beta);
|
||||
printf("alpha : %8.6f MeV\n", alpha);
|
||||
|
||||
|
||||
double thetaCM = t * TMath::DegToRad();
|
||||
double phiCM = - p * TMath::DegToRad();
|
||||
|
||||
TLorentzVector * output = reaction.Event(thetaCM, phiCM);
|
||||
TLorentzVector Pb = output[2];
|
||||
TLorentzVector PB = output[3];
|
||||
|
||||
Pb.Print();
|
||||
PB.Print();
|
||||
|
||||
helios.CalArrayHit(Pb, 1);
|
||||
helios.CalRecoilHit(PB, 6);
|
||||
|
||||
printf("+++++++++++++++++++++++++++++++++++++\n");
|
||||
|
||||
int hitID = 2;
|
||||
while( hitID > 1 ){
|
||||
printf("==================== check accp.\n");
|
||||
hitID = helios.DetAcceptance();
|
||||
printf("-------------------- hitID %d\n", hitID);
|
||||
}
|
||||
|
||||
PrintTrajectory(helios.GetTrajectory_b());
|
||||
|
||||
|
||||
}
|
86
README.md
|
@ -4,78 +4,34 @@ This is the analysis package for the SOLARIS DAQ. It is supposed to be the analy
|
|||
|
||||
The folder struture is
|
||||
|
||||
Analysis
|
||||
├── README.md
|
||||
├── SetupNewExp // bash script to create new branch and raw data folder
|
||||
├── SOLARIS.sh // bash script to define some env variable and functions
|
||||
├── Armory // analysis codes, independent from experiment.
|
||||
├── Cleopatra // Swaper for DWBA code Ptolomey and simulation
|
||||
├── data_raw // should be the symbolic link to the raw data, created by SetUpNewExp
|
||||
├── root_data // symbolic link to converted root file, created by SetUpNewExp
|
||||
Analysis
|
||||
|
||||
├── README.md
|
||||
|
||||
├── SetupNewExp // bash script to create new branch and raw data folder
|
||||
|
||||
├── SOLARIS.sh // bash script to define some env variable and functions
|
||||
|
||||
├── armory // analysis codes, independent from experiment.
|
||||
|
||||
├── Cleopatra // Swaper for DWBA code Ptolomey
|
||||
|
||||
├── data_raw // should be the symbolic link to the raw data, created by SetUpNewExp
|
||||
|
||||
├── root_data // symbolic link to converted root file, created by SetUpNewExp
|
||||
|
||||
└── working // working directory, depends on experiment.
|
||||
|
||||
# SOLARIS.sh
|
||||
|
||||
this batch shell script adds few enviroment variables and functions. Add the Armory and Cleopatra into the system PATH.
|
||||
|
||||
```sh
|
||||
>source SOLARIS.sh
|
||||
```
|
||||
|
||||
# Event Builder
|
||||
|
||||
Please download the SOLARIS_DAQ, under the Aux directory, make, and link the EventBuilder to Armory.
|
||||
The EventBuilder is at the armory. It depends on the Hit.h and SolReader.h.
|
||||
|
||||
The reason for having EventBuilder in the DAQ code is the Hit.h is original from the DAQ code.
|
||||
## Hit.h
|
||||
|
||||
# ROOT issue
|
||||
The Hit class stores a hit (or a data block)
|
||||
|
||||
We are still using TProof for parallel calculation. TProof is not pre-compiled since 6.32+. And 6.30 only precompiled for Ubuntu 22.04. So, for system using Ubuntu 24.04, user must precompiled to root in order to work.
|
||||
## SolReader.h
|
||||
|
||||
## Compilation
|
||||
|
||||
We can manual download the git repository of the root following the instruction. in the cmake
|
||||
|
||||
```sh
|
||||
root_install="/opt/root_v6.32.00_compiled"
|
||||
root_src="root_src"
|
||||
root_build="root_build"
|
||||
cmake -DCMAKE_INSTALL_PREFIX=$root_install $root_src -Dproof=ON -Dmathmore=ON
|
||||
sudo cmake --build . --target install -j <number_of_threads>
|
||||
```
|
||||
|
||||
# Analysis & Simulation
|
||||
|
||||
The Armory/AnalysisLib.h constains many small but handy functions.
|
||||
|
||||
All class headers are started with Class*.h
|
||||
|
||||
The classes **DetGeo**** and **ReactionConfig** are fundamental for loading the detectorGeo.txt and reactionConfig.txt.
|
||||
|
||||
Both txt file support empty lines, can have multiple settings. The reason for that is for many-array configuration.
|
||||
|
||||
The **TransferReaction** class is only use one of the reaction from the reactionConfig.txt. This class generates the TLorentzVector for ligh and heavy recoils.
|
||||
|
||||
```C++
|
||||
TransferReaction::SetReactionFromFile("reactionConfig.txt", ID); // ID = 0 or 1
|
||||
```
|
||||
Same for the **Helios** class, **Helios** class use the detectorGeo.txt. It takes TLorentzVector and calculate does it be detected by the array or recoil detector.
|
||||
|
||||
```C++
|
||||
HELIOS::SetDetectorGeometry("detectorGeo.txt", ID); // ID = 0 or 1
|
||||
```
|
||||
|
||||
## Simulation
|
||||
|
||||
Simply run
|
||||
```sh
|
||||
>SimTransfer
|
||||
```
|
||||
|
||||
it will digest the detectorGeo.txt, reactionConfig.txt, if DWBA.root exist, find the reactions.
|
||||
|
||||
* it does not have TargetScattering (yet)
|
||||
* for multiple reactions, it will randomly use any and disregard the total Xsec of different reactions. The Xsec only takes effect within same reaction.
|
||||
* the decay of heavy recoil only have isotropic decay.
|
||||
The SolReader class read the sol file. It can be loaded in CERN ROOT alone.
|
||||
|
||||
|
||||
|
|
16
SOLARIS.sh
|
@ -16,28 +16,24 @@ export SOLARISANADIR
|
|||
|
||||
echo "####### set global variable SOLARISANADIR = ${SOLARISANADIR}"
|
||||
|
||||
export PATH=$PATH:$SOLARISANADIR/Armory:$SOLARISANADIR/Cleopatra
|
||||
export PATH=$PATH:$SOLARISANADIR/armory
|
||||
|
||||
echo "####### add ${SOLARISANADIR}/Armory into PATH"
|
||||
echo "####### add ${SOLARISANADIR}/Cleopatra into PATH"
|
||||
echo "####### add ${SOLARISANADIR}/armory into PATH"
|
||||
|
||||
|
||||
###########################
|
||||
|
||||
echo "####### Define BASH Alias and Functions for SOLARIS"
|
||||
echo " 2Working = goto the working directory"
|
||||
echo " ShowRunTimeStamp = show Run Timestamp"
|
||||
echo " ShowRunSize = show Run Size"
|
||||
echo "####### Define BASH Alias / Functions for SOLARIS"
|
||||
|
||||
alias 2Working='cd ${SOLARISANADIR}/working'
|
||||
alias ShowRunTimeStamp='cat $SOLARISANADIR/data_raw/RunTimeStamp.dat'
|
||||
alias ShowRunTimeStamp='cat $SOLARISANADIR/data_raw/data/RunTimeStamp.dat'
|
||||
|
||||
function ShowRunSize {
|
||||
if [ $# -ne 1 ]; then
|
||||
echo 'Please set run number '
|
||||
return 0
|
||||
fi
|
||||
source $SOLARISANADIR/data_raw/expName.sh
|
||||
source $SOLARISANADIR/working/expName.sh
|
||||
RUN=$1
|
||||
if [ ${RUN} = "latest" ]; then
|
||||
RUN=${runID}
|
||||
|
@ -48,5 +44,5 @@ function ShowRunSize {
|
|||
elif [ ${runLen} -eq 2 ]; then
|
||||
RUN="0"${RUN}
|
||||
fi
|
||||
du -hc $SOLARISANADIR/data_raw/${expName}_${RUN}_*.sol
|
||||
du -hc $SOLARISANADIR/data_raw/data/${expName}_${RUN}_*.sol
|
||||
}
|
||||
|
|
|
@ -1,239 +0,0 @@
|
|||
let energy = [];
|
||||
let jpi = [];
|
||||
let Name;
|
||||
let A;
|
||||
let Sym;
|
||||
|
||||
function breakdownName(str) {
|
||||
const match = str.match(/^(\d+)([a-zA-Z]+)$/);
|
||||
if (match) {
|
||||
const numberPart = parseInt(match[1]);
|
||||
const stringPart = match[2];
|
||||
return { numberPart, stringPart };
|
||||
} else {
|
||||
return null; // If the input string doesn't match the expected format
|
||||
}
|
||||
}
|
||||
|
||||
let Sn = 999;
|
||||
let Sp = 999;
|
||||
let Sa = 999;
|
||||
|
||||
function GetData(){
|
||||
|
||||
Name = document.getElementById('ASym').value;
|
||||
let maxEx = parseFloat(document.getElementById('maxEx').value);
|
||||
|
||||
let str = 'displayIsoData.py?ASym=' + Name + "&maxEx=" + maxEx;
|
||||
|
||||
let client = new XMLHttpRequest();
|
||||
client.onreadystatechange = function() {
|
||||
let haha = client.responseText.split('\n');
|
||||
|
||||
jpi = [];
|
||||
energy = [];
|
||||
haha.forEach(line =>{
|
||||
|
||||
// console.log(line)
|
||||
if( line.includes("Sn:") ) {
|
||||
let pos1 = line.indexOf("Sn:");
|
||||
let pos2 = line.indexOf("MeV");
|
||||
Sn = parseFloat(line.substring(pos1+3, pos2));
|
||||
}
|
||||
if( line.includes("Sp:") ) {
|
||||
let pos1 = line.indexOf("Sp:");
|
||||
let pos2 = line.indexOf("MeV");
|
||||
Sp = parseFloat(line.substring(pos1+3, pos2));
|
||||
}
|
||||
if( line.includes("Sa:") ) {
|
||||
let pos1 = line.indexOf("Sa:");
|
||||
let pos2 = line.indexOf("MeV");
|
||||
Sa = parseFloat(line.substring(pos1+3, pos2));
|
||||
}
|
||||
|
||||
if( line.includes("<tr><td style=") && line.length != 0) {
|
||||
jpi.push(line.substring(95).slice(0,-10).trim());
|
||||
energy.push(parseFloat(line.substring(43,54).trim()));
|
||||
// console.log(jpi[jpi.length - 1] + ", " + energy[energy.length-1]);
|
||||
}
|
||||
});
|
||||
}
|
||||
client.open('GET', str, false);
|
||||
client.send();
|
||||
|
||||
}
|
||||
|
||||
function PlotLevels(){
|
||||
|
||||
GetData();
|
||||
|
||||
Plotly.purge("Plot_Levels");
|
||||
|
||||
if( energy.length == 0 ) return;
|
||||
|
||||
// console.log( Name + " | num. states : " + energy.length);
|
||||
|
||||
const plotWidth = 300;
|
||||
const plotHeight = 600;
|
||||
const yMin = -1;
|
||||
|
||||
let maxEx = parseFloat(document.getElementById('maxEx').value);
|
||||
const maxExExp = Math.max(...energy);
|
||||
|
||||
// console.log(maxExExp);
|
||||
|
||||
// let maxY = parseFloat(document.getElementById('plotRange').value);
|
||||
|
||||
const fig = {
|
||||
data: [],
|
||||
layout: {
|
||||
plot_bgcolor: 'white',
|
||||
width: plotWidth,
|
||||
height: plotHeight,
|
||||
margin: { l: 0, r: 0, t: 0, b: 0 },
|
||||
showlegend: false,
|
||||
xaxis: {
|
||||
showline: false,
|
||||
visible: false,
|
||||
range: [-1, 2.5]
|
||||
},
|
||||
yaxis: {
|
||||
range: [yMin, maxEx + 2],
|
||||
showline: false,
|
||||
visible: false
|
||||
},
|
||||
annotations: []
|
||||
}
|
||||
};
|
||||
|
||||
const l = energy.length;
|
||||
|
||||
const fontSize = 14;
|
||||
const fontSizeMeV = fontSize / plotHeight * (maxExExp + 1 - yMin);
|
||||
|
||||
let ypos = [];
|
||||
for( let i = 0; i < energy.length; i++) ypos.push(energy[i]);
|
||||
|
||||
let noOverlap = false;
|
||||
let loop = 0;
|
||||
|
||||
while (!noOverlap && loop < 2 * l) {
|
||||
for (let i = 1; i <= l; i++) {
|
||||
const diff = ypos[i] - ypos[i - 1];
|
||||
if (diff < fontSizeMeV) {
|
||||
ypos[i - 1] += (diff - fontSizeMeV) / 2;
|
||||
ypos[i] += (fontSizeMeV - diff) / 2;
|
||||
if (ypos[i - 1] < yMin + fontSizeMeV / 2) {
|
||||
ypos[i - 1] = yMin + fontSizeMeV / 2;
|
||||
ypos[i] = ypos[i - 1] + fontSizeMeV;
|
||||
}
|
||||
}
|
||||
}
|
||||
let count = 0;
|
||||
for (let i = 1; i <= l; i++) {
|
||||
const diff = ypos[i] - ypos[i - 1];
|
||||
if (diff > fontSizeMeV) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
if (count === l) {
|
||||
noOverlap = true;
|
||||
}
|
||||
loop++;
|
||||
}
|
||||
|
||||
for (let i = 0; i < l; i++) {
|
||||
fig.data.push({
|
||||
x: [0, 1],
|
||||
y: [energy[i], energy[i]],
|
||||
mode: 'lines',
|
||||
line: { color: 'black', width: 1 }
|
||||
});
|
||||
|
||||
fig.data.push({
|
||||
x: [1.03, 1.1, 1.19],
|
||||
y: [energy[i], ypos[i], ypos[i]],
|
||||
mode: 'lines',
|
||||
line: { color: 'gray', width: 1 }
|
||||
});
|
||||
|
||||
// console.log(energy[i]+ ", " + ypos[i]);
|
||||
|
||||
fig.layout.annotations.push({
|
||||
x: 1.2,
|
||||
y: ypos[i],
|
||||
text: `${energy[i].toFixed(3)}, ${jpi[i]}`,
|
||||
xanchor: 'left',
|
||||
font: { size: fontSize },
|
||||
showarrow: false
|
||||
});
|
||||
}
|
||||
|
||||
console.log("Sn: " + Sn);
|
||||
console.log("Sp: " + Sp);
|
||||
console.log("Sa: " + Sa);
|
||||
|
||||
let leftPos = -0.8;
|
||||
|
||||
fig.data.push({
|
||||
x: [leftPos, 1],
|
||||
y: [Sn, Sn],
|
||||
mode: 'lines',
|
||||
line: { color: 'blue', width: 1 }
|
||||
});
|
||||
fig.layout.annotations.push({
|
||||
x: leftPos,
|
||||
y: Sn + fontSizeMeV/2,
|
||||
text: `${'Sn:'+Sn.toFixed(3)}`,
|
||||
xanchor: 'left',
|
||||
font: { size: fontSize, color: 'blue' },
|
||||
showarrow: false
|
||||
});
|
||||
|
||||
fig.data.push({
|
||||
x: [leftPos, 1],
|
||||
y: [Sp, Sp],
|
||||
mode: 'lines',
|
||||
line: { color: 'red', width: 1 }
|
||||
});
|
||||
fig.layout.annotations.push({
|
||||
x: leftPos,
|
||||
y: Sp + fontSizeMeV/2,
|
||||
text: `${'Sp:'+Sp.toFixed(3)}`,
|
||||
xanchor: 'left',
|
||||
font: { size: fontSize, color: 'red' },
|
||||
showarrow: false
|
||||
});
|
||||
|
||||
fig.data.push({
|
||||
x: [leftPos, 1],
|
||||
y: [Sa, Sa],
|
||||
mode: 'lines',
|
||||
line: { color: 'purple', width: 1 }
|
||||
});
|
||||
fig.layout.annotations.push({
|
||||
x: leftPos,
|
||||
y: Sa + fontSizeMeV/2,
|
||||
text: `${'Sa:'+Sa.toFixed(3)}`,
|
||||
xanchor: 'left',
|
||||
font: { size: fontSize, color: 'purple' },
|
||||
showarrow: false
|
||||
});
|
||||
|
||||
// let NameYPos = (parseFloat(maxEx) + 2*fontSizeMeV);
|
||||
// console.log(NameYPos);
|
||||
|
||||
let name2 = breakdownName(Name);
|
||||
|
||||
fig.layout.annotations.push({
|
||||
x: 0.5,
|
||||
y: (maxEx + 1),
|
||||
text: "<sup>" + name2.numberPart +"</sup>" + name2.stringPart,
|
||||
font: { size: 2 * fontSize },
|
||||
showarrow: false
|
||||
});
|
||||
|
||||
// Create the plot
|
||||
Plotly.newPlot('Plot_Levels', fig.data, fig.layout);
|
||||
|
||||
}
|
|
@ -1,55 +0,0 @@
|
|||
# Introduction
|
||||
|
||||
This is a web inteface for the HELIOS/SOLARIS simulation. Its purpose is NOT to replace the Simulation_Helper.C in the origin digios repository.
|
||||
It is simply provide a more easy accessible way to do simulation.
|
||||
|
||||
# Installation in Apache2
|
||||
|
||||
Assume the parant SOLARIS_ANALYSIS is in the home folder
|
||||
add a symbolic link
|
||||
|
||||
```sh
|
||||
$cd /var/www/html
|
||||
$ln -s ~/SOLARIS_ANALYSIS SOLARIS
|
||||
```
|
||||
|
||||
I want localhost/SOLARIS map to /var/www/html/SOLARIS/WebSimHelper, in the apache config
|
||||
|
||||
```sh
|
||||
$cd /etc/apache2/sit-available
|
||||
$touch SOLARIS.conf
|
||||
```
|
||||
|
||||
inside SOLARIS.conf
|
||||
|
||||
```sh
|
||||
<VirtualHost *:80>
|
||||
ServerAdmin rtang@anl.gov
|
||||
DocumentRoot /var/www/html/
|
||||
ServerName localhost
|
||||
|
||||
#map localhost/SOLARIS to /var/www/html/SOLARIS/WebSimHelper
|
||||
Alias /SOLARIS /var/www/html/SOLARIS/WebSimHelper
|
||||
|
||||
#set the directory properties
|
||||
<Directory /var/www/html/>
|
||||
Options Indexes FollowSymLinks
|
||||
AllowOverride None
|
||||
Require all granted
|
||||
Options +ExecCGI
|
||||
AddHandler cgi-script .cgi .py
|
||||
</Directory>
|
||||
|
||||
ErrorLog ${APACHE_LOG_DIR}/error.log
|
||||
CustomLog ${APACHE_LOG_DIR}/access.log combined
|
||||
|
||||
</VirtualHost>
|
||||
```
|
||||
|
||||
then enable the site
|
||||
|
||||
```sh
|
||||
$sudo a2ensite SOLARIS.conf
|
||||
$sudo systemctl restart apach2.service
|
||||
```
|
||||
|
|
@ -1,29 +0,0 @@
|
|||
#!/usr/bin/env /usr/bin/python3
|
||||
|
||||
import isotopeLib
|
||||
import cgi
|
||||
|
||||
form = cgi.FieldStorage()
|
||||
|
||||
ASym = form.getvalue('ASym')
|
||||
maxEx = form.getvalue('maxEx')
|
||||
|
||||
print( "Content-type:text/html\r\n\r\n")
|
||||
print("<html>")
|
||||
print("<style> body { font-family: courier, courier new, serif; color: #F7CF3C; } </style>")
|
||||
print("<body>")
|
||||
|
||||
isotopeLib.PrintIsoWeb(ASym)
|
||||
|
||||
if maxEx == "can be omitted" or float(maxEx) <= 0:
|
||||
maxEx = -1
|
||||
else:
|
||||
isotopeLib.PrintIsoExWeb(ASym, float(maxEx))
|
||||
|
||||
|
||||
print("</body>")
|
||||
print("</html>")
|
||||
|
||||
|
||||
|
||||
|
|
@ -1,18 +0,0 @@
|
|||
#!/usr/bin/env /usr/bin/python3
|
||||
|
||||
import isotopeLib as iso
|
||||
|
||||
import sys
|
||||
|
||||
if len(sys.argv) < 3:
|
||||
print("Usage: python getEx.py A Z Ex")
|
||||
sys.exit(1)
|
||||
|
||||
A = int(sys.argv[1])
|
||||
Z = int(sys.argv[2])
|
||||
Ex = float(sys.argv[3])
|
||||
ASym = iso.GetSymbol(A, Z)
|
||||
|
||||
ExList = iso.GetExList(ASym, Ex)
|
||||
|
||||
print(ExList)
|
|
@ -1,463 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Heliosmatics</title>
|
||||
<meta name="description" content="HELIOSmatics was first built by Ben P. Kay in MS Excel around 2010. Later, it was modified by Ryan Tang. Now, it migrates to web.">
|
||||
<link rel="icon" type="image/x-icon" href="logos/SOLARIS_favicon.png">
|
||||
<script src="https://cdn.plot.ly/plotly-2.16.1.min.js"></script>
|
||||
<meta name="viewport" content="width=device-width, height=device-height, initial-scale=1.0, user-scalable=no, user-scalable=0"/>
|
||||
</head>
|
||||
<style>
|
||||
body{
|
||||
font-family: Arial, Helvetica, sans-serif;
|
||||
background : #6DB33E;
|
||||
}
|
||||
.column{
|
||||
float : left;
|
||||
width: 650px;
|
||||
padding: 0px;
|
||||
}
|
||||
.row:after {
|
||||
content: "";
|
||||
display: table;
|
||||
clear: both;
|
||||
}
|
||||
.plotStyle{
|
||||
width:650px;
|
||||
height:600px;
|
||||
}
|
||||
.slider{
|
||||
width : 400px;
|
||||
}
|
||||
.plotSlider{
|
||||
width: 400px;
|
||||
}
|
||||
|
||||
hr {
|
||||
height:4px;
|
||||
background-color:#F7CF3C;
|
||||
border-style:none;
|
||||
border-width:none;
|
||||
}
|
||||
@media screen and (max-width: 1000px) {
|
||||
.column {
|
||||
width: 100%;
|
||||
}
|
||||
.plotStyle{
|
||||
width:400px;
|
||||
height: 370px;
|
||||
}
|
||||
.slider{
|
||||
width: 200px;
|
||||
}
|
||||
.plotSlider{
|
||||
width: 180px;
|
||||
}
|
||||
img {
|
||||
height: 50px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
<body>
|
||||
|
||||
<h1>HELIOSmatics</h1>
|
||||
|
||||
<button onclick="CopyInputs()">Copy settings to clipboard</button>
|
||||
|
||||
<h1 id='reactionName' style="color: #1363A7"> 24F(d,p)25F@10MeV/u</h1>
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<td style="text-align:right"> Beam (A):</td>
|
||||
<td><Input type="text" style="width:60px" value="24F" id="beam" enterkeyhint="done"/></td>
|
||||
<td style="text-align:right"> Beam Ex:</td>
|
||||
<td><Input type="text" style="width:60px" value="0" id="beamEx" enterkeyhint="done"/></td>
|
||||
<td>MeV</td>
|
||||
<td id='beamSp'></td>
|
||||
<!--td id="beamYield"></td>-->
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="text-align:right"> Target (a):</td>
|
||||
<td><Input type="text" style="width:60px" value="d" id="target" enterkeyhint="done"/></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="text-align:right"> Light (b):</td>
|
||||
<td><Input type="text" style="width:60px" value="p" id="light" enterkeyhint="done"/></td>
|
||||
<td style="text-align:right"> Q-value:</td>
|
||||
<td id='Q-value'>2.057</td>
|
||||
<td>MeV</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="text-align:right"> Heavy (B):</td>
|
||||
<td id='heavyName'>25F</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<p style="font: 12px" id='heavySp'></p>
|
||||
|
||||
<p></p>
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<td>
|
||||
<input type="radio" name="SSType" id='HELIOS' value="HELIOS"/>HELIOS
|
||||
</td>
|
||||
<td>
|
||||
<input type="radio" name="SSType" id='SOLARIS' value="SOLARIS" checked="checked"/>SOLARIS
|
||||
</td>
|
||||
<td>
|
||||
<input type="radio" name="SSType" id='ISS' value="ISS"/>ISS
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<p></p>
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<td style="text-align:right"> B-field (abs.):</td>
|
||||
<td><Input type="text" style="width:60px" value="2" id='BField' enterkeyhint="done"/></td>
|
||||
<td>T</td>
|
||||
<td><Input type="range" min="0" max="6" step="0.05" value="2" class="slider" id='BRange'/> </td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td style="text-align:right"> Beam Energy:</td>
|
||||
<td><Input type="text" style="width:60px" value="10" id='KEA' enterkeyhint="done"/></td>
|
||||
<td>MeV/u</td>
|
||||
<td><Input type="range" min="0" max="20" step="0.1" value="10" class="slider" id='KEARange'/> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td id='minKEA'> </td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<p></p>
|
||||
|
||||
<table id="ExTable", style="border:1px solid; text-align:center;">
|
||||
<tr>
|
||||
<th style="width:85px"> E<sub>x</sub> [MeV]</th>
|
||||
<th style="width:85px"> θ<sub>cm</sub>[deg]</th>
|
||||
<th style="width:70px">E<sub>b</sub>[MeV]</th>
|
||||
<th style="width:70px">Z<sub>b0</sub>[mm]</th>
|
||||
<th style="width:70px">Z<sub>b</sub>[mm]</th>
|
||||
<th style="width:70px">2ρ<sub>b</sub>[mm]</th>
|
||||
<th style="width:70px">θLab<sub>b</sub>[deg]</th>
|
||||
<th style="width:60px">T<sub>b</sub>[ns]</th>
|
||||
<th style="width:70px">E<sub>B</sub>[MeV]</th>
|
||||
<th style="width:90px">θLab<sub>B</sub>[deg]</th>
|
||||
<th style="width:80px">Z<sub>B0</sub>/2[mm]</th>
|
||||
<th style="width:70px">2ρ<sub>B</sub>[mm]</th>
|
||||
</tr>
|
||||
</tr>
|
||||
<td><input type="text" id='Ex1' name="Ex" size="8" value="0" enterkeyhint="done"/></td>
|
||||
<td><input type="text" id='theta1' name="thetaCM" size="8" value="10" enterkeyhint="done"/></td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
</tr>
|
||||
</tr>
|
||||
<td><input type="text" id='Ex2' name="Ex" size="8" value="1" enterkeyhint="done"/></td>
|
||||
<td><input type="text" id='theta2' name="thetaCM" size="8" value="40" enterkeyhint="done"/></td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><button type="button" onclick="addRow()" style="width:85px">Add E<sub>x</sub></button></td>
|
||||
<td><button type="button" onclick="deleteRow()">Remove E<sub>x</sub></button></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<p></p>
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<td style="text-align:right"> θ<sub>CM</sub>:</td>
|
||||
<td><Input type="text" style="width:60px" value="0" id='thetaCM' enterkeyhint="done"/></td>
|
||||
<td>deg</td>
|
||||
<td><Input type="range" min="0" max="50" step="0.1" value="0" class="slider" id='thetaCMRange'/> </td>
|
||||
</tr>
|
||||
<td style="text-align:right"> Array Pos:</td>
|
||||
<td><Input type="text" style="width:60px" value="-100" id='posArray' enterkeyhint="done"/></td>
|
||||
<td>mm</td>
|
||||
<td><Input type="range" min="-500" max="1000" step="1" value="-100" class="slider" id='posArrayRange'/> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="text-align:right"> Recoil Pos:</td>
|
||||
<td><Input type="text" style="width:60px" value="1500" id='posRecoil' enterkeyhint="done"/></td>
|
||||
<td>mm</td>
|
||||
<td><Input type="range" min="0" max="2000" step="1" value="1500" class="slider" id='posRecoilRange'/> </td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<td style="text-align:right" > Recoil radius, inner [mm]:</td>
|
||||
<td><Input type="text" style="width:40px" value="10" id='innerRecoil' enterkeyhint="done"/></td>
|
||||
<td style="text-align:right" > outter [mm]:</td>
|
||||
<td><Input type="text" style="width:40px" value="45" id='outterRecoil' enterkeyhint="done"/></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<p></p>
|
||||
|
||||
|
||||
<div class="row">
|
||||
<div class="column">
|
||||
<table cellspacing="0" cellpadding="0">
|
||||
<tr>
|
||||
<td>
|
||||
<div id="Plot_EZ" class="plotStyle"></div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr> <td> </td></tr>
|
||||
<tr>
|
||||
<td> zRange can be changed by Array position.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<table>
|
||||
<tr>
|
||||
<td>eRange:</td>
|
||||
<td><Input type="text" style="width:60px" value="12" id='eRange' enterkeyhint="done"/></td>
|
||||
<td>MeV</td>
|
||||
<td><Input type="range" min="1" max="30" step="0.1" value="12" class="plotSlider" id='eRangeSlider'/></td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
<tr> <td> </td></tr>
|
||||
</table>
|
||||
</div>
|
||||
<div class="column">
|
||||
<table cellspacing="0" cellpadding="0">
|
||||
<tr>
|
||||
<td>
|
||||
<div id="Plot_RZ" class="plotStyle"></div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr> <td> </td></tr>
|
||||
<tr>
|
||||
<td>
|
||||
<table>
|
||||
<tr>
|
||||
<td>zRange(Min):</td>
|
||||
<td><Input type="text" style="width:60px" value="-200" id='zRange1' enterkeyhint="done"/></td>
|
||||
<td>mm</td>
|
||||
<td><Input type="range" min="-2000" max="4000" step="1" value="-200" class="plotSlider" id='zRange1Slider'/></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>zRange(Max):</td>
|
||||
<td><Input type="text" style="width:60px" value="2000" id='zRange2' enterkeyhint="done"/></td>
|
||||
<td>mm</td>
|
||||
<td><Input type="range" min="-2000" max="4000" step="1" value="2000" class="plotSlider" id='zRange2Slider'/></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>rRange:</td>
|
||||
<td><Input type="text" style="width:60px" value="50" id='rRange' enterkeyhint="done"/></td>
|
||||
<td>mm</td>
|
||||
<td><Input type="range" min="1" max="400" step="1" value="50" class="plotSlider" id='rRangeSlider'/></td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
<tr> <td> </td></tr>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<p id="n0"></p>
|
||||
<p id="n1"></p>
|
||||
<p id="n2"></p>
|
||||
<p id="n3"></p>
|
||||
|
||||
<!-- ===================================================== -->
|
||||
<h2> DWBA & Monte Carlo Simultion </h2>
|
||||
|
||||
<h3>DWBA and E<sub>x</sub> List:</h3>
|
||||
<b style="color:red;">For 2-nucleon transfer</b>, <b>Orbital</b> take the form NL=X, where N is number of node, X is momentum number. n and L are related by Σ<sub>i</sub> (2n<sub>i</sub>+l<sub>i</sub>) = 2N + X + 2n + l, where n<sub>i</sub> and l<sub>i</sub> are the principle number and orbital angular momentum of the each transfered nucleon, and n and l are the internal quanta of the 2-nucleon. e.g. (t,p) reaction to 0f orbtial, the left-hand side would be n<sub>i</sub> = 0 and l<sub>i</sub> = 3 and the sum is 3+3 = 6 = 2N + X + 2n+l. Assume n = l = 0, we have 6 = 2N+L. Thus, 3L=0, 2L=2,1L=4, 0L=6. </p>
|
||||
|
||||
Beam J<sup>π</sup>: <input type="text" id="neam_jpi" size="5" value=""/>
|
||||
<BR>TODO: guess the orbital for Beam J<sup>π</sup>=0
|
||||
<br>
|
||||
<input type="checkbox" id="pos" onclick="checkParity()" checked/>Positive parity</td>
|
||||
<input type="checkbox" id="neg" onclick="checkParity()" checked/>Negative parity</td>
|
||||
<input type="checkbox" id="unk" onclick="checkParity()" checked/>Unknown parity</td>
|
||||
<br>
|
||||
|
||||
<button type="button" onclick="addStates()">Add known states</button>
|
||||
Max Ex: <input type="text" id="maxEx" size="5" value="5"/>MeV
|
||||
|
||||
<p id='waiting'></p>
|
||||
|
||||
<table id="ExTable2">
|
||||
<tr>
|
||||
<td><b> E<sub>x</sub> [MeV] </b></td>
|
||||
<td><b> J<sup>π</sup></b></td>
|
||||
<td><b> Orbital </b></td>
|
||||
</tr>
|
||||
</tr>
|
||||
<td><input type="text" name="Ex" size="5" value="0"/></td>
|
||||
<td><input type="text" name="Jpi" size="5" value="3/2+"/></td>
|
||||
<td><input type="text" name="Orb" size="6" value="0d3/2"/></td>
|
||||
<td><button type="button" onclick="addRow2(this)">Insert Ex</button></td>
|
||||
<td><button type="button" onclick="deleteRow2(this)">Remove Ex</button></td>
|
||||
</tr>
|
||||
<!-- <tr>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td><button type="button" onclick="copyEx()">Copy Ex</button></td>
|
||||
<td><button type="button" onclick="pasteEx()"> Paste Ex </button></td>
|
||||
</tr> -->
|
||||
</table>
|
||||
|
||||
<p></p>
|
||||
<input type="checkbox" name="DWBA" value="On"/>Cal. DWBA
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<td>Incoming Channel</td>
|
||||
<td>
|
||||
<select name="op1">
|
||||
<option value="A" selected>D | An & Cai (2006) E < 183, 12 < A < 238</option>
|
||||
<option value="H">D | Han, Shi, & Shen (2006) E < 200, 12 < A < 209</option>
|
||||
<option value="B">D | Bojowald et al. (1988) 50 < E < 80, 27 < A < 208</option>
|
||||
<option value="D">D | Daehnick, Childs, Vrcelj (1980) 11.8 < E < 80, 27 < A < 238 (REL) </option>
|
||||
<option value="C">D | Daehnick, Childs, Vrcelj (1980) 11.8 < E < 80, 27 < A < 238 (NON-REL) </option>
|
||||
<option value="L">D | Lohr and Haeberli (1974) 9 < E < 13, 40 < A </option>
|
||||
<option value="Q">D | Perey and Perey (1963) 12 < E < 25, 40 < A </option>
|
||||
<option value="Z">D | Zhang, Pang, Lou (2016) 5 < E < 170, A < 18, spe 6-7Li </option>
|
||||
<option value="K">P | Koning & Delaroche (2009) E < 200, 24 < A < 209 | Iso.Dep.</option>
|
||||
<option value="V">P | Varner et al. (1991) 16 < E < 65, 4 < A < 209</option>
|
||||
<option value="M">P | Menet et al. (1971) 30 < E < 60, 40 < A </option>
|
||||
<option value="G">P | Becchetti and Greenlees (1969) E < 50, 40 < A </option>
|
||||
<option value="P">P | Perey (1963) E < 20, 30 < A < 100 </option>
|
||||
<option value="x">A=3 | Xu, Guo, Han, & Shen (2011) E < 250, 20 < A < 209 </option>
|
||||
<option value="l">A=3 | Liang, Li, & Cai (2009) E < 270, All masses </option>
|
||||
<option value="p">A=3 | Pang et al. (2009) all E, all masses, Iso. Dep. </option>
|
||||
<option value="c">A=3 | Li, Liang, Cai (2007), E < 40, 48 < A < 232, Tritons </option>
|
||||
<option value="t">A=3 | Trost et al. (1987) 10 < E < 220, 10 < A < 208 </option>
|
||||
<option value="h">A=3 | Hyakutake et al. (1980) 90 < E < 120, About 58 < A < 92 </option>
|
||||
<option value="b">A=3 | Becchetti and Greenlees (1971), E < 40, 40 < A, Iso. Dep. </option>
|
||||
<option value="s">A=4 | Su & Han (2015) E < 398, 20 < A < 209 </option>
|
||||
<option value="a">A=4 | Avrigeanu et al. (2009) </option>
|
||||
<option value="f">A=4 | Bassani and Picard (1969) 24 < E < 31, A = 90 </option>
|
||||
</select>
|
||||
<td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Outgoing Channel</td>
|
||||
<td>
|
||||
<select name="op2">
|
||||
<option value="A">D | An & Cai (2006) E < 183, 12 < A < 238</option>
|
||||
<option value="H">D | Han, Shi, & Shen (2006) E < 200, 12 < A < 209</option>
|
||||
<option value="B">D | Bojowald et al. (1988) 50 < E < 80, 27 < A < 208</option>
|
||||
<option value="D">D | Daehnick, Childs, Vrcelj (1980) 11.8 < E < 80, 27 < A < 238 (REL) </option>
|
||||
<option value="C">D | Daehnick, Childs, Vrcelj (1980) 11.8 < E < 80, 27 < A < 238 (NON-REL) </option>
|
||||
<option value="L">D | Lohr and Haeberli (1974) 9 < E < 13, 40 < A </option>
|
||||
<option value="Q">D | Perey and Perey (1963) 12 < E < 25, 40 < A </option>
|
||||
<option value="Z">D | Zhang, Pang, Lou (2016) 5 < E < 170, A < 18, spe 6-7Li </option>
|
||||
<option value="K" selected>P | Koning & Delaroche (2009) E < 200, 24 < A < 209, Iso.Dep.</option>
|
||||
<option value="V">P | Varner et al. (1991) 16 < E < 65, 4 < A < 209</option>
|
||||
<option value="M">P | Menet et al. (1971) 30 < E < 60, 40 < A </option>
|
||||
<option value="G">P | Becchetti and Greenlees (1969) E < 50, 40 < A </option>
|
||||
<option value="P">P | Perey (1963) E < 20, 30 < A < 100 </option>
|
||||
<option value="x">A=3 | Xu, Guo, Han, & Shen (2011) E < 250, 20 < A < 209 </option>
|
||||
<option value="l">A=3 | Liang, Li, & Cai (2009) E < 270, All masses </option>
|
||||
<option value="p">A=3 | Pang et al. (2009) all E | all masses, Iso. Dep. </option>
|
||||
<option value="c">A=3 | Li, Liang, Cai (2007), E < 40, 48 < A < 232, Tritons </option>
|
||||
<option value="t">A=3 | Trost et al. (1987) 10 < E < 220, 10 < A < 208 </option>
|
||||
<option value="h">A=3 | Hyakutake et al. (1980) 90 < E < 120, About 58 < A < 92 </option>
|
||||
<option value="b">A=3 | Becchetti and Greenlees (1971), E < 40, 40 < A, Iso. Dep. </option>
|
||||
<option value="s">A=4 | Su & Han (2015) E < 398, 20 < A < 209 </option>
|
||||
<option value="a">A=4 | Avrigeanu et al. (2009) </option>
|
||||
<option value="f">A=4 | Bassani and Picard (1969) 24 < E < 31, A = 90 </option>
|
||||
</select>
|
||||
<td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<input type="checkbox" name="onlyDWBA" value="On"/>Only DWBA and Don't Sim. Angle range (for only DWBA)
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Min [deg]: </td>
|
||||
<td><input type = "text" name = "minAng" size="6" value="0" /></td>
|
||||
<td>Max [deg]: </td>
|
||||
<td><input type = "text" name = "maxAng" size="6" value="90"/></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<button type="button" onclick="DWBA_Sim()" style="width:200px;height:60px;">Run DWBA and Simulation</button>
|
||||
|
||||
|
||||
<!-- ===================================================== -->
|
||||
<hr>
|
||||
<h1>θ<sub>CM</sub> Calculator</h1>
|
||||
|
||||
The calculation only give θ<sub>CM</sub> after the bending.
|
||||
<p></p>
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<td>Ex [MeV] : </td>
|
||||
<td><Input type="text" style="width:60px" value="0" id='Ex0' enterkeyhint="done"/></td>
|
||||
<td>θ<sub>CM</sub> Gate [deg] : </td>
|
||||
<td><Input type="text" style="width:60px" value="10" id='thetaCMGate' enterkeyhint="done"/></td>
|
||||
<td>X Gate [%] : </td>
|
||||
<td><Input type="text" style="width:60px" value="95" id='XGate' enterkeyhint="done"/></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<table id='thetaCMTable' style="border:1px solid; text-align:center;">
|
||||
<tr>
|
||||
<td style="width:30px"><b>ID</b></td>
|
||||
<td style="width:120px"><b>pos<sub>0</sub>(gated)</b></td>
|
||||
<td style="width:120px"><b>pos<sub>1</sub>(gated)</b></td>
|
||||
<td style="width:60px"><b>θ<sub>1</sub>[deg]</b></td>
|
||||
<td style="width:60px"><b>θ<sub>2</sub>[deg]</b></td>
|
||||
<td style="width:60px"><b>θ<sub>avg</sub>[deg]</b></td>
|
||||
<td style="width:60px"><b>Δθ[deg]</b></td>
|
||||
<td style="width:100px"><b>sin(θ<sub>avg</sub>)Δθ</b></td>
|
||||
</tr>
|
||||
</table>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<!-- ===================================================== -->
|
||||
|
||||
<hr>
|
||||
<p></p>
|
||||
HELIOSmatics was first built by Ben P. Kay in MS Excel around 2010. It was modified by Ryan Tang later. And now it migrated to the web on Dec, 2022.
|
||||
<br>
|
||||
The calculation can be found in the source code (heliosmatics.js or press F12)
|
||||
|
||||
<p></p>
|
||||
|
||||
</body>
|
||||
|
||||
<!-- ######################################################################################### -->
|
||||
|
||||
<script src="heliosmatics.js"></script>
|
||||
<script src="montecarlo.js"></script>
|
||||
|
||||
</html>
|
|
@ -1,196 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>SOLARIS Si-Array Mode Simulation </title>
|
||||
<meta name="description" content="SOLARIS Si-Array mode simulation. This is ported from the original Heliosmatics in MS excel, Monte Carlo simulation using CERN ROOT, and DWBA simulation using the Peolemy.">
|
||||
<link rel="icon" type="image/x-icon" href="logos/SOLARIS_favicon.png">
|
||||
</head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<script src="https://cdn.plot.ly/plotly-2.16.1.min.js"></script>
|
||||
<style>
|
||||
|
||||
:root{
|
||||
--navWidth: 300px;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: Arial, Helvetica, sans-serif;
|
||||
}
|
||||
/* table, th, td { */
|
||||
/* border: 1px solid black; */
|
||||
/* } */
|
||||
table.center{
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
header {
|
||||
background-color: #F7CF3C;
|
||||
padding: 10px;
|
||||
text-align: center;
|
||||
font-size: 35px;
|
||||
color: black;
|
||||
}
|
||||
nav {
|
||||
float: left;
|
||||
width : var(--navWidth);
|
||||
height: 100vh;
|
||||
/* background: #6DB33E; */
|
||||
background: #1363A7;
|
||||
padding: 0px;
|
||||
}
|
||||
article {
|
||||
float: none;
|
||||
padding: 0px;
|
||||
margin-left: var(--navWidth);
|
||||
height: 1000px;
|
||||
height : 100vh;
|
||||
/* background: #1363A7; */
|
||||
background: #6DB33E;
|
||||
}
|
||||
a {
|
||||
color : #F7CF3C;
|
||||
}
|
||||
|
||||
.column1{
|
||||
float : left;
|
||||
width : 50%;
|
||||
text-align:right;
|
||||
}
|
||||
.column2{
|
||||
float : right;
|
||||
width : 50%;
|
||||
text-align: left;
|
||||
}
|
||||
.row:after {
|
||||
content: "";
|
||||
display: table;
|
||||
clear: both;
|
||||
}
|
||||
|
||||
@media (max-width: 1000px) {
|
||||
.column1 {
|
||||
width: 100%;
|
||||
height: 40%;
|
||||
text-align:center;
|
||||
}
|
||||
.column2 {
|
||||
width: 100%;
|
||||
text-align:center;
|
||||
}
|
||||
nav {
|
||||
width: 100%;
|
||||
height: auto;
|
||||
margin-left : 0;
|
||||
}
|
||||
article {
|
||||
float: left;
|
||||
margin-left : 0px;
|
||||
width: 100%;
|
||||
height: 100vh;
|
||||
margin-left : 0;
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
||||
<body>
|
||||
|
||||
<header>
|
||||
<div class="row">
|
||||
<div class="column1"">
|
||||
<img src="logos/SOLARIS_logo.png" width="300">
|
||||
</div>
|
||||
<div class="column2">
|
||||
<span style="font-size:70px;">Simulation</span>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<section>
|
||||
|
||||
<nav id="nav">
|
||||
<div class="visit-counter"></div>
|
||||
<p></p>
|
||||
<table class="center">
|
||||
<tr>
|
||||
<td style="text-align:right"><a href="heliosmatics.html" target="uploaded">HELIOSmatics</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="text-align:right"><a href="simpleSim.html" target="uploaded">DWBA and Monte Carlo Simulation</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="text-align:right"><a href="miscCal.html" target="uploaded">Misc. Calulations</a></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="text-align:right"><a href="instruction.html" target="uploaded">Intructions & Credits</a></td>
|
||||
</tr>
|
||||
|
||||
<table>
|
||||
|
||||
<p></p><!-- ////////////////////////////////////////// -->
|
||||
|
||||
<form action = "displayIsoData.py" method = "POST" target = "NuclearData">
|
||||
<table class="center">
|
||||
<tr>
|
||||
<td style="text-align:right">Isotopes Name:</td>
|
||||
<td><input type = "text" name = "ASym" id="ASym" size="13" value="24F" enterkeyhint="done"/></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="text-align:right">Max Ex [MeV]:</td>
|
||||
<td><input type = "text" name = "maxEx" id="maxEx" size="13" value="can be omitted" enterkeyhint="done"/></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td></td>
|
||||
<td><button onclick="PlotLevels()" style="width: 130px;">Get Isotopes Data</button></td>
|
||||
</tr>
|
||||
</table>
|
||||
</form>
|
||||
<div id="Plot_Levels" class="plotStyle"></div>
|
||||
<iframe name="NuclearData" style="border:none;width:100%;height:100%" ></iframe>
|
||||
|
||||
</nav>
|
||||
|
||||
<!-- ////////////////////////////////////////// -->
|
||||
<article id="article" >
|
||||
<iframe id="main" name="uploaded" style="border:none;width:100%;" src="heliosmatics.html"></iframe>
|
||||
</article>
|
||||
</section>
|
||||
|
||||
|
||||
<script src="EnergyLevelsPlot.js"></script>
|
||||
|
||||
<script>
|
||||
|
||||
let frame = document.getElementById("main");
|
||||
let frameNav = document.getElementById("nav");
|
||||
let frameArticle = document.getElementById("article");
|
||||
|
||||
let x = window.matchMedia("(max-width: 1000px)");
|
||||
|
||||
adjustHeight();
|
||||
|
||||
x.addListener(adjustHeight);
|
||||
|
||||
function adjustHeight(){
|
||||
let hhh = frame.contentWindow.document.body.scrollHeight * 1.1 + 'px';
|
||||
|
||||
frame.style.height = hhh;
|
||||
frameArticle.style.height = hhh;
|
||||
|
||||
if( x.matches){
|
||||
frameNav.style.height = "40%";
|
||||
}else{
|
||||
frameNav.style.height = hhh;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
frame.onload = adjustHeight;
|
||||
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -1,74 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<body>
|
||||
<style>
|
||||
body{
|
||||
font-family: Arial, Helvetica, sans-serif;
|
||||
}
|
||||
a {
|
||||
color : #1363A7;
|
||||
}
|
||||
hr {
|
||||
height:4px;
|
||||
background-color:#F7CF3C;
|
||||
border-style:none;
|
||||
border-width:none;
|
||||
}
|
||||
img {
|
||||
height: 100px;
|
||||
}
|
||||
@media screen and (max-width: 1000px) {
|
||||
img {
|
||||
height: 50px;
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
||||
<h1>Intructions:</h1>
|
||||
<p>
|
||||
<ul>
|
||||
<li>Use the <a href="heliosmatics.html" target="uploaded">HELIOSmatics</a> to check the detector and field settings.</li>
|
||||
<li>The easiest way to do DWBA and Monte Carlo Simulation is use the <a href="simpleSim.html" target="uploaded">Simplied Interface</a>
|
||||
<li>The kenimatic calculation is documented in <a href="https://wiki.anl.gov/wiki_heliosdaq/images/3/3f/Kinematics_of_HELIOS.pdf" target="_blank" >Here</a>.</li>
|
||||
<li>The DWBA calucation is using Ptolemy. <a href="https://www.phy.anl.gov/theory/research/ptolemy/" target="_blank">Here</a> for more detail. </li>
|
||||
<li>Past calculations can be found <a href="files/" target="uploaded">Here</a>. Clear every Monday.</li>
|
||||
</ul>
|
||||
</p>
|
||||
|
||||
<hr>
|
||||
<h1>Credits:</h1>
|
||||
|
||||
<h4>This page is created and hosted by Fox's Lab (FSU) in collabortion with SOLARIS (FRIB).</h4>
|
||||
<h4>The SOLARIS project is based on HELIOS (ANL) and is leaded by ANL.</h4>
|
||||
<h4>The ISS (ISOLDE Solenoidal Spectrometer) is located as CERN.</h4>
|
||||
|
||||
<a href="https://fsunuc.physics.fsu.edu" target="_blank"><img src="logos/FSU_logo_640.png"></a>
|
||||
<a href="https://fribs.msu.edu/news/2021/solaris.html" target="_blank"><img src="logos/FRIB_logo.jpg"></a>
|
||||
<a href="https://home.cern/science/experiments/isolde" target="_blank"><img src="logos/CERN_logo.svg"></a>
|
||||
<a href="https://www.anl.gov/phy" target="_blank"><img src="logos/ANL_logo.gif"></a>
|
||||
|
||||
<a href="https://www.anl.gov/phy/solaris" target="_blank"><img src="logos/SOLARIS_logo.png"></a>
|
||||
<a href="https://isolde-solenoidal-spectrometer.web.cern.ch/" target="_blank"><img src="logos/ISS_logo.png"></a>
|
||||
<a href="https://www.anl.gov/phy/helical-orbit-spectrometer" target="_blank"><img src="logos/HELIOS_logo.jpg"></a>
|
||||
|
||||
<p></p>
|
||||
The simulation was started from Ben Kay (ANL) around 2010 using excel spreadsheet.
|
||||
<br>
|
||||
Ryan Tang (former ANL postdoc, now at FSU) developed a Monte Carlo simulation with DWBA using CERN ROOT framework.
|
||||
<br>
|
||||
And the whole simulation migrated to here at Dec, 2022.
|
||||
|
||||
<p></p>
|
||||
Contact: Ryan Tang (rtang at fsu.edu)
|
||||
<p> any suggestions and feedback are very welcome.</p>
|
||||
|
||||
<hr>
|
||||
<h2> Todo : </h2>
|
||||
<ul>
|
||||
<li>File name of the images of past calculations include reaction</li>
|
||||
<li>Change the legend position of the DWBA calcualtion</li>
|
||||
<li>A 3-D simulation? </li>
|
||||
</ul>
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -1,185 +0,0 @@
|
|||
#!/usr/bin/env /usr/bin/python3
|
||||
|
||||
import pandas as pd
|
||||
import urllib.request
|
||||
import re
|
||||
import numpy
|
||||
|
||||
me = 0.51099895000 # +- 15
|
||||
mp = 938.27208816 # +- 29
|
||||
mn = 939.56542052 # +- 54
|
||||
ma = 3727.37915
|
||||
|
||||
livechart = "https://nds.iaea.org/relnsd/v0/data?"
|
||||
|
||||
def lc_read_csv(url):
|
||||
req = urllib.request.Request(url)
|
||||
req.add_header('User-Agent', 'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:77.0) Gecko/20100101 Firefox/77.0')
|
||||
return pd.read_csv(urllib.request.urlopen(req))
|
||||
|
||||
# Read the saved CSV file back into a DataFrame
|
||||
try :
|
||||
haha = pd.read_csv('IAEA_NuclearData.csv')
|
||||
except FileNotFoundError:
|
||||
# the service URL
|
||||
url = livechart + "fields=ground_states&nuclides=all"
|
||||
haha = lc_read_csv(url)
|
||||
haha.insert(0, 'A', haha['z'] + haha['n'])
|
||||
haha.to_csv('IAEA_NuclearData.csv', index=False)
|
||||
haha = pd.read_csv('IAEA_NuclearData.csv')
|
||||
|
||||
# print(haha.columns)
|
||||
## ['A', 'z', 'n', 'symbol', 'radius', 'unc_r', 'abundance', 'unc_a',
|
||||
## 'energy_shift', 'energy', 'unc_e', 'ripl_shift', 'jp', 'half_life',
|
||||
## 'operator_hl', 'unc_hl', 'unit_hl', 'half_life_sec', 'unc_hls',
|
||||
## 'decay_1', 'decay_1_%', 'unc_1', 'decay_2', 'decay_2_%', 'unc_2',
|
||||
## 'decay_3', 'decay_3_%', 'unc_3', 'isospin', 'magnetic_dipole', 'unc_md',
|
||||
## 'electric_quadrupole', 'unc_eq', 'qbm', 'unc_qb', 'qbm_n', 'unc_qbmn',
|
||||
## 'qa', 'unc_qa', 'qec', 'unc_qec', 'sn', 'unc_sn', 'sp', 'unc_sp',
|
||||
## 'binding', 'unc_ba', 'atomic_mass', 'unc_am', 'massexcess', 'unc_me',
|
||||
## 'me_systematics', 'discovery', 'ENSDFpublicationcut-off',
|
||||
## 'ENSDFauthors', 'Extraction_date']
|
||||
|
||||
|
||||
def GetExList(ASym : str, maxEx : float) ->pd.DataFrame:
|
||||
try:
|
||||
exList = lc_read_csv(livechart + "fields=levels&nuclides=" + ASym)
|
||||
exJpi = exList[['energy', 'jp']]
|
||||
exJpi = exJpi[exJpi['energy'] < (maxEx * 1000)]
|
||||
return exJpi
|
||||
except:
|
||||
return pd.DataFrame()
|
||||
|
||||
def BreakDownName(ASym : str):
|
||||
match = re.match(r'(\d+)(\D+)', ASym)
|
||||
return [int(match.group(1)), match.group(2) ]
|
||||
|
||||
def GetAZ(ASym : str):
|
||||
[A, sym] = BreakDownName(ASym)
|
||||
try:
|
||||
dudu = haha[(haha['symbol']==sym) & (haha['A']==A)]
|
||||
Z = int(dudu['z'].iloc[0])
|
||||
return [A, Z]
|
||||
except:
|
||||
return [A, numpy.nan]
|
||||
|
||||
def GetBindingPerA(ASym : str) -> float:
|
||||
[A, sym] = BreakDownName(ASym)
|
||||
try:
|
||||
dudu = haha[(haha['symbol']==sym) & (haha['A']==A)]
|
||||
Z = int(dudu['z'].iloc[0])
|
||||
N = A - Z
|
||||
return dudu['binding'].iloc[0]/1000
|
||||
except:
|
||||
return numpy.nan
|
||||
|
||||
def GetMassFromSym(ASym : str) -> float:
|
||||
[A, sym] = BreakDownName(ASym)
|
||||
try:
|
||||
dudu = haha[(haha['symbol']==sym) & (haha['A']==A)]
|
||||
Z = int(dudu['z'].iloc[0])
|
||||
N = A - Z
|
||||
binding = dudu['binding'].iloc[0]/1000
|
||||
return Z*mp + N*mn - binding*A
|
||||
except:
|
||||
return numpy.nan
|
||||
|
||||
def GetMassFromAZ(A : int, Z : int) -> float:
|
||||
try:
|
||||
dudu = haha[(haha['z']==Z) & (haha['A']==A)]
|
||||
Z = int(dudu['z'].iloc[0])
|
||||
N = A - Z
|
||||
binding = dudu['binding'].iloc[0]/1000
|
||||
return Z*mp + N*mn - binding*A
|
||||
except:
|
||||
return numpy.nan
|
||||
|
||||
def GetSymbol(A : int, Z : int) -> str:
|
||||
try:
|
||||
dudu = haha[(haha['z']==Z) & (haha['A']==A)]
|
||||
return "%d%s" % (A , dudu['symbol'].iloc[0])
|
||||
except:
|
||||
return "0x"
|
||||
|
||||
def GetJpi(ASym : str):
|
||||
[A, sym] = BreakDownName(ASym)
|
||||
try:
|
||||
dudu = haha[(haha['symbol']==sym) & (haha['A']==A)]
|
||||
return dudu['jp'].iloc[0]
|
||||
except:
|
||||
return "unknown"
|
||||
|
||||
def GetHalfLife(ASym : str) -> float:
|
||||
[A, sym] = BreakDownName(ASym)
|
||||
try:
|
||||
dudu = haha[(haha['symbol']==sym) & (haha['A']==A)]
|
||||
return dudu['half_life_sec'].iloc[0]
|
||||
except:
|
||||
return "unknown"
|
||||
|
||||
def GetSn(ASym : str) -> float:
|
||||
[A, Z] = GetAZ(ASym)
|
||||
if numpy.isnan(Z) :
|
||||
return numpy.nan
|
||||
else:
|
||||
mass0 = GetMassFromAZ(A, Z)
|
||||
mass1 = GetMassFromAZ(A-1, Z)
|
||||
return mass1 + mn - mass0
|
||||
|
||||
def GetSp(ASym : str):
|
||||
[A, Z] = GetAZ(ASym)
|
||||
if numpy.isnan(Z) :
|
||||
return numpy.nan
|
||||
else:
|
||||
mass0 = GetMassFromAZ(A, Z)
|
||||
mass1 = GetMassFromAZ(A-1, Z-1)
|
||||
return mass1 + mp - mass0
|
||||
|
||||
def GetSa(ASym : str):
|
||||
[A, Z] = GetAZ(ASym)
|
||||
if numpy.isnan(Z) :
|
||||
return numpy.nan
|
||||
else:
|
||||
mass0 = GetMassFromAZ(A, Z)
|
||||
mass1 = GetMassFromAZ(A-4, Z-2)
|
||||
return mass1 + ma - mass0
|
||||
|
||||
def PrintIso(ASym: str):
|
||||
[A, Z] = GetAZ(ASym)
|
||||
print("========================= ", ASym)
|
||||
print("A : %d, Z : %d, N : %d" % (A, Z, A-Z))
|
||||
print(" Jpi : ", GetJpi(ASym))
|
||||
print("half-live : %.2f sec" % (GetHalfLife(ASym)))
|
||||
print(" Mass : %9.2f MeV" % (GetMassFromSym(ASym) ))
|
||||
print(" Binding : %9.2f MeV/A" % (GetBindingPerA(ASym)))
|
||||
print(" Binding : %9.2f MeV" % (GetBindingPerA(ASym) * A))
|
||||
print(" Sn: %9.2f MeV" % GetSn(ASym))
|
||||
print(" Sp: %9.2f MeV" % GetSp(ASym))
|
||||
print(" Sa: %9.2f MeV" % GetSa(ASym))
|
||||
print("=============================")
|
||||
|
||||
def PrintIsoWeb(ASym : str):
|
||||
[A, Z] = GetAZ(ASym)
|
||||
print("<br>========================= ", ASym)
|
||||
print("<br>A : %d, Z : %d, N : %d" % (A, Z, A-Z))
|
||||
print("<br> Jpi : ", GetJpi(ASym))
|
||||
print("<br>half-live : %.2f sec" % (GetHalfLife(ASym)))
|
||||
print("<br> Mass : %9.2f MeV" % (GetMassFromSym(ASym) ))
|
||||
print("<br> Binding : %9.2f MeV/A" % (GetBindingPerA(ASym)))
|
||||
print("<br> Binding : %9.2f MeV" % (GetBindingPerA(ASym) * A))
|
||||
print("<br> Sn: %9.2f MeV" % GetSn(ASym))
|
||||
print("<br> Sp: %9.2f MeV" % GetSp(ASym))
|
||||
print("<br> Sa: %9.2f MeV" % GetSa(ASym))
|
||||
print("<br>=============================")
|
||||
|
||||
|
||||
def PrintIsoExWeb(ASym : str, maxEx : float):
|
||||
exList = GetExList(ASym, maxEx)
|
||||
if exList.empty:
|
||||
print("<br> cannot find Ex data")
|
||||
else:
|
||||
print("<table>")
|
||||
for i in range(0,len(exList)):
|
||||
print("<tr><td style=\"text-align:right\" width=80>%9.3f</td><td style=\"text-align:right\" width=100>%s</td></tr>" % (exList['energy'].iloc[i]/1000, exList['jp'].iloc[i].replace(' ', ',')))
|
||||
print("</table>")
|
||||
|
Before Width: | Height: | Size: 7.2 KiB |
|
@ -1 +0,0 @@
|
|||
<svg height="316.227766" viewBox="0 0 14.41662 14.41666" width="316.227766" xmlns="http://www.w3.org/2000/svg"><path d="m171.53706 206.16631c0-.26917-.2353-.35454-.41945-.35454-.12453 0-.20567.008-.26247.0134-.008.19756-.0162.37924-.0162.57433v.14887c.0268.004.15346.003.18133.002.22331-.005.51682-.0759.51682-.38453m4.66831-.97296c.50271.61665.91016 1.59279.96943 2.40947h.008l.4191-4.32823h.23636s-.26811 2.79788-.4244 4.18818c-.19543 1.74131-.44379 2.46415-.91898 3.22474l-.0727-.33126c.37006-.65017.47589-1.21779.52387-1.51659.15064-.93098-.0646-2.20169-.71332-3.19334-.72672-1.11125-2.026-1.92864-3.62091-1.92864-1.31021 0-2.44863.57573-3.24308 1.47426l-.19262-.1524c.84102-.95462 2.0634-1.56351 3.4357-1.56351 1.43898 0 2.72027.64664 3.5934 1.71732m-2.32798 2.39748-.0885-.00071c-.10866-.14675-1.24425-1.33138-1.34267-1.43616-.002.10019-.003.30833-.003.51082 0 .26882.0205.6791.0324.901-.0275-.005-.0681-.01-.11536-.01-.048 0-.0871.004-.11853.01.0222-.2861.0282-.75036.0282-1.1871 0-.34078-.005-.52775-.009-.69991l.0885.001c.11465.12453 1.24389 1.29293 1.34232 1.3977.002-.0998.003-.27657.003-.47907 0-.26881-.0205-.67945-.0324-.90099.0275.005.0681.01.11535.01.048 0 .0871-.004.11889-.01-.0226.2861-.0286.75036-.0286 1.1871 0 .34078.005.5341.009.70626m-2.04858-.0342c-.0247 0-.11818.001-.16969.009-.10689-.16298-.44944-.67663-.68262-.91616-.007 0-.13759 0-.13759 0v.21519c0 .23283.0106.46814.0215.70097-.0459-.008-.12911-.009-.14605-.009-.0173 0-.10054.001-.1464.009.0109-.23283.0215-.46814.0215-.70097v-.46531c0-.23284-.0106-.46849-.0215-.70097.10301.008.23283.0134.33584.0134.10302 0 .20567-.0134.30833-.0134.30586 0 .58632.0903.58632.43074 0 .36018-.35913.49001-.5648.51682.13265.1651.60748.74365.76447.91969-.054-.008-.14464-.009-.16933-.009m-1.58962.009c-.097-.005-.23213-.009-.36019-.0113-.0737-.001-.14569-.002-.20214-.002h-.024c-.1651 0-.41839.005-.58349.0134.0109-.23566.0219-.47096.0219-.70379v-.46532c0-.23283-.0109-.46813-.0219-.69814.16228.008.4131.0134.57538.0134s.46531-.007.55915-.0134c-.004.0254-.007.0554-.007.0921 0 .037.004.0751.007.0935-.1785-.0134-.49671-.0353-.84843-.0353-.003.11642-.008.60995-.008.67769.31926 0 .52387-.0138.68368-.0268-.005.0268-.008.0755-.008.10231 0 .0272.003.0674.008.0945-.18662-.019-.60466-.0247-.68368-.0247-.005.0907-.00071.67628.003.72566.19791-.003.70485-.0183.88935-.0353-.003.0205-.006.0628-.006.10407 0 .0409.002.0709.006.0995m-1.73037 2.69028c-.32244-.65581-.46885-1.32186-.48825-1.95897.0822 0 .1771.003.25894.003.0286.60996.16651 1.36772.64347 2.19146-.17216-.0631-.30163-.14676-.41416-.23566m-1.43263-3.62479c0-.58173.43991-.96908 1.03822-.96908.23283 0 .49918.072.6477.13547-.031.0688-.0564.15981-.0674.2166l-.0162.006c-.115-.12736-.29986-.23777-.57361-.23777-.34749 0-.74719.28116-.74719.84208 0 .5461.40746.83608.77153.83608.32737 0 .48366-.1524.62441-.27129l.0109.0109-.0399.21202c-.0646.0487-.28822.18803-.62442.18803-.60925 0-1.02411-.38382-1.02411-.96873m4.8461-4.27002c.7112.19967 1.3776.56515 1.90747 1.05904-.15275-.0406-.30868-.0737-.46708-.0984-.74506-.58878-1.71485-.94015-2.72803-.94015-2.39395 0-4.35327 1.95227-4.35327 4.35187 0 2.39959 1.95227 4.35151 4.35186 4.35151 2.3996 0 4.35152-1.95192 4.35152-4.35151 0-.92816-.34961-1.85561-.82974-2.51072.11466.0346.25436.0935.41522.18873.32491.49283.62654 1.29752.88477 2.53189.27093 1.29505 1.66476 7.49794 1.81539 8.16822h1.68734v-12.71341l-7.03545-.0434zm-2.32022 9.05439c.34537.29881.89218.67487 1.56845.91793-.0564.0603-.11782.12559-.18309.19473-.67557-.26705-1.33632-.68192-1.84961-1.24036.14428.0487.30339.0928.46425.1277m-5.06095-10.72056v14.41662h4.30248l4.25627-4.52614-.006-.005c-.68439.4826-1.55293.74471-2.4892.74471-1.73532 0-3.26461-1.02941-3.92783-2.3107l-.007.005.90276 3.04624h-.24448s-.44803-1.54376-.83044-2.88925c-.28928-1.01847-.46778-1.77306-.46531-2.44264.008-2.30328 1.81892-4.41501 4.22769-4.57094.066-.005.27093-.0258.57608-.0261 1.85526-.001 7.57203.0427 8.1213.0469v-1.48802zm11.37956 10.37802.0649.29492c-.77823.84067-1.96956 1.47073-3.35668 1.47073-.29704 0-.60713-.0289-.95215-.10195.0702-.0744.13723-.14605.20038-.21308.22154.0392.47625.0653.73766.0653 1.34902.00071 2.52765-.60642 3.30588-1.51588m-.72285-4.21147c.0219 1.27142-.56056 2.13466-.744 2.43382-.15981.26105-.54187.76412-1.27706 1.54481-.92745.98496-3.82623 4.06612-4.01955 4.27144h7.86095l-1.81257-8.25077z" fill="#1e59ae" transform="translate(-164.54114 -200.69462)"/></svg>
|
Before Width: | Height: | Size: 4.3 KiB |
Before Width: | Height: | Size: 18 KiB |
Before Width: | Height: | Size: 600 KiB |
Before Width: | Height: | Size: 93 KiB |
Before Width: | Height: | Size: 5.5 KiB |
Before Width: | Height: | Size: 80 KiB |
Before Width: | Height: | Size: 215 KiB |
|
@ -1,43 +0,0 @@
|
|||
#!/usr/bin/python3
|
||||
|
||||
import isotopeLib
|
||||
import cgi
|
||||
|
||||
form = cgi.FieldStorage()
|
||||
|
||||
ASym = form.getvalue('ASym')
|
||||
A=form.getvalue('A')
|
||||
Z=form.getvalue('Z')
|
||||
|
||||
|
||||
print( "Content-type:text/html\r\n\r\n")
|
||||
|
||||
if 'ASym' in form :
|
||||
|
||||
if ASym == "p" : ASym = "1H"
|
||||
if ASym == "d" : ASym = "2H"
|
||||
if ASym == "t" : ASym = "3H"
|
||||
if ASym == "a" : ASym = "4He"
|
||||
|
||||
[A,Z] = isotopeLib.GetAZ(ASym)
|
||||
|
||||
if 'A' in form:
|
||||
ASym = isotopeLib.GetSymbol(float(A), float(Z))
|
||||
|
||||
#===================================
|
||||
# print(A)
|
||||
# print(Z)
|
||||
# print(isotopeLib.GetMassFromSym(ASym))
|
||||
# print(ASym)
|
||||
# print(isotopeLib.GetSn(ASym))
|
||||
# print(isotopeLib.GetSp(ASym))
|
||||
# print(isotopeLib.GetSa(ASym))
|
||||
|
||||
print(A , ",",
|
||||
Z , ",",
|
||||
format(isotopeLib.GetMassFromSym(ASym), '.2f'), ",",
|
||||
ASym, ",",
|
||||
format(isotopeLib.GetSn(ASym), '.2f'), ",",
|
||||
format(isotopeLib.GetSp(ASym), '.2f'), ",",
|
||||
format(isotopeLib.GetSa(ASym), '.2f')
|
||||
)
|
|
@ -1,287 +0,0 @@
|
|||
<!DOCTYOE html>
|
||||
<html>
|
||||
|
||||
<style>
|
||||
body{
|
||||
font-family: Arial, Helvetica, sans-serif;
|
||||
}
|
||||
table{
|
||||
border-collapse: collapse;
|
||||
border : 1px solid;
|
||||
}
|
||||
|
||||
td{
|
||||
padding : 4px;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
<body>
|
||||
|
||||
|
||||
<h1> enA, pnA, pps convertor </h1>
|
||||
|
||||
<table id="convertor">
|
||||
<tr>
|
||||
<td style="text-align:right">Charge state:</td>
|
||||
<td><input type="text" id="ChargeState" size="10" value="6" enterkeyhint="done"/> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="text-align:right">Attenuation:</td>
|
||||
<td><input type="text" id="att" size="10" value="1e+4" enterkeyhint="done" /> </td>
|
||||
</tr>
|
||||
<tr style="text-align:center">
|
||||
<td>enA </td>
|
||||
<td>pnA </td>
|
||||
<td>pps </td>
|
||||
<td>att. pps </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><input type="text" id='enA' size="10" value="6" enterkeyhint="done"/></td>
|
||||
<td><input type="text" id="pnA" size="10" enterkeyhint="done"/></td>
|
||||
<td><input type="text" id="pps" size="10" enterkeyhint="done"/></td>
|
||||
<td width="100"></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<h1> Yield Calculator </h1>
|
||||
|
||||
<table id="yieldTable">
|
||||
<tr>
|
||||
<td style="text-align:right"> Integrated Xsec </td>
|
||||
<td><Input type="text" id="Xsec" size="10" value="4" enterkeyhint="done"/></td>
|
||||
<td>mb</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="text-align:right"> Beam intensity </td>
|
||||
<td><Input type="text" id="BeamPPS" size="10" value="1e5" enterkeyhint="done"/></td>
|
||||
<td>pps</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="text-align:right"> Target thickness </td>
|
||||
<td><Input type="text" id="thickness" size="10" value="100" enterkeyhint="done"/></td>
|
||||
<td>ug/cm2</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="text-align:right"> Target molar mass </td>
|
||||
<td><Input type="text" id="molar" size="10" value="16" enterkeyhint="done"/></td>
|
||||
<td>g/mol</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="text-align:right"> Nucleus/molecule </td>
|
||||
<td><Input type="text" id="ddd" size="10" value="2" enterkeyhint="done"/></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="text-align:right"> Num of nucleus per area </td>
|
||||
<td></td>
|
||||
<td>count/cm2</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="text-align:right"> Yield per sec </td>
|
||||
<td></td>
|
||||
<td>count/sec</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="text-align:right"> Spectroscopic factor </td>
|
||||
<td><Input type="text" id="SF" size="10" value="0.6" enterkeyhint="done"/></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="text-align:right"> Wanted Count </td>
|
||||
<td><Input type="text" id="wantedCount" size="10" value="1000" enterkeyhint="done"/></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="text-align:right"> stat. uncertainty </td>
|
||||
<td></td>
|
||||
<td>%</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="text-align:right"> Beam Time required </td>
|
||||
<td></td>
|
||||
<td>day</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
</body>
|
||||
|
||||
<script>
|
||||
|
||||
function toSci(xx, digi){
|
||||
//return xx.toExponential(digi).replace(/e\+?/, ' x 10^');
|
||||
return xx.toExponential(digi);
|
||||
}
|
||||
|
||||
function convert(type){
|
||||
let chargeState = document.getElementById('ChargeState').value;
|
||||
let attenuation = document.getElementById('att').value;
|
||||
let eee = 6241510000;
|
||||
|
||||
let table = document.getElementById('convertor');
|
||||
|
||||
if ( type == 1 ){
|
||||
let enA = document.getElementById('enA').value;
|
||||
let pnA = enA/chargeState;
|
||||
let pps = pnA*eee;
|
||||
var att = pps/attenuation;
|
||||
document.getElementById('pnA').value = pnA;
|
||||
document.getElementById('pps').value = toSci(pps,3);
|
||||
}
|
||||
|
||||
if ( type == 2 ){
|
||||
let pnA = document.getElementById('pnA').value;
|
||||
let enA = pnA*chargeState;
|
||||
let pps = pnA*eee;
|
||||
var att = pps/attenuation;
|
||||
document.getElementById('enA').value = enA;
|
||||
document.getElementById('pps').value = toSci(pps,3);
|
||||
}
|
||||
|
||||
if ( type == 3 ){
|
||||
let pps = document.getElementById('pps').value;
|
||||
let pnA = pps/eee;
|
||||
let enA = pnA*chargeState;
|
||||
var att = pps/attenuation;
|
||||
document.getElementById('enA').value = enA;
|
||||
document.getElementById('pnA').value = pnA;
|
||||
}
|
||||
|
||||
table.rows[3].cells[3].innerHTML = '<span style="color:#FF0000">' + toSci(att,3) + '</span>';
|
||||
|
||||
}
|
||||
|
||||
function yieldCal(type){
|
||||
let NA = 6.0221409e+23;
|
||||
let mb2cm = 1e-27;
|
||||
|
||||
let xsec = document.getElementById('Xsec').value;
|
||||
let beamPPS = document.getElementById('BeamPPS').value;
|
||||
let thickness = document.getElementById('thickness').value;
|
||||
let molar = document.getElementById('molar').value;
|
||||
let nParticle = document.getElementById('ddd').value;
|
||||
let SF = document.getElementById('SF').value;
|
||||
let wantedCount = document.getElementById('wantedCount').value;
|
||||
|
||||
let table = document.getElementById('yieldTable');
|
||||
|
||||
let nTarget = thickness * NA * nParticle / molar / 1e6;
|
||||
let yield = xsec * beamPPS * nTarget * mb2cm;
|
||||
|
||||
table.rows[5].cells[1].innerHTML = toSci(nTarget, 3);
|
||||
table.rows[6].cells[1].innerHTML = yield.toPrecision(4);
|
||||
|
||||
let error = Math.sqrt(wantedCount)/wantedCount*100;
|
||||
table.rows[9].cells[1].innerHTML = error.toPrecision(4);
|
||||
|
||||
let day = wantedCount / SF /yield /60/60/24;
|
||||
//table.rows[10].cells[1].innerHTML = day.toPrecision(4);
|
||||
table.rows[10].cells[1].innerHTML = '<span style="color:#FF0000">' + day.toPrecision(4) + '</span>';
|
||||
|
||||
}
|
||||
|
||||
convert(1);
|
||||
yieldCal(1);
|
||||
|
||||
|
||||
document.getElementById('enA').addEventListener('keypress',
|
||||
function(e){
|
||||
//alert( e.keyCode );
|
||||
if(e.keyCode == 13 ){
|
||||
convert(1);
|
||||
}
|
||||
}, false
|
||||
);
|
||||
|
||||
|
||||
document.getElementById('pnA').addEventListener('keypress',
|
||||
function(e){
|
||||
if(e.keyCode == 13){
|
||||
convert(2);
|
||||
}
|
||||
}, false
|
||||
);
|
||||
|
||||
|
||||
document.getElementById('pps').addEventListener('keypress',
|
||||
function(e){
|
||||
if(e.keyCode == 13){
|
||||
convert(3);
|
||||
}
|
||||
}, false
|
||||
);
|
||||
|
||||
document.getElementById('att').addEventListener('keypress',
|
||||
function(e){
|
||||
if(e.keyCode == 13){
|
||||
convert(1);
|
||||
}
|
||||
}, false
|
||||
);
|
||||
|
||||
|
||||
document.getElementById('ChargeState').addEventListener('keypress',
|
||||
function(e){
|
||||
if(e.keyCode == 13){
|
||||
convert(1);
|
||||
}
|
||||
}, false
|
||||
);
|
||||
|
||||
|
||||
document.getElementById('Xsec').addEventListener('keypress',
|
||||
function(e){
|
||||
if(e.keyCode == 13){
|
||||
yieldCal(0);
|
||||
}
|
||||
}, false
|
||||
);
|
||||
|
||||
document.getElementById('BeamPPS').addEventListener('keypress',
|
||||
function(e){
|
||||
if(e.keyCode == 13){
|
||||
yieldCal(1);
|
||||
}
|
||||
}, false
|
||||
);
|
||||
|
||||
document.getElementById('thickness').addEventListener('keypress',
|
||||
function(e){
|
||||
if(e.keyCode == 13){
|
||||
yieldCal(2);
|
||||
}
|
||||
}, false
|
||||
);
|
||||
|
||||
document.getElementById('molar').addEventListener('keypress',
|
||||
function(e){
|
||||
if(e.keyCode == 13){
|
||||
yieldCal(3);
|
||||
}
|
||||
}, false
|
||||
);
|
||||
|
||||
document.getElementById('ddd').addEventListener('keypress',
|
||||
function(e){
|
||||
if(e.keyCode == 13){
|
||||
yieldCal(4);
|
||||
}
|
||||
}, false
|
||||
);
|
||||
|
||||
document.getElementById('SF').addEventListener('keypress',
|
||||
function(e){
|
||||
if(e.keyCode == 13){
|
||||
yieldCal(5);
|
||||
}
|
||||
}, false
|
||||
);
|
||||
|
||||
document.getElementById('wantedCount').addEventListener('keypress',
|
||||
function(e){
|
||||
if(e.keyCode == 13){
|
||||
yieldCal(6);
|
||||
}
|
||||
}, false
|
||||
);
|
||||
</script>
|
||||
|
||||
|
||||
</html>
|
|
@ -1,113 +0,0 @@
|
|||
function addRow2(ele) {
|
||||
|
||||
let iRow = ele.closest('tr').sectionRowIndex;
|
||||
|
||||
let table = document.getElementById("ExTable2");
|
||||
let row = table.insertRow(iRow+1);
|
||||
row.innerHTML = '<td><input type="text" name="Ex" size="5" /></td> \
|
||||
<td><input type="text" name="Jpi" size="5"/></td> \
|
||||
<td><input type="text" name="Orb" size="6"/></td> \
|
||||
<td><button type="button" onclick="addRow(this)">Insert Ex</button></td> \
|
||||
<td><button type="button" onclick="deleteRow(this)">Remove Ex</button></td>';
|
||||
}
|
||||
|
||||
function deleteRow2(ele){
|
||||
let table = document.getElementById("ExTable2");
|
||||
let nRow = table.rows.length;
|
||||
let iRow = ele.closest('tr').sectionRowIndex;
|
||||
if ( nRow > 2){
|
||||
table.deleteRow(iRow);
|
||||
}
|
||||
}
|
||||
|
||||
let parity;
|
||||
function checkParity(){
|
||||
parity = 0;
|
||||
if( document.getElementById('pos').checked == true ) parity += 1;
|
||||
if( document.getElementById('neg').checked == true ) parity += 2;
|
||||
if( document.getElementById('unk').checked == true ) parity += 4;
|
||||
//console.log(parity);
|
||||
}
|
||||
|
||||
checkParity();
|
||||
|
||||
function addStates(){
|
||||
let AZ = document.getElementById('heavyName').value;
|
||||
let maxEx = document.getElementById('maxEx').value;
|
||||
let beamJpi = document.getElementById('beam_Jpi').value;
|
||||
|
||||
let str = 'get_nuclear_data.py?isotopes_name=' + AZ + '&maxEx='+maxEx;
|
||||
|
||||
let table = document.getElementById("ExTable");
|
||||
|
||||
const client = new XMLHttpRequest();
|
||||
|
||||
client.addEventListener('loadstart',
|
||||
function(e){
|
||||
document.getElementById('waiting').innerHTML = "wait....retrieving data from IAEA..";
|
||||
}
|
||||
);
|
||||
|
||||
client.addEventListener('error',
|
||||
function(e){
|
||||
document.getElementById('waiting').innerHTML = "Error.";
|
||||
}
|
||||
);
|
||||
|
||||
client.addEventListener('loadend',
|
||||
function(e){
|
||||
let result = client.responseText.split(/\r?\n/);
|
||||
|
||||
//clear table
|
||||
let nRow = table.rows.length;
|
||||
for( let j = nRow; j > 2; j--){
|
||||
table.deleteRow(j - 2);
|
||||
}
|
||||
|
||||
document.getElementById('waiting').innerHTML = "";
|
||||
let count = 0;
|
||||
|
||||
for( let i = 0; i < result.length; i++){
|
||||
if( i < 17 ) continue;
|
||||
if( result[i] == "</table>" ) break;
|
||||
|
||||
let kaka = result[i].split(' ').filter(n => n);
|
||||
|
||||
let ex = parseFloat(kaka[3])/1000.;
|
||||
let jpi = kaka[7]?.replace('(', '')?.replace(')', '');
|
||||
console.log(ex + ", " + jpi);
|
||||
|
||||
//check parity
|
||||
if( (((parity >> 2) & 1) != 1) && kaka[7].slice(-1) == ")" ) continue;
|
||||
if( (((parity >> 2) & 1) != 1) && jpi == "," ) continue;
|
||||
if( (((parity) & 1) != 1) && jpi.slice(-1) == "+" ) continue;
|
||||
if( (((parity >> 1) & 1) != 1) && jpi.slice(-1) == "-" ) continue;
|
||||
|
||||
count ++;
|
||||
nRow = table.rows.length;
|
||||
let row = table.insertRow(nRow-1);
|
||||
row.innerHTML = '<td><input type="text" name="Ex" size="5" value="' + ex.toFixed(3) + '"/></td> \
|
||||
<td><input type="text" name="Jpi" size="5" value="' + jpi + '"/></td> \
|
||||
<td><input type="text" name="Orb" size="6" /></td> \
|
||||
<td><button type="button" onclick="addRow(this)">Insert Ex</button></td> \
|
||||
<td><button type="button" onclick="deleteRow(this)">Remove Ex</button></td> \
|
||||
<td>'+ kaka[7] +'</td>';
|
||||
|
||||
}
|
||||
if( count == 0 ){
|
||||
document.getElementById('waiting').innerHTML = "no states found.";
|
||||
nRow = table.rows.length;
|
||||
let row = table.insertRow(nRow-1);
|
||||
row.innerHTML = '<td><input type="text" name="Ex" size="5" value="0"/></td> \
|
||||
<td><input type="text" name="Jpi" size="5" value="1/2+"/></td> \
|
||||
<td><input type="text" name="Orb" size="6" value="1s1/2"/></td> \
|
||||
<td><button type="button" onclick="addRow(this)">Insert Ex</button></td> \
|
||||
<td><button type="button" onclick="deleteRow(this)">Remove Ex</button></td>';
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
client.open('GET', str);
|
||||
client.send();
|
||||
|
||||
}
|
|
@ -1,529 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>DWBA and Monte Carlo Simulation</title>
|
||||
<link rel="icon" type="image/x-icon" href="logos/SOLARIS_favicon.png">
|
||||
</head>
|
||||
<style>
|
||||
body {
|
||||
font-family: Arial, Helvetica, sans-serif;
|
||||
background: #6DB33E;
|
||||
}
|
||||
</style>
|
||||
<body>
|
||||
|
||||
<h1>DWBA and Monte Carlo Simulation</h1>
|
||||
|
||||
<button onclick="GetClipBoard()">Paste Settings from clipboard</button>
|
||||
|
||||
<form action = "simpleInput.py" method = "POST" target = "uploaded">
|
||||
|
||||
<h3>Reaction: </h3>
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<td>Beam Energy</td>
|
||||
<td><input type = "text" name = "KEA" size="6" value="10" /></td>
|
||||
<td style="text-align:left">MeV/u</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Beam </td>
|
||||
<td><input type = "text" name = "beam_AZ" size="6" value="16O"/></td>
|
||||
<td style="text-align:right">J<sup>π</sup></td>
|
||||
<td><input type = "text" id="beam_Jpi" name = "beam_Jpi" size="5" value="0+"/><td>
|
||||
<td style="text-align:right">Ex:</td>
|
||||
<td><input type = "text" name = "beam_Ex" size="6" value="0.00"/></td>
|
||||
<td style="text-align:left">MeV</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Target</td>
|
||||
<td><input type = "text" name = "target_AZ" size="6" value="d"/></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Light recoil</td>
|
||||
<td><input type = "text" name = "lRecoil_AZ" size="6" value="p"/></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td> Number of events </td>
|
||||
<td><input type = "text" name = "numEvent" size="6" value="100000"/></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<h3>Detector:</h3>
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<input type="radio" name="SSType" value="HELIOS"/>HELIOS
|
||||
<br>
|
||||
<input type="radio" name="SSType" value="SOLARIS" checked="checked"/>SOLARIS
|
||||
<br>
|
||||
<input type="radio" name="SSType" value="ISS"/>ISS
|
||||
</tr>
|
||||
<tr>
|
||||
<td>B-field </td>
|
||||
<td><input type = "text" name = "BField" size="5" value="-2.5"/></td>
|
||||
<td style="text-align:left">T (minus sign = field point to upstream)</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Array Pos.</td>
|
||||
<td><input type = "text" name = "posArray" size="5" value="-100"/></td>
|
||||
<td style="text-align:left">mm (negative for upstream)</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Recoil Pos.</td>
|
||||
<td><input type = "text" name = "posRecoil" size="5" value="500"/></td>
|
||||
<td style="text-align:left">mm (negative for upstream)</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<h3>DWBA and E<sub>x</sub> List:</h3>
|
||||
|
||||
<p><b style="color:red;">For 2-nucleon transfer</b>, <b>Orbital</b> take the form NL=X, where N is number of node, X is momentum number. n and L are related by Σ<sub>i</sub> (2n<sub>i</sub>+l<sub>i</sub>) = 2N + X + 2n + l, where n<sub>i</sub> and l<sub>i</sub> are the principle number and orbital angular momentum of the each transfered nucleon, and n and l are the internal quanta of the 2-nucleon. e.g. (t,p) reaction to 0f orbtial, the left-hand side would be n<sub>i</sub> = 0 and l<sub>i</sub> = 3 and the sum is 3+3 = 6 = 2N + X + 2n+l. Assume n = l = 0, we have 6 = 2N+L. Thus, 3L=0, 2L=2,1L=4, 0L=6. </p>
|
||||
|
||||
TODO: guess the orbital
|
||||
<br>
|
||||
<input type="checkbox" id="pos" onclick="checkParity()" checked/>Positive parity</td>
|
||||
<input type="checkbox" id="neg" onclick="checkParity()" checked/>Negative parity</td>
|
||||
<input type="checkbox" id="unk" onclick="checkParity()" checked/>Unknown parity</td>
|
||||
<br>
|
||||
<button type="button" onclick="addStates()">Add known states</button>
|
||||
Isotope: <input type="text" id="AZ" size="5" value="17O"/>
|
||||
Max Ex: <input type="text" id="maxEx" size="5" value="5"/>MeV
|
||||
|
||||
<p id='waiting'></p>
|
||||
|
||||
<table id="ExTable">
|
||||
<tr>
|
||||
<td><b> E<sub>x</sub> [MeV] </b></td>
|
||||
<td><b> J<sup>π</sup></b></td>
|
||||
<td><b> Orbital </b></td>
|
||||
</tr>
|
||||
</tr>
|
||||
<td><input type="text" name="Ex" size="5" value="0"/></td>
|
||||
<td><input type="text" name="Jpi" size="5" value="3/2+"/></td>
|
||||
<td><input type="text" name="Orb" size="6" value="0d3/2"/></td>
|
||||
<td><button type="button" onclick="addRow(this)">Insert Ex</button></td>
|
||||
<td><button type="button" onclick="deleteRow(this)">Remove Ex</button></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td><button type="button" onclick="copyEx()">Copy Ex</button></td>
|
||||
<td><button type="button" onclick="pasteEx()"> Paste Ex </button></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<p></p>
|
||||
<input type="checkbox" name="DWBA" value="On"/>Cal. DWBA
|
||||
<!--<input type="checkbox" name="onlyDWBA" value="On"/>ONLY Cal. DWBA (tetsing)-->
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<td>Incoming Channel</td>
|
||||
<td>
|
||||
<select name="op1">
|
||||
<option value="A" selected>D | An & Cai (2006) E < 183, 12 < A < 238</option>
|
||||
<option value="H">D | Han, Shi, & Shen (2006) E < 200, 12 < A < 209</option>
|
||||
<option value="B">D | Bojowald et al. (1988) 50 < E < 80, 27 < A < 208</option>
|
||||
<option value="D">D | Daehnick, Childs, Vrcelj (1980) 11.8 < E < 80, 27 < A < 238 (REL) </option>
|
||||
<option value="C">D | Daehnick, Childs, Vrcelj (1980) 11.8 < E < 80, 27 < A < 238 (NON-REL) </option>
|
||||
<option value="L">D | Lohr and Haeberli (1974) 9 < E < 13, 40 < A </option>
|
||||
<option value="Q">D | Perey and Perey (1963) 12 < E < 25, 40 < A </option>
|
||||
<option value="Z">D | Zhang, Pang, Lou (2016) 5 < E < 170, A < 18, spe 6-7Li </option>
|
||||
<option value="K">P | Koning & Delaroche (2009) E < 200, 24 < A < 209 | Iso.Dep.</option>
|
||||
<option value="V">P | Varner et al. (1991) 16 < E < 65, 4 < A < 209</option>
|
||||
<option value="M">P | Menet et al. (1971) 30 < E < 60, 40 < A </option>
|
||||
<option value="G">P | Becchetti and Greenlees (1969) E < 50, 40 < A </option>
|
||||
<option value="P">P | Perey (1963) E < 20, 30 < A < 100 </option>
|
||||
<option value="x">A=3 | Xu, Guo, Han, & Shen (2011) E < 250, 20 < A < 209 </option>
|
||||
<option value="l">A=3 | Liang, Li, & Cai (2009) E < 270, All masses </option>
|
||||
<option value="p">A=3 | Pang et al. (2009) all E, all masses, Iso. Dep. </option>
|
||||
<option value="c">A=3 | Li, Liang, Cai (2007), E < 40, 48 < A < 232, Tritons </option>
|
||||
<option value="t">A=3 | Trost et al. (1987) 10 < E < 220, 10 < A < 208 </option>
|
||||
<option value="h">A=3 | Hyakutake et al. (1980) 90 < E < 120, About 58 < A < 92 </option>
|
||||
<option value="b">A=3 | Becchetti and Greenlees (1971), E < 40, 40 < A, Iso. Dep. </option>
|
||||
<option value="s">A=4 | Su & Han (2015) E < 398, 20 < A < 209 </option>
|
||||
<option value="a">A=4 | Avrigeanu et al. (2009) </option>
|
||||
<option value="f">A=4 | Bassani and Picard (1969) 24 < E < 31, A = 90 </option>
|
||||
</select>
|
||||
<td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Outgoing Channel</td>
|
||||
<td>
|
||||
<select name="op2">
|
||||
<option value="A">D | An & Cai (2006) E < 183, 12 < A < 238</option>
|
||||
<option value="H">D | Han, Shi, & Shen (2006) E < 200, 12 < A < 209</option>
|
||||
<option value="B">D | Bojowald et al. (1988) 50 < E < 80, 27 < A < 208</option>
|
||||
<option value="D">D | Daehnick, Childs, Vrcelj (1980) 11.8 < E < 80, 27 < A < 238 (REL) </option>
|
||||
<option value="C">D | Daehnick, Childs, Vrcelj (1980) 11.8 < E < 80, 27 < A < 238 (NON-REL) </option>
|
||||
<option value="L">D | Lohr and Haeberli (1974) 9 < E < 13, 40 < A </option>
|
||||
<option value="Q">D | Perey and Perey (1963) 12 < E < 25, 40 < A </option>
|
||||
<option value="Z">D | Zhang, Pang, Lou (2016) 5 < E < 170, A < 18, spe 6-7Li </option>
|
||||
<option value="K" selected>P | Koning & Delaroche (2009) E < 200, 24 < A < 209, Iso.Dep.</option>
|
||||
<option value="V">P | Varner et al. (1991) 16 < E < 65, 4 < A < 209</option>
|
||||
<option value="M">P | Menet et al. (1971) 30 < E < 60, 40 < A </option>
|
||||
<option value="G">P | Becchetti and Greenlees (1969) E < 50, 40 < A </option>
|
||||
<option value="P">P | Perey (1963) E < 20, 30 < A < 100 </option>
|
||||
<option value="x">A=3 | Xu, Guo, Han, & Shen (2011) E < 250, 20 < A < 209 </option>
|
||||
<option value="l">A=3 | Liang, Li, & Cai (2009) E < 270, All masses </option>
|
||||
<option value="p">A=3 | Pang et al. (2009) all E | all masses, Iso. Dep. </option>
|
||||
<option value="c">A=3 | Li, Liang, Cai (2007), E < 40, 48 < A < 232, Tritons </option>
|
||||
<option value="t">A=3 | Trost et al. (1987) 10 < E < 220, 10 < A < 208 </option>
|
||||
<option value="h">A=3 | Hyakutake et al. (1980) 90 < E < 120, About 58 < A < 92 </option>
|
||||
<option value="b">A=3 | Becchetti and Greenlees (1971), E < 40, 40 < A, Iso. Dep. </option>
|
||||
<option value="s">A=4 | Su & Han (2015) E < 398, 20 < A < 209 </option>
|
||||
<option value="a">A=4 | Avrigeanu et al. (2009) </option>
|
||||
<option value="f">A=4 | Bassani and Picard (1969) 24 < E < 31, A = 90 </option>
|
||||
</select>
|
||||
<td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<input type="checkbox" name="onlyDWBA" value="On"/>Only DWBA and Don't Sim. Angle range (for only DWBA)
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Min [deg]: </td>
|
||||
<td><input type = "text" name = "minAng" size="6" value="0" /></td>
|
||||
<td>Max [deg]: </td>
|
||||
<td><input type = "text" name = "maxAng" size="6" value="90"/></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<h3> Plot config:</h3>
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<td><input type="checkbox" name="plot" value="pEZ" checked/>E vs Z</td>
|
||||
<td><input type="checkbox" name="plot" value="pExCal" checked/>Ex (cal.)</td>
|
||||
<td><input type="checkbox" name="plot" value="pThetaCM" checked/>ThetaCM</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><input type="checkbox" name="plot" value="pThetaCM_Z" checked/>ThetaCM vs Z</td>
|
||||
<td><input type="checkbox" name="plot" value="pRecoilXY" checked/>Recoil X vs Y</td>
|
||||
<td><input type="checkbox" name="plot" value="pRecoilRThetaCM"/>Recoil-R vs ThetaCM</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><input type="checkbox" name="plot" value="pRecoilRZ"/>Recoil R vs Z</td>
|
||||
<td><input type="checkbox" name="plot" value="pTDiffZ"/>Time diff vs Z</td>
|
||||
<td><input type="checkbox" name="plot" value="pArrayXY"/>Array X vs Y</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<p></p>
|
||||
|
||||
<input type="checkbox" name="gate" value="hit==1" checked/>Array Hit<br>
|
||||
<input type="checkbox" name="gate" value="loop<=1" checked/>Loop = 1<br>
|
||||
<input type="checkbox" name="gate" value="thetaCM>10" checked/> ThetaCM > 10 deg<br>
|
||||
|
||||
<p></p>
|
||||
|
||||
<input type = "submit" value = "Run DWBA and Simulation" style="width:200px;height:60px;" formtarget="_blank"/>
|
||||
</form>
|
||||
|
||||
<hr style="height:4px;background-color:#F7CF3C; border-style:none; border-width:none">
|
||||
|
||||
<h2>Advanced control</h2>
|
||||
|
||||
<!-- ////////////////////////////////////////// -->
|
||||
<table>
|
||||
<tr>
|
||||
<td>Download Sample files:</td>
|
||||
<td style="text-align:left">
|
||||
<a href="sample_files/reactionConfig_sample.txt" download="reactionConfig.txt">Reaction File</a>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td></td>
|
||||
<td style="text-align:left">
|
||||
<a href="sample_files/detectorGeo_SOLARIS_sample.txt" download="detectorGeo_SOLAIRS.txt">DetectorGeo (SOLARIS) File</a>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td></td>
|
||||
<td style="text-align:left">
|
||||
<a href="sample_files/detectorGeo_HELIOS_sample.txt" download="detectorGeo_HELIOS.txt">DetectorGeo (HELIOS) File</a>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td></td>
|
||||
<td style="text-align:left">
|
||||
<a href="sample_files/Ex_sample.txt" download="Ex.txt">Ex File</a>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td></td>
|
||||
<td style="text-align:left">
|
||||
<a href="sample_files/DWBA_sample.txt" download="DWBA">DWBA File</a>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td></td>
|
||||
<td style="text-align:left">
|
||||
<a href="sample_files/PlotConfig_sample.txt" download="PlotConfig.txt">Plot Config File</a>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<p></p><!-- ////////////////////////////////////////// -->
|
||||
<form enctype = "multipart/form-data" action = "Simulation_gateway.py" method = "post" target="uploaded">
|
||||
<table>
|
||||
<tr>
|
||||
<td style="text-align:right" width="200">Reaction File </td>
|
||||
<td><input type = "file" name = "filename1" /> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="text-align:right" width="200">DetectorGeo File </th>
|
||||
<td><input type = "file" name = "filename2" /> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="text-align:right" width="200">Ex File </th>
|
||||
<td><input type = "file" name = "filename3" /> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="text-align:right" width="200">DWBA File ^ </th>
|
||||
<td><input type = "file" name = "filename4" /> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="text-align:right" width="200">*.in File ^ </th>
|
||||
<td><input type = "file" name = "filename4a" /> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="text-align:right" width="200">Plot Config File # </th>
|
||||
<td><input type = "file" name = "filename5" /> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>^ can be alone <br># can be omitted</th>
|
||||
<td><input type = "submit" value = "Upload & Run Simulation" style="height:50px; width:200px" formtarget="_blank"/> </td>
|
||||
</tr>
|
||||
</table>
|
||||
</form>
|
||||
|
||||
<ul>
|
||||
<li>File name can be customized.</li>
|
||||
<li>For kinematic simulation, only the reactionConfig.txt, detectorGeo.txt, and Ex.txt are needed.</li>
|
||||
<li>For DWBA calculation, only the DWBA file is needed.</li>
|
||||
<li>If reactionConfig.txt, detectorGeo.txt, and DWBA file are presented, will do DWBA and use the result for simulation.</li>
|
||||
<li>When the DWBA file is presented, the kinematic simulation will use the DWBA result and also the excitation energy. i.e. the user provide Ex.txt will not be used.</li>
|
||||
<li>User can use a customs in File for DWBA calculation. Once the in File exist, it ignores the DWBA file.</li>
|
||||
<li>To change DWBA angular range, download the in file, edit it. But becareful, DWBA for kinematic simulation must be 0 -180 deg.</li>
|
||||
</ul>
|
||||
|
||||
<hr style="height:4px;background-color:#F7CF3C; border-style:none; border-width:none">
|
||||
The source code for calculation can be found in <a href="https://github.com/calemhoffman/digios/tree/master/analysis/Cleopatra/Transfer.C" target="_blank">Here</a>
|
||||
|
||||
</body>
|
||||
|
||||
|
||||
<script>
|
||||
|
||||
function GetClipBoard(){
|
||||
navigator.clipboard.readText().then(
|
||||
function(result){
|
||||
//console.log(result);
|
||||
if( result.substring(0,16) == "====HELIOSMATICS" ){
|
||||
let haha = result.substring(17).split(', ');
|
||||
console.log(haha);
|
||||
//alert(haha);
|
||||
document.getElementsByName('beam_AZ')[0].value = haha[0];
|
||||
document.getElementsByName('beam_Ex')[0].value = haha[1];
|
||||
document.getElementsByName('target_AZ')[0].value = haha[2];
|
||||
document.getElementsByName('lRecoil_AZ')[0].value = haha[3];
|
||||
document.getElementsByName('KEA')[0].value = haha[5];
|
||||
document.getElementsByName('BField')[0].value = haha[4];
|
||||
document.getElementsByName('posArray')[0].value = haha[6];
|
||||
document.getElementsByName('posRecoil')[0].value = haha[7];
|
||||
|
||||
document.getElementById('AZ').value = haha[8];
|
||||
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
function copyEx(){
|
||||
let inputs = document.getElementsByTagName("input");
|
||||
let copyText = "====ExList|";
|
||||
for(let i = 0; i < inputs.length; i++){
|
||||
if( inputs[i].type == 'text'){
|
||||
if( inputs[i].name == "Ex" || inputs[i].name == "Jpi" || inputs[i].name == "Orb" ){
|
||||
//if( inputs[i].value == "" ) continue;
|
||||
copyText += inputs[i].value;
|
||||
if(inputs[i].name == "Orb") {
|
||||
copyText += "|";
|
||||
}else{
|
||||
copyText += ",";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//console.log(copyText);
|
||||
|
||||
navigator.clipboard.writeText(copyText).then(
|
||||
() => {
|
||||
alert('Ex are copied to clipboard.\n' + copyText);
|
||||
}).catch(
|
||||
() =>{
|
||||
alert('Cannot copy.');
|
||||
});
|
||||
}
|
||||
|
||||
function pasteEx(){
|
||||
navigator.clipboard.readText().then(
|
||||
function(result){
|
||||
//console.log(result);
|
||||
if( result.substring(0,10) == "====ExList" ){
|
||||
let haha = result.substring(11).split('|');
|
||||
//console.log(haha);
|
||||
let table = document.getElementById("ExTable");
|
||||
let nRow = table.rows.length;
|
||||
//console.log(nRow);
|
||||
//remove all Row except the 1st
|
||||
for( let i = nRow; i > 2; i--){
|
||||
table.deleteRow(i - 2);
|
||||
}
|
||||
|
||||
for( let i = 0; i < haha.length; i++){
|
||||
if( haha[i] == "" ) continue;
|
||||
|
||||
let kaka = haha[i].split(',');
|
||||
//console.log(kaka);
|
||||
|
||||
nRow = table.rows.length;
|
||||
let row = table.insertRow(nRow-1);
|
||||
row.innerHTML = '<td><input type="text" name="Ex" size="5" value="' + kaka[0] + '"/></td> \
|
||||
<td><input type="text" name="Jpi" size="5" value="' + kaka[1] + '"/></td> \
|
||||
<td><input type="text" name="Orb" size="6" value="' + kaka[2] + '"/></td>\
|
||||
<td><button type="button" onclick="addRow(this)">Insert Ex</button></td> \
|
||||
<td><button type="button" onclick="deleteRow(this)">Remove Ex</button></td>';
|
||||
}
|
||||
|
||||
}else{
|
||||
alert("Setting not fond in clipboard.");
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
let parity;
|
||||
function checkParity(){
|
||||
parity = 0;
|
||||
if( document.getElementById('pos').checked == true ) parity += 1;
|
||||
if( document.getElementById('neg').checked == true ) parity += 2;
|
||||
if( document.getElementById('unk').checked == true ) parity += 4;
|
||||
//console.log(parity);
|
||||
}
|
||||
|
||||
checkParity();
|
||||
|
||||
function addStates(){
|
||||
let AZ = document.getElementById('AZ').value;
|
||||
let maxEx = document.getElementById('maxEx').value;
|
||||
let beamJpi = document.getElementById('beam_Jpi').value;
|
||||
|
||||
let str = 'get_nuclear_data.py?isotopes_name=' + AZ + '&maxEx='+maxEx;
|
||||
|
||||
let table = document.getElementById("ExTable");
|
||||
|
||||
const client = new XMLHttpRequest();
|
||||
|
||||
client.addEventListener('loadstart',
|
||||
function(e){
|
||||
document.getElementById('waiting').innerHTML = "wait....retrieving data from IAEA..";
|
||||
}
|
||||
);
|
||||
|
||||
client.addEventListener('error',
|
||||
function(e){
|
||||
document.getElementById('waiting').innerHTML = "Error.";
|
||||
}
|
||||
);
|
||||
|
||||
client.addEventListener('loadend',
|
||||
function(e){
|
||||
let result = client.responseText.split(/\r?\n/);
|
||||
|
||||
//clear table
|
||||
let nRow = table.rows.length;
|
||||
for( let j = nRow; j > 2; j--){
|
||||
table.deleteRow(j - 2);
|
||||
}
|
||||
|
||||
document.getElementById('waiting').innerHTML = "";
|
||||
let count = 0;
|
||||
|
||||
for( let i = 0; i < result.length; i++){
|
||||
if( i < 17 ) continue;
|
||||
if( result[i] == "</table>" ) break;
|
||||
|
||||
let kaka = result[i].split(' ').filter(n => n);
|
||||
|
||||
let ex = parseFloat(kaka[3])/1000.;
|
||||
let jpi = kaka[7]?.replace('(', '')?.replace(')', '');
|
||||
console.log(ex + ", " + jpi);
|
||||
|
||||
//check parity
|
||||
if( (((parity >> 2) & 1) != 1) && kaka[7].slice(-1) == ")" ) continue;
|
||||
if( (((parity >> 2) & 1) != 1) && jpi == "," ) continue;
|
||||
if( (((parity) & 1) != 1) && jpi.slice(-1) == "+" ) continue;
|
||||
if( (((parity >> 1) & 1) != 1) && jpi.slice(-1) == "-" ) continue;
|
||||
|
||||
count ++;
|
||||
nRow = table.rows.length;
|
||||
let row = table.insertRow(nRow-1);
|
||||
row.innerHTML = '<td><input type="text" name="Ex" size="5" value="' + ex.toFixed(3) + '"/></td> \
|
||||
<td><input type="text" name="Jpi" size="5" value="' + jpi + '"/></td> \
|
||||
<td><input type="text" name="Orb" size="6" /></td> \
|
||||
<td><button type="button" onclick="addRow(this)">Insert Ex</button></td> \
|
||||
<td><button type="button" onclick="deleteRow(this)">Remove Ex</button></td> \
|
||||
<td>'+ kaka[7] +'</td>';
|
||||
|
||||
}
|
||||
if( count == 0 ){
|
||||
document.getElementById('waiting').innerHTML = "no states found.";
|
||||
nRow = table.rows.length;
|
||||
let row = table.insertRow(nRow-1);
|
||||
row.innerHTML = '<td><input type="text" name="Ex" size="5" value="0"/></td> \
|
||||
<td><input type="text" name="Jpi" size="5" value="1/2+"/></td> \
|
||||
<td><input type="text" name="Orb" size="6" value="1s1/2"/></td> \
|
||||
<td><button type="button" onclick="addRow(this)">Insert Ex</button></td> \
|
||||
<td><button type="button" onclick="deleteRow(this)">Remove Ex</button></td>';
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
client.open('GET', str);
|
||||
client.send();
|
||||
|
||||
}
|
||||
|
||||
//document.getElementById("ExTable").find('tr').click( () => {alert( $this.index);} );
|
||||
|
||||
function addRow(ele) {
|
||||
|
||||
let iRow = ele.closest('tr').sectionRowIndex;
|
||||
|
||||
let table = document.getElementById("ExTable");
|
||||
let row = table.insertRow(iRow+1);
|
||||
row.innerHTML = '<td><input type="text" name="Ex" size="5" /></td> \
|
||||
<td><input type="text" name="Jpi" size="5"/></td> \
|
||||
<td><input type="text" name="Orb" size="6"/></td> \
|
||||
<td><button type="button" onclick="addRow(this)">Insert Ex</button></td> \
|
||||
<td><button type="button" onclick="deleteRow(this)">Remove Ex</button></td>';
|
||||
}
|
||||
|
||||
function deleteRow(ele){
|
||||
let table = document.getElementById("ExTable");
|
||||
let nRow = table.rows.length;
|
||||
let iRow = ele.closest('tr').sectionRowIndex;
|
||||
if ( nRow > 3){
|
||||
table.deleteRow(iRow);
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
</html>
|
930
armory/AnalysisLib.h
Normal file
|
@ -0,0 +1,930 @@
|
|||
#ifndef ANALYSIS_LIB_H
|
||||
#define ANALYSIS_LIB_H
|
||||
|
||||
#include <cstdio>
|
||||
#include <vector>
|
||||
#include <fstream>
|
||||
#include <string>
|
||||
|
||||
#include <TMacro.h>
|
||||
#include <TList.h>
|
||||
#include <TFile.h>
|
||||
#include <TMath.h>
|
||||
#include <TObjArray.h>
|
||||
#include <TCutG.h>
|
||||
|
||||
namespace AnalysisLib {
|
||||
|
||||
std::vector<std::string> SplitStr(std::string tempLine, std::string splitter, int shift = 0){
|
||||
|
||||
std::vector<std::string> output;
|
||||
|
||||
size_t pos;
|
||||
do{
|
||||
pos = tempLine.find(splitter); /// fine splitter
|
||||
if( pos == 0 ){ ///check if it is splitter again
|
||||
tempLine = tempLine.substr(pos+1);
|
||||
continue;
|
||||
}
|
||||
|
||||
std::string secStr;
|
||||
if( pos == std::string::npos ){
|
||||
secStr = tempLine;
|
||||
}else{
|
||||
secStr = tempLine.substr(0, pos+shift);
|
||||
tempLine = tempLine.substr(pos+shift);
|
||||
}
|
||||
|
||||
///check if secStr is begin with space
|
||||
while( secStr.substr(0, 1) == " ") secStr = secStr.substr(1);
|
||||
|
||||
///check if secStr is end with space
|
||||
while( secStr.back() == ' ') secStr = secStr.substr(0, secStr.size()-1);
|
||||
|
||||
output.push_back(secStr);
|
||||
///printf(" |%s---\n", secStr.c_str());
|
||||
|
||||
}while(pos != std::string::npos );
|
||||
|
||||
return output;
|
||||
};
|
||||
|
||||
struct Array{
|
||||
|
||||
double detPerpDist; /// distance from axis
|
||||
double detWidth; /// width
|
||||
double detLength; /// length
|
||||
double blocker;
|
||||
double firstPos; /// meter
|
||||
double eSigma; /// intrinsic energy resolution MeV
|
||||
double zSigma; /// intrinsic position resolution mm
|
||||
bool detFaceOut; ///detector_facing_Out_or_In
|
||||
std::vector<double> pos; /// near position in meter
|
||||
int nDet, mDet; /// nDet = number of different pos, mDet, number of same pos
|
||||
std::vector<double> detPos; ///absolute position of detector
|
||||
|
||||
double zMin, zMax;
|
||||
|
||||
void DeduceAbsolutePos(){
|
||||
nDet = pos.size();
|
||||
detPos.clear();
|
||||
|
||||
for(int id = 0; id < nDet; id++){
|
||||
if( firstPos > 0 ) detPos.push_back(firstPos + pos[id]);
|
||||
if( firstPos < 0 ) detPos.push_back(firstPos - pos[nDet - 1 - id]);
|
||||
///printf("%d | %f, %f \n", id, pos[id], detPos[id]);
|
||||
}
|
||||
|
||||
zMin = TMath::Min(detPos.front(), detPos.back()) - (firstPos < 0 ? detLength : 0);
|
||||
zMax = TMath::Max(detPos.front(), detPos.back()) + (firstPos > 0 ? detLength : 0);
|
||||
}
|
||||
|
||||
void PrintArray(){
|
||||
for(int i = 0; i < nDet ; i++){
|
||||
if( firstPos > 0 ){
|
||||
printf("%d, %8.2f mm - %8.2f mm \n", i, detPos[i], detPos[i] + detLength);
|
||||
}else{
|
||||
printf("%d, %8.2f mm - %8.2f mm \n", i, detPos[i] - detLength , detPos[i]);
|
||||
}
|
||||
}
|
||||
|
||||
printf(" Blocker Position: %8.2f mm \n", firstPos > 0 ? firstPos - blocker : firstPos + blocker );
|
||||
printf(" First Position: %8.2f mm \n", firstPos);
|
||||
printf(" number of det : %d x %d \n", mDet, nDet);
|
||||
printf(" detector facing : %s\n", detFaceOut ? "Out" : "In");
|
||||
printf(" energy resol.: %f MeV\n", eSigma);
|
||||
printf(" pos-Z resol.: %f mm \n", zSigma);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
struct DetGeo{
|
||||
|
||||
double Bfield; /// T
|
||||
int BfieldSign ; /// sign of B-field
|
||||
double BfieldTheta; /// rad, 0 = z-axis, pi/2 = y axis, pi = -z axis
|
||||
double bore; /// bore , mm
|
||||
|
||||
double recoilPos; /// recoil, downstream
|
||||
double recoilInnerRadius; /// radius recoil inner
|
||||
double recoilOuterRadius; /// radius recoil outter
|
||||
|
||||
double recoilPos1, recoilPos2; /// imaginary recoils
|
||||
|
||||
double elumPos1, elumPos2; /// imaginary elum, only sensitive to light recoil
|
||||
|
||||
//===================1st array
|
||||
Array array1;
|
||||
|
||||
//==================2nd array
|
||||
bool use2ndArray;
|
||||
Array array2;
|
||||
|
||||
double zMin, zMax; /// range of detectors
|
||||
bool isCoincidentWithRecoil;
|
||||
|
||||
};
|
||||
|
||||
struct ReactionConfig{
|
||||
|
||||
int beamA;
|
||||
int beamZ;
|
||||
int targetA;
|
||||
int targetZ;
|
||||
int recoilLightA;
|
||||
int recoilLightZ;
|
||||
int recoilHeavyA;
|
||||
int recoilHeavyZ;
|
||||
float beamEnergy; ///MeV/u
|
||||
float beamEnergySigma; ///beam-energy_sigma_in_MeV/u
|
||||
float beamAngle; ///beam-angle_in_mrad
|
||||
float beamAngleSigma; ///beam-emittance_in_mrad
|
||||
float beamX; ///x_offset_of_Beam_in_mm
|
||||
float beamY; ///y_offset_of_Beam_in_mm
|
||||
int numEvents; ///number_of_Event_being_generated
|
||||
bool isTargetScattering; ///isTargetScattering
|
||||
float targetDensity; ///target_density_in_g/cm3
|
||||
float targetThickness; ///targetThickness_in_cm
|
||||
std::string beamStoppingPowerFile; ///stopping_power_for_beam
|
||||
std::string recoilLightStoppingPowerFile; ///stopping_power_for_light_recoil
|
||||
std::string recoilHeavyStoppingPowerFile; ///stopping_power_for_heavy_recoil
|
||||
bool isDecay; ///isDacay
|
||||
int heavyDecayA; ///decayNucleus_A
|
||||
int heavyDecayZ; ///decayNucleus_Z
|
||||
bool isRedo; ///isReDo
|
||||
std::vector<float> beamEx; ///excitation_energy_of_A[MeV]
|
||||
|
||||
};
|
||||
|
||||
///Using TMacro to load the detectorGeo frist,
|
||||
///this indrect method is good for loading detectorGeo from TMacro in root file
|
||||
DetGeo LoadDetectorGeo(TMacro * macro){
|
||||
|
||||
DetGeo detGeo;
|
||||
|
||||
if( macro == NULL ) return detGeo;
|
||||
|
||||
TList * haha = macro->GetListOfLines();
|
||||
int numLine = (haha)->GetSize();
|
||||
|
||||
detGeo.array1.pos.clear();
|
||||
detGeo.array2.pos.clear();
|
||||
detGeo.use2ndArray = false;
|
||||
|
||||
int detFlag = 0;
|
||||
int detLine = 0;
|
||||
|
||||
for( int i = 0 ; i < numLine; i++){
|
||||
|
||||
std::vector<std::string> str = SplitStr(macro->GetListOfLines()->At(i)->GetName(), " ");
|
||||
|
||||
//printf("%3d | %s\n", i, str[0].c_str());
|
||||
|
||||
if( str[0].find("####") != std::string::npos ) break;
|
||||
if( str[0].find("#===") != std::string::npos ) {
|
||||
detFlag ++;
|
||||
detLine = 0;
|
||||
continue;;
|
||||
}
|
||||
|
||||
if( detFlag == 0 ){
|
||||
if ( i == 0 ) {
|
||||
detGeo.Bfield = atof(str[0].c_str());
|
||||
detGeo.BfieldSign = detGeo.Bfield > 0 ? 1: -1;
|
||||
}
|
||||
if ( i == 1 ) detGeo.BfieldTheta = atof(str[0].c_str());
|
||||
if ( i == 2 ) detGeo.bore = atof(str[0].c_str());
|
||||
if ( i == 3 ) detGeo.recoilPos = atof(str[0].c_str());
|
||||
if ( i == 4 ) detGeo.recoilInnerRadius = atof(str[0].c_str());
|
||||
if ( i == 5 ) detGeo.recoilOuterRadius = atof(str[0].c_str());
|
||||
if ( i == 6 ) detGeo.isCoincidentWithRecoil = str[0] == "false" ? false: true;
|
||||
if ( i == 7 ) detGeo.recoilPos1 = atof(str[0].c_str());
|
||||
if ( i == 8 ) detGeo.recoilPos2 = atof(str[0].c_str());
|
||||
if ( i == 9 ) detGeo.elumPos1 = atof(str[0].c_str());
|
||||
if ( i == 10 ) detGeo.elumPos2 = atof(str[0].c_str());
|
||||
}
|
||||
|
||||
if( detFlag == 1){
|
||||
if ( detLine == 0 ) detGeo.array1.detPerpDist = atof(str[0].c_str());
|
||||
if ( detLine == 1 ) detGeo.array1.detWidth = atof(str[0].c_str());
|
||||
if ( detLine == 2 ) detGeo.array1.detLength = atof(str[0].c_str());
|
||||
if ( detLine == 3 ) detGeo.array1.blocker = atof(str[0].c_str());
|
||||
if ( detLine == 4 ) detGeo.array1.firstPos = atof(str[0].c_str());
|
||||
if ( detLine == 5 ) detGeo.array1.eSigma = atof(str[0].c_str());
|
||||
if ( detLine == 6 ) detGeo.array1.zSigma = atof(str[0].c_str());
|
||||
if ( detLine == 7 ) detGeo.array1.detFaceOut = str[0] == "Out" ? true : false;
|
||||
if ( detLine == 8 ) detGeo.array1.mDet = atoi(str[0].c_str());
|
||||
if ( detLine >= 9 ) (detGeo.array1.pos).push_back(atof(str[0].c_str()));
|
||||
detLine ++;
|
||||
}
|
||||
|
||||
if( detFlag == 2){
|
||||
if ( detLine == 0 ) detGeo.use2ndArray = str[0] == "true" ? true : false;
|
||||
if ( detLine == 1 ) detGeo.array2.detPerpDist = atof(str[0].c_str());
|
||||
if ( detLine == 2 ) detGeo.array2.detWidth = atof(str[0].c_str());
|
||||
if ( detLine == 3 ) detGeo.array2.detLength = atof(str[0].c_str());
|
||||
if ( detLine == 4 ) detGeo.array2.blocker = atof(str[0].c_str());
|
||||
if ( detLine == 5 ) detGeo.array2.firstPos = atof(str[0].c_str());
|
||||
if ( detLine == 6 ) detGeo.array2.eSigma = atof(str[0].c_str());
|
||||
if ( detLine == 7 ) detGeo.array2.zSigma = atof(str[0].c_str());
|
||||
if ( detLine == 8 ) detGeo.array2.detFaceOut = str[0] == "Out" ? true : false;
|
||||
if ( detLine == 9 ) detGeo.array2.mDet = atoi(str[0].c_str());
|
||||
if ( detLine >= 10 ) (detGeo.array2.pos).push_back(atof(str[0].c_str()));
|
||||
detLine ++;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
detGeo.array1.DeduceAbsolutePos();
|
||||
|
||||
detGeo.zMin = detGeo.array1.zMin;
|
||||
detGeo.zMax = detGeo.array1.zMax;
|
||||
|
||||
if( detGeo.use2ndArray) {
|
||||
detGeo.array2.DeduceAbsolutePos();
|
||||
|
||||
detGeo.zMin = TMath::Min(detGeo.array1.zMin, detGeo.array2.zMin);
|
||||
detGeo.zMax = TMath::Min(detGeo.array1.zMax, detGeo.array2.zMax);
|
||||
}
|
||||
|
||||
return detGeo;
|
||||
}
|
||||
|
||||
void PrintDetGeo(DetGeo detGeo, bool printAll = true){
|
||||
|
||||
printf("=====================================================\n");
|
||||
printf(" B-field: %8.2f T, Theta : %6.2f deg \n", detGeo.Bfield, detGeo.BfieldTheta);
|
||||
if( detGeo.BfieldTheta != 0.0 ) {
|
||||
printf(" +---- field angle != 0 is not supported!!! \n");
|
||||
}
|
||||
printf(" Recoil detector pos: %8.2f mm, radius: %6.2f - %6.2f mm \n", detGeo.recoilPos, detGeo.recoilInnerRadius, detGeo.recoilOuterRadius);
|
||||
if( printAll ){
|
||||
printf("------------------------------------- Detector Position \n");
|
||||
detGeo.array1.PrintArray();
|
||||
|
||||
if( detGeo.use2ndArray){
|
||||
printf("--------------------------------- 2nd Detector Position \n");
|
||||
detGeo.array2.PrintArray();
|
||||
}
|
||||
}else{
|
||||
if( detGeo.use2ndArray){
|
||||
printf("--------------------------------- 2nd Detector Position \n");
|
||||
detGeo.array2.PrintArray();
|
||||
}else{
|
||||
printf("------------------------------------- Detector Position \n");
|
||||
detGeo.array1.PrintArray();
|
||||
}
|
||||
}
|
||||
|
||||
if( detGeo.elumPos1 != 0 || detGeo.elumPos2 != 0 || detGeo.recoilPos1 != 0 || detGeo.recoilPos2 != 0){
|
||||
printf("=================================== Auxillary/Imaginary Detectors\n");
|
||||
}
|
||||
if( detGeo.elumPos1 != 0 ) printf(" Elum 1 pos.: %f mm \n", detGeo.elumPos1);
|
||||
if( detGeo.elumPos2 != 0 ) printf(" Elum 2 pos.: %f mm \n", detGeo.elumPos2);
|
||||
if( detGeo.recoilPos1 != 0 ) printf(" Recoil 1 pos.: %f mm \n", detGeo.recoilPos1);
|
||||
if( detGeo.recoilPos2 != 0 ) printf(" Recoil 2 pos.: %f mm \n", detGeo.recoilPos2);
|
||||
printf("=====================================================\n");
|
||||
|
||||
}
|
||||
|
||||
ReactionConfig LoadReactionConfig(TMacro * macro){
|
||||
|
||||
ReactionConfig reaction;
|
||||
|
||||
if( macro == NULL ) return reaction;
|
||||
|
||||
int numLine = macro->GetListOfLines()->GetSize();
|
||||
|
||||
for( int i = 0; i < numLine; i ++){
|
||||
|
||||
std::vector<std::string> str = SplitStr(macro->GetListOfLines()->At(i)->GetName(), " ");
|
||||
|
||||
///printf("%d | %s\n", i, str[0].c_str());
|
||||
|
||||
if( str[0].find_first_of("#") == 0 ) break;
|
||||
|
||||
if( i == 0 ) reaction.beamA = atoi(str[0].c_str());
|
||||
if( i == 1 ) reaction.beamZ = atoi(str[0].c_str());
|
||||
if( i == 2 ) reaction.targetA = atoi(str[0].c_str());
|
||||
if( i == 3 ) reaction.targetZ = atoi(str[0].c_str());
|
||||
if( i == 4 ) reaction.recoilLightA = atoi(str[0].c_str());
|
||||
if( i == 5 ) reaction.recoilLightZ = atoi(str[0].c_str());
|
||||
if( i == 6 ) reaction.beamEnergy = atof(str[0].c_str());
|
||||
if( i == 7 ) reaction.beamEnergySigma = atof(str[0].c_str());
|
||||
if( i == 8 ) reaction.beamAngle = atof(str[0].c_str());
|
||||
if( i == 9 ) reaction.beamAngleSigma = atof(str[0].c_str());
|
||||
if( i == 10 ) reaction.beamX = atof(str[0].c_str());
|
||||
if( i == 11 ) reaction.beamY = atof(str[0].c_str());
|
||||
if( i == 12 ) reaction.numEvents = atoi(str[0].c_str());
|
||||
if( i == 13 ) {
|
||||
if( str[0].compare("false") == 0 ) reaction.isTargetScattering = false;
|
||||
if( str[0].compare("true") == 0 ) reaction.isTargetScattering = true;
|
||||
}
|
||||
if( i == 14 ) reaction.targetDensity = atof(str[0].c_str());
|
||||
if( i == 15 ) reaction.targetThickness = atof(str[0].c_str());
|
||||
if( i == 16 ) reaction.beamStoppingPowerFile = str[0];
|
||||
if( i == 17 ) reaction.recoilLightStoppingPowerFile = str[0];
|
||||
if( i == 18 ) reaction.recoilHeavyStoppingPowerFile = str[0];
|
||||
if( i == 19 ) {
|
||||
if( str[0].compare("false") == 0 ) reaction.isDecay = false;
|
||||
if( str[0].compare("true") == 0 ) reaction.isDecay = true;
|
||||
}
|
||||
if( i == 20 ) reaction.heavyDecayA = atoi(str[0].c_str());
|
||||
if( i == 21 ) reaction.heavyDecayZ = atoi(str[0].c_str());
|
||||
if( i == 22 ) {
|
||||
if( str[0].compare("false") == 0 ) reaction.isRedo = false;
|
||||
if( str[0].compare("true" ) == 0 ) reaction.isRedo = true;
|
||||
}
|
||||
|
||||
if( i >= 23) {
|
||||
reaction.beamEx.push_back( atof(str[0].c_str()) );
|
||||
}
|
||||
}
|
||||
|
||||
reaction.recoilHeavyA = reaction.beamA + reaction.targetA - reaction.recoilLightA;
|
||||
reaction.recoilHeavyZ = reaction.beamZ + reaction.targetZ - reaction.recoilLightZ;
|
||||
|
||||
return reaction;
|
||||
|
||||
}
|
||||
|
||||
void PrintReactionConfig(ReactionConfig reaction){
|
||||
|
||||
printf("=====================================================\n");
|
||||
printf(" beam : A = %3d, Z = %2d \n", reaction.beamA, reaction.beamZ);
|
||||
printf(" target : A = %3d, Z = %2d \n", reaction.targetA, reaction.targetZ);
|
||||
printf(" light : A = %3d, Z = %2d \n", reaction.recoilLightA, reaction.recoilLightZ);
|
||||
|
||||
printf(" beam Energy : %.2f +- %.2f MeV/u, dE/E = %5.2f %%\n", reaction.beamEnergy, reaction.beamEnergySigma, reaction.beamEnergySigma/reaction.beamEnergy);
|
||||
printf(" Angle : %.2f +- %.2f mrad\n", reaction.beamAngle, reaction.beamAngleSigma);
|
||||
printf(" offset : (x,y) = (%.2f, %.2f) mmm \n", reaction.beamX, reaction.beamY);
|
||||
|
||||
printf("##### number of Simulation Events : %d \n", reaction.numEvents);
|
||||
|
||||
printf(" is target scattering : %s \n", reaction.isTargetScattering ? "Yes" : "No");
|
||||
|
||||
if(reaction.isTargetScattering){
|
||||
printf(" target density : %.f g/cm3\n", reaction.targetDensity);
|
||||
printf(" thickness : %.f cm\n", reaction.targetThickness);
|
||||
printf(" beam stopping file : %s \n", reaction.beamStoppingPowerFile.c_str());
|
||||
printf(" recoil light stopping file : %s \n", reaction.recoilLightStoppingPowerFile.c_str());
|
||||
printf(" recoil heavy stopping file : %s \n", reaction.recoilHeavyStoppingPowerFile.c_str());
|
||||
}
|
||||
|
||||
printf(" is simulate decay : %s \n", reaction.isDecay ? "Yes" : "No");
|
||||
if( reaction.isDecay ){
|
||||
printf(" heavy decay : A = %d, Z = %d \n", reaction.heavyDecayA, reaction.heavyDecayZ);
|
||||
}
|
||||
printf(" is Redo until hit array : %s \n", reaction.isRedo ? "Yes" : "No");
|
||||
|
||||
printf(" beam Ex : %.2f MeV \n", reaction.beamEx[0]);
|
||||
for( int i = 1; i < (int) reaction.beamEx.size(); i++){
|
||||
printf(" %.2f MeV \n", reaction.beamEx[i]);
|
||||
}
|
||||
|
||||
printf("=====================================================\n");
|
||||
|
||||
}
|
||||
|
||||
DetGeo detGeo;
|
||||
ReactionConfig reactionConfig1;
|
||||
ReactionConfig reactionConfig2;
|
||||
|
||||
void LoadDetGeoAndReactionConfigFile(std::string detGeoFileName = "detectorGeo.txt",
|
||||
std::string reactionConfigFileName1 = "reactionConfig1.txt",
|
||||
std::string reactionConfigFileName2 = "reactionConfig2.txt"){
|
||||
printf("=====================================================\n");
|
||||
printf(" loading detector geometery : %s.", detGeoFileName.c_str());
|
||||
TMacro * haha = new TMacro();
|
||||
if( haha->ReadFile(detGeoFileName.c_str()) > 0 ) {
|
||||
detGeo = AnalysisLib::LoadDetectorGeo(haha);
|
||||
printf("... done.\n");
|
||||
AnalysisLib::PrintDetGeo(detGeo);
|
||||
}else{
|
||||
printf("... fail\n");
|
||||
}
|
||||
delete haha;
|
||||
|
||||
printf("=====================================================\n");
|
||||
printf(" loading reaction1 config : %s.", reactionConfigFileName1.c_str());
|
||||
TMacro * kaka = new TMacro();
|
||||
if( kaka->ReadFile(reactionConfigFileName1.c_str()) > 0 ) {
|
||||
reactionConfig1 = AnalysisLib::LoadReactionConfig(kaka);
|
||||
printf("..... done.\n");
|
||||
AnalysisLib::PrintReactionConfig(reactionConfig1);
|
||||
}else{
|
||||
printf("..... fail\n");
|
||||
}
|
||||
delete kaka;
|
||||
|
||||
if( detGeo.use2ndArray){
|
||||
printf("=====================================================\n");
|
||||
printf(" loading reaction2 config : %s.", reactionConfigFileName2.c_str());
|
||||
TMacro * jaja = new TMacro();
|
||||
if( jaja->ReadFile(reactionConfigFileName2.c_str()) > 0 ) {
|
||||
reactionConfig2 = AnalysisLib::LoadReactionConfig(kaka);
|
||||
printf("..... done.\n");
|
||||
AnalysisLib::PrintReactionConfig(reactionConfig2);
|
||||
}else{
|
||||
printf("..... fail\n");
|
||||
}
|
||||
delete jaja;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//************************************** Correction parameters;
|
||||
|
||||
std::vector<float> xnCorr; //correction of xn to match xf
|
||||
std::vector<float> xScale; // correction of x to be (0,1)
|
||||
std::vector<std::vector<float>> xfxneCorr; //correction of xn and xf to match e
|
||||
std::vector<std::vector<float>> eCorr; // correction to e, ch -> MeV
|
||||
std::vector<std::vector<float>> rdtCorr; // correction of rdt, ch -> MeV
|
||||
|
||||
//~========================================= xf = xn correction
|
||||
void LoadXNCorr(bool verbose = false, const char * fileName = "correction_xf_xn.dat"){
|
||||
printf(" loading xf-xn correction.");
|
||||
xnCorr.clear();
|
||||
std::ifstream file;
|
||||
file.open(fileName);
|
||||
if( file.is_open() ){
|
||||
float a;
|
||||
while( file >> a ) xnCorr.push_back(a);
|
||||
printf(".......... done.\n");
|
||||
}else{
|
||||
printf(".......... fail.\n");
|
||||
}
|
||||
file.close();
|
||||
if( verbose ) for(int i = 0; i < (int) xnCorr.size(); i++) printf("%2d | %10.3f\n", i, xnCorr[i]);
|
||||
}
|
||||
|
||||
|
||||
//~========================================= X-Scale correction
|
||||
void LoadXScaleCorr(bool verbose = false, const char * fileName = "correction_scaleX.dat"){
|
||||
printf(" loading x-Scale correction.");
|
||||
xScale.clear();
|
||||
std::ifstream file;
|
||||
file.open(fileName);
|
||||
if( file.is_open() ){
|
||||
float a, b;
|
||||
while( file >> a ) xScale.push_back(a);
|
||||
printf("........ done.\n");
|
||||
}else{
|
||||
printf("........ fail.\n");
|
||||
}
|
||||
file.close();
|
||||
if( verbose ) for(int i = 0; i < (int) xScale.size(); i++) printf("%2d | %10.3f\n", i, xnCorr[i]);
|
||||
}
|
||||
|
||||
//~========================================= e = xf + xn correction
|
||||
void LoadXFXN2ECorr(bool verbose = false, const char * fileName = "correction_xfxn_e.dat"){
|
||||
printf(" loading xf/xn-e correction.");
|
||||
xfxneCorr.clear();
|
||||
std::ifstream file;
|
||||
file.open(fileName);
|
||||
if( file.is_open() ){
|
||||
float a, b;
|
||||
while( file >> a >> b) xfxneCorr.push_back({a, b});
|
||||
printf("........ done.\n");
|
||||
}else{
|
||||
printf("........ fail.\n");
|
||||
}
|
||||
file.close();
|
||||
if( verbose ) for(int i = 0; i < (int) xfxneCorr.size(); i++) printf("%2d | %10.3f, %10.3f\n", i, xfxneCorr[i][0], xfxneCorr[i][1]);
|
||||
}
|
||||
|
||||
//~========================================= e correction
|
||||
void LoadECorr(bool verbose = false, const char * fileName = "correction_e.dat"){
|
||||
printf(" loading e correction.");
|
||||
eCorr.clear();
|
||||
std::ifstream file;
|
||||
file.open(fileName);
|
||||
if( file.is_open() ){
|
||||
float a, b;
|
||||
while( file >> a >> b) eCorr.push_back( {a, b} ); // 1/a1, a0 , e' = e * a1 + a0
|
||||
printf(".............. done.\n");
|
||||
}else{
|
||||
printf(".............. fail.\n");
|
||||
}
|
||||
file.close();
|
||||
if( verbose ) for(int i = 0; i < (int) eCorr.size(); i++) printf("%2d | %10.3f, %10.3f\n", i, eCorr[i][0], eCorr[i][1]);
|
||||
}
|
||||
|
||||
//~========================================= rdt correction
|
||||
void LoadRDTCorr(bool verbose = false, const char * fileName = "correction_rdt.dat"){
|
||||
printf(" loading rdt correction.");
|
||||
rdtCorr.clear();
|
||||
std::ifstream file;
|
||||
file.open(fileName);
|
||||
if( file.is_open() ){
|
||||
float a, b;
|
||||
while( file >> a >> b) rdtCorr.push_back({a, b});
|
||||
printf("............ done.\n");
|
||||
}else{
|
||||
printf("............ fail.\n");
|
||||
}
|
||||
file.close();
|
||||
if( verbose ) for(int i = 0; i < (int) rdtCorr.size(); i++) printf("%2d | %10.3f, %10.3f\n", i, rdtCorr[i][0], rdtCorr[i][1]);
|
||||
}
|
||||
|
||||
|
||||
struct ReactionParas{
|
||||
|
||||
double Et; // total energy in CM frame
|
||||
double beta; // Lorentz beta from Lab to CM
|
||||
double gamma; // Lorentz gamma from Lab to CM
|
||||
double alpha; // E-Z slope / beta
|
||||
double G; //The G-coefficient....
|
||||
double massB; // heavy mass
|
||||
double q; // charge of light particle
|
||||
double mass; //light mass
|
||||
bool hasReactionPara;
|
||||
|
||||
double detPrepDist;
|
||||
|
||||
};
|
||||
|
||||
ReactionParas reactParas1;
|
||||
ReactionParas reactParas2;
|
||||
|
||||
//~========================================= reaction parameters
|
||||
void LoadReactionParas(int arrayID, bool verbose = false){
|
||||
|
||||
//check is the transfer.root is using the latest reactionConfig.txt
|
||||
//sicne reaction.dat is generated as a by-product of transfer.root
|
||||
//TFile * transfer = new TFile("transfer.root");
|
||||
//TString aaa1 = "";
|
||||
//TString aaa2 = "";
|
||||
//if( transfer->IsOpen() ){
|
||||
// TMacro * reactionConfig = (TMacro *) transfer->FindObjectAny("reactionConfig");
|
||||
// TMacro presentReactionConfig ("reactionConfig.txt");
|
||||
// aaa1 = ((TMD5*) reactionConfig->Checksum())->AsString();
|
||||
// aaa2 = ((TMD5*) presentReactionConfig.Checksum())->AsString();
|
||||
//}
|
||||
//printf("%s\n", aaa1.Data());
|
||||
//printf("%s\n", aaa2.Data());
|
||||
|
||||
//if( aaa1 != aaa2 ) {
|
||||
// printf("########################## recalculate transfer.root \n");
|
||||
// system("../Cleopatra/Transfer");
|
||||
// printf("########################## transfer.root updated\n");
|
||||
//}
|
||||
|
||||
ReactionParas * reactParas = nullptr;
|
||||
|
||||
std::string fileName;
|
||||
|
||||
if( arrayID == 1){
|
||||
reactParas = &AnalysisLib::reactParas1;
|
||||
fileName = "reaction.dat";
|
||||
}else if( arrayID == 2){
|
||||
reactParas = &AnalysisLib::reactParas2;
|
||||
fileName = "reaction2.dat";
|
||||
}else{
|
||||
printf("arrayID must be either 1 or 2. Abort.\n");
|
||||
return;
|
||||
}
|
||||
reactParas->detPrepDist = AnalysisLib::detGeo.array1.detPerpDist;
|
||||
|
||||
printf(" loading reaction parameters");
|
||||
std::ifstream file;
|
||||
file.open(fileName.c_str());
|
||||
reactParas->hasReactionPara = false;
|
||||
if( file.is_open() ){
|
||||
std::string x;
|
||||
int i = 0;
|
||||
while( file >> x ){
|
||||
if( x.substr(0,2) == "//" ) continue;
|
||||
if( i == 0 ) reactParas->mass = atof(x.c_str());
|
||||
if( i == 1 ) reactParas->q = atof(x.c_str());
|
||||
if( i == 2 ) reactParas->beta = atof(x.c_str());
|
||||
if( i == 3 ) reactParas->Et = atof(x.c_str());
|
||||
if( i == 4 ) reactParas->massB = atof(x.c_str());
|
||||
i = i + 1;
|
||||
}
|
||||
printf("........ done.\n");
|
||||
|
||||
reactParas->hasReactionPara = true;
|
||||
reactParas->alpha = 299.792458 * abs(detGeo.Bfield) * reactParas->q / TMath::TwoPi()/1000.; //MeV/mm
|
||||
reactParas->gamma = 1./TMath::Sqrt(1-reactParas->beta * reactParas->beta);
|
||||
reactParas->G = reactParas->alpha * reactParas->gamma * reactParas->beta * reactParas->detPrepDist ;
|
||||
|
||||
if( verbose ){
|
||||
printf("\tmass-b : %f MeV/c2 \n", reactParas->mass);
|
||||
printf("\tcharge-b : %f \n", reactParas->q);
|
||||
printf("\tE-total : %f MeV \n", reactParas->Et);
|
||||
printf("\tmass-B : %f MeV/c2 \n", reactParas->massB);
|
||||
printf("\tbeta : %f \n", reactParas->beta);
|
||||
printf("\tB-field : %f T \n", detGeo.Bfield);
|
||||
printf("\tslope : %f MeV/mm \n", reactParas->alpha * reactParas->beta);
|
||||
printf("\tdet radius: %f mm \n", reactParas->detPrepDist);
|
||||
printf("\tG-coeff : %f MeV \n", reactParas->G);
|
||||
printf("=====================================================\n");
|
||||
}
|
||||
|
||||
}else{
|
||||
printf("........ fail.\n");
|
||||
}
|
||||
file.close();
|
||||
|
||||
}
|
||||
|
||||
std::vector<double> CalExTheta(double e, double z){
|
||||
|
||||
ReactionParas * reactParas = nullptr;
|
||||
|
||||
if( detGeo.array1.zMin <= z && z <= detGeo.array1.zMax ){
|
||||
reactParas = &reactParas1;
|
||||
if( !reactParas->hasReactionPara) return {TMath::QuietNaN(), TMath::QuietNaN()};
|
||||
}
|
||||
|
||||
if( detGeo.array2.zMin <= z && z <= detGeo.array2.zMax ){
|
||||
reactParas = &reactParas2;
|
||||
if( !reactParas->hasReactionPara) return {TMath::QuietNaN(), TMath::QuietNaN()};
|
||||
}
|
||||
|
||||
double Ex = TMath::QuietNaN();
|
||||
double thetaCM = TMath::QuietNaN();
|
||||
|
||||
double y = e + reactParas->mass; // to give the KE + mass of proton;
|
||||
double Z = reactParas->alpha * reactParas->gamma * reactParas->beta * z;
|
||||
double H = TMath::Sqrt(TMath::Power(reactParas->gamma * reactParas->beta,2) * (y*y - reactParas->mass * reactParas->mass) ) ;
|
||||
|
||||
if( TMath::Abs(Z) < H ) {
|
||||
///using Newton's method to solve 0 == H * sin(phi) - G * tan(phi) - Z = f(phi)
|
||||
double tolerrence = 0.001;
|
||||
double phi = 0; ///initial phi = 0 -> ensure the solution has f'(phi) > 0
|
||||
double nPhi = 0; /// new phi
|
||||
|
||||
int iter = 0;
|
||||
do{
|
||||
phi = nPhi;
|
||||
nPhi = phi - (H * TMath::Sin(phi) - reactParas->G * TMath::Tan(phi) - Z) / (H * TMath::Cos(phi) - reactParas->G /TMath::Power( TMath::Cos(phi), 2));
|
||||
iter ++;
|
||||
if( iter > 10 || TMath::Abs(nPhi) > TMath::PiOver2()) break;
|
||||
}while( TMath::Abs(phi - nPhi ) > tolerrence);
|
||||
phi = nPhi;
|
||||
|
||||
/// check f'(phi) > 0
|
||||
double Df = H * TMath::Cos(phi) - reactParas->G / TMath::Power( TMath::Cos(phi),2);
|
||||
if( Df > 0 && TMath::Abs(phi) < TMath::PiOver2() ){
|
||||
double K = H * TMath::Sin(phi);
|
||||
double x = TMath::ACos( reactParas->mass / ( y * reactParas->gamma - K));
|
||||
double momt = reactParas->mass * TMath::Tan(x); /// momentum of particel b or B in CM frame
|
||||
double EB = TMath::Sqrt(reactParas->mass * reactParas->mass + reactParas->Et * reactParas->Et - 2 * reactParas->Et * TMath::Sqrt(momt*momt + reactParas->mass * reactParas->mass));
|
||||
Ex = EB - reactParas->massB;
|
||||
|
||||
double hahaha1 = reactParas->gamma * TMath::Sqrt(reactParas->mass * reactParas->mass + momt * momt) - y;
|
||||
double hahaha2 = reactParas->gamma * reactParas->beta * momt;
|
||||
thetaCM = TMath::ACos(hahaha1/hahaha2) * TMath::RadToDeg();
|
||||
|
||||
}
|
||||
}
|
||||
return {Ex, thetaCM};
|
||||
|
||||
}
|
||||
|
||||
//************************************** TCutG
|
||||
|
||||
TObjArray * LoadListOfTCut(TString fileName, TString cutName = "cutList"){
|
||||
|
||||
if( fileName == "" ) return nullptr;
|
||||
|
||||
TObjArray * cutList = nullptr;
|
||||
|
||||
TFile * fCut = new TFile(fileName);
|
||||
bool isCutFileOpen = fCut->IsOpen();
|
||||
if(!isCutFileOpen) {
|
||||
printf( "Failed to open rdt-cutfile 1 : %s\n" , fileName.Data());
|
||||
}else{
|
||||
cutList = (TObjArray *) fCut->FindObjectAny(cutName);
|
||||
|
||||
if( cutList ){
|
||||
int numCut = cutList->GetEntries();
|
||||
printf("=========== found %d cutG in %s \n", numCut, fCut->GetName());
|
||||
|
||||
for(int i = 0; i < numCut ; i++){
|
||||
printf("cut name : %s , VarX: %s, VarY: %s, numPoints: %d \n",
|
||||
cutList->At(i)->GetName(),
|
||||
((TCutG*)cutList->At(i))->GetVarX(),
|
||||
((TCutG*)cutList->At(i))->GetVarY(),
|
||||
((TCutG*)cutList->At(i))->GetN()
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return cutList;
|
||||
}
|
||||
|
||||
TCutG * LoadSingleTCut( TString fileName, TString cutName = "cutEZ"){
|
||||
|
||||
if( fileName == "" ) return nullptr;
|
||||
TCutG * cut = nullptr;
|
||||
|
||||
TFile * fCut = new TFile(fileName);
|
||||
bool isCutFileOpen = fCut->IsOpen();
|
||||
if( !isCutFileOpen) {
|
||||
printf( "Failed to open E-Z cutfile : %s\n" , fileName.Data());
|
||||
}else{
|
||||
cut = (TCutG *) fCut->FindObjectAny(cutName);
|
||||
if( cut != NULL ) {
|
||||
printf("Found EZ cut| name : %s, VarX: %s, VarY: %s, numPoints: %d \n",
|
||||
cut->GetName(),
|
||||
cut->GetVarX(),
|
||||
cut->GetVarY(),
|
||||
cut->GetN()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return cut;
|
||||
}
|
||||
|
||||
|
||||
//************************************** Others
|
||||
std::vector<std::vector<double>> combination(std::vector<double> arr, int r){
|
||||
|
||||
std::vector<std::vector<double>> output;
|
||||
|
||||
int n = arr.size();
|
||||
std::vector<int> v(n);
|
||||
std::fill(v.begin(), v.begin()+r, 1);
|
||||
do {
|
||||
//for( int i = 0; i < n; i++) { printf("%d ", v[i]); }; printf("\n");
|
||||
|
||||
std::vector<double> temp;
|
||||
for (int i = 0; i < n; ++i) {
|
||||
if (v[i]) {
|
||||
//printf("%.1f, ", arr[i]);
|
||||
temp.push_back(arr[i]);
|
||||
}
|
||||
}
|
||||
//printf("\n");
|
||||
|
||||
output.push_back(temp);
|
||||
|
||||
} while (std::prev_permutation(v.begin(), v.end()));
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
double* sumMeanVar(std::vector<double> data){
|
||||
|
||||
int n = data.size();
|
||||
double sum = 0;
|
||||
for( int k = 0; k < n; k++) sum += data[k];
|
||||
double mean = sum/n;
|
||||
double var = 0;
|
||||
for( int k = 0; k < n; k++) var += pow(data[k] - mean,2);
|
||||
|
||||
static double output[3];
|
||||
output[0] = sum;
|
||||
output[1] = mean;
|
||||
output[2] = var;
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
double* fitSlopeIntercept(std::vector<double> dataX, std::vector<double> dataY){
|
||||
|
||||
double * smvY = sumMeanVar(dataY);
|
||||
double sumY = smvY[0];
|
||||
double meanY = smvY[1];
|
||||
|
||||
double * smvX = sumMeanVar(dataX);
|
||||
double sumX = smvX[0];
|
||||
double meanX = smvX[1];
|
||||
double varX = smvX[2];
|
||||
|
||||
int n = dataX.size();
|
||||
double sumXY = 0;
|
||||
for( int j = 0; j < n; j++) sumXY += dataX[j] * dataY[j];
|
||||
|
||||
double slope = ( sumXY - sumX * sumY/n ) / varX;
|
||||
double intercept = meanY - slope * meanX;
|
||||
|
||||
static double output[2];
|
||||
output[0] = slope;
|
||||
output[1] = intercept;
|
||||
|
||||
return output;
|
||||
|
||||
}
|
||||
|
||||
std::vector<std::vector<double>> FindMatchingPair(std::vector<double> enX, std::vector<double> enY){
|
||||
|
||||
//output[0] = fitEnergy;
|
||||
//output[1] = refEnergy;
|
||||
|
||||
int nX = enX.size();
|
||||
int nY = enY.size();
|
||||
|
||||
std::vector<double> fitEnergy;
|
||||
std::vector<double> refEnergy;
|
||||
|
||||
if( nX > nY ){
|
||||
|
||||
std::vector<std::vector<double>> output = combination(enX, nY);
|
||||
|
||||
double * smvY = sumMeanVar(enY);
|
||||
double sumY = smvY[0];
|
||||
double meanY = smvY[1];
|
||||
double varY = smvY[2];
|
||||
|
||||
double optRSquared = 0;
|
||||
double absRSqMinusOne = 1;
|
||||
int maxID = 0;
|
||||
|
||||
for( int k = 0; k < (int) output.size(); k++){
|
||||
|
||||
double * smvX = sumMeanVar(output[k]);
|
||||
double sumX = smvX[0];
|
||||
double meanX = smvX[1];
|
||||
double varX = smvX[2];
|
||||
|
||||
double sumXY = 0;
|
||||
for( int j = 0; j < nY; j++) sumXY += output[k][j] * enY[j];
|
||||
|
||||
double rSq = abs(sumXY - sumX*sumY/nY)/sqrt(varX*varY);
|
||||
|
||||
//for( int j = 0; j < nY ; j++){ printf("%.1f, ", output[k][j]); }; printf("| %.10f\n", rSq);
|
||||
|
||||
if( abs(rSq-1) < absRSqMinusOne ) {
|
||||
absRSqMinusOne = abs(rSq-1);
|
||||
optRSquared = rSq;
|
||||
maxID = k;
|
||||
}
|
||||
}
|
||||
|
||||
fitEnergy = output[maxID];
|
||||
refEnergy = enY;
|
||||
|
||||
printf(" R^2 : %.20f\n", optRSquared);
|
||||
|
||||
//calculation fitting coefficient
|
||||
//double * si = fitSlopeIntercept(fitEnergy, refEnergy);
|
||||
//printf( " y = %.4f x + %.4f\n", si[0], si[1]);
|
||||
|
||||
}else if( nX < nY ){
|
||||
|
||||
std::vector<std::vector<double>> output = combination(enY, nX);
|
||||
|
||||
|
||||
double * smvX = sumMeanVar(enX);
|
||||
double sumX = smvX[0];
|
||||
double meanX = smvX[1];
|
||||
double varX = smvX[2];
|
||||
|
||||
double optRSquared = 0;
|
||||
double absRSqMinusOne = 1;
|
||||
int maxID = 0;
|
||||
|
||||
for( int k = 0; k < (int) output.size(); k++){
|
||||
|
||||
double * smvY = sumMeanVar(output[k]);
|
||||
double sumY = smvY[0];
|
||||
double meanY = smvY[1];
|
||||
double varY = smvY[2];
|
||||
|
||||
double sumXY = 0;
|
||||
for( int j = 0; j < nX; j++) sumXY += output[k][j] * enX[j];
|
||||
|
||||
double rSq = abs(sumXY - sumX*sumY/nX)/sqrt(varX*varY);
|
||||
|
||||
//for( int j = 0; j < nX ; j++){ printf("%.1f, ", output[k][j]); }; printf("| %.10f\n", rSq);
|
||||
|
||||
if( abs(rSq-1) < absRSqMinusOne ) {
|
||||
absRSqMinusOne = abs(rSq-1);
|
||||
optRSquared = rSq;
|
||||
maxID = k;
|
||||
}
|
||||
}
|
||||
|
||||
fitEnergy = enX;
|
||||
refEnergy = output[maxID];
|
||||
printf(" R^2 : %.20f\n", optRSquared);
|
||||
|
||||
}else{
|
||||
fitEnergy = enX;
|
||||
refEnergy = enY;
|
||||
|
||||
//if nX == nY, ther could be cases that only partial enX and enY are matched.
|
||||
|
||||
}
|
||||
|
||||
printf("fitEnergy = ");for( int k = 0; k < (int) fitEnergy.size() ; k++){ printf("%7.2f, ", fitEnergy[k]); }; printf("\n");
|
||||
printf("refEnergy = ");for( int k = 0; k < (int) refEnergy.size() ; k++){ printf("%7.2f, ", refEnergy[k]); }; printf("\n");
|
||||
|
||||
std::vector<std::vector<double>> haha;
|
||||
haha.push_back(fitEnergy);
|
||||
haha.push_back(refEnergy);
|
||||
|
||||
return haha;
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
#endif
|
351
armory/EventBuilder.cpp
Normal file
|
@ -0,0 +1,351 @@
|
|||
#include "SolReader.h"
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
|
||||
#include "TFile.h"
|
||||
#include "TTree.h"
|
||||
#include "TMath.h"
|
||||
#include "TString.h"
|
||||
#include "TMacro.h"
|
||||
//#include "TClonesArray.h" // plan to save trace as TVector with TClonesArray
|
||||
//#include "TVector.h"
|
||||
|
||||
#define MAX_MULTI 64
|
||||
#define MAX_TRACE_LEN 2500
|
||||
|
||||
#define tick2ns 8 // 1 tick = 8 ns
|
||||
|
||||
SolReader ** reader;
|
||||
Hit ** hit;
|
||||
|
||||
std::vector<std::vector<int>> idList;
|
||||
|
||||
unsigned long totFileSize = 0;
|
||||
unsigned long processedFileSize = 0;
|
||||
|
||||
std::vector<int> activeFileID;
|
||||
std::vector<int> groupIndex;
|
||||
std::vector<std::vector<int>> group; // group[i][j], i = group ID, j = group member)
|
||||
|
||||
void findEarliestTime(int &fileID, int &groupID){
|
||||
|
||||
unsigned long firstTime = 0;
|
||||
for( int i = 0; i < (int) activeFileID.size(); i++){
|
||||
int id = activeFileID[i];
|
||||
if( i == 0 ) {
|
||||
firstTime = hit[id]->timestamp;
|
||||
fileID = id;
|
||||
groupID = i;
|
||||
//printf("%d | %d %lu %d | %d \n", id, reader[id]->GetBlockID(), hit[id]->timestamp, hit[id]->channel, (int) activeFileID.size());
|
||||
continue;
|
||||
}
|
||||
if( hit[id]->timestamp <= firstTime) {
|
||||
firstTime = hit[id]->timestamp;
|
||||
fileID = id;
|
||||
groupID = i;
|
||||
//printf("%d | %d %lu %d | %d \n", id, reader[id]->GetBlockID(), hit[id]->timestamp, hit[id]->channel, (int) activeFileID.size());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
unsigned long long evID = 0;
|
||||
unsigned int multi = 0;
|
||||
unsigned short bd[MAX_MULTI] = {0};
|
||||
unsigned short sn[MAX_MULTI] = {0};
|
||||
unsigned short ch[MAX_MULTI] = {0};
|
||||
unsigned short e[MAX_MULTI] = {0};
|
||||
unsigned short e2[MAX_MULTI] = {0}; //for PSD energy short
|
||||
unsigned long long e_t[MAX_MULTI] = {0};
|
||||
unsigned short e_f[MAX_MULTI] = {0};
|
||||
unsigned short lowFlag[MAX_MULTI] = {0};
|
||||
unsigned short highFlag[MAX_MULTI] = {0};
|
||||
int traceLen[MAX_MULTI] = {0};
|
||||
int trace[MAX_MULTI][MAX_TRACE_LEN] = {0};
|
||||
|
||||
void fillData(int &fileID, const bool &saveTrace){
|
||||
bd[multi] = idList[fileID][1];
|
||||
sn[multi] = idList[fileID][3];
|
||||
ch[multi] = hit[fileID]->channel;
|
||||
e[multi] = hit[fileID]->energy;
|
||||
e2[multi] = hit[fileID]->energy_short;
|
||||
e_t[multi] = hit[fileID]->timestamp;
|
||||
e_f[multi] = hit[fileID]->fine_timestamp;
|
||||
lowFlag[multi] = hit[fileID]->flags_low_priority;
|
||||
highFlag[multi] = hit[fileID]->flags_high_priority;
|
||||
|
||||
if( saveTrace ){
|
||||
traceLen[multi] = hit[fileID]->traceLenght;
|
||||
for( int i = 0; i < TMath::Min(traceLen[multi], MAX_TRACE_LEN); i++){
|
||||
trace[multi][i] = hit[fileID]->analog_probes[0][i];
|
||||
}
|
||||
}
|
||||
|
||||
multi++;
|
||||
reader[fileID]->ReadNextBlock();
|
||||
}
|
||||
|
||||
void printEvent(){
|
||||
printf("==================== evID : %llu\n", evID);
|
||||
for( int i = 0; i < multi; i++){
|
||||
printf(" %2d | %d %d | %llu %d \n", i, bd[i], ch[i], e_t[i], e[i] );
|
||||
}
|
||||
printf("==========================================\n");
|
||||
}
|
||||
|
||||
//^##################################################################################
|
||||
int main(int argc, char ** argv){
|
||||
|
||||
printf("=======================================================\n");
|
||||
printf("=== SOLARIS Event Builder sol --> root ===\n");
|
||||
printf("=======================================================\n");
|
||||
|
||||
if( argc <= 3){
|
||||
printf("%s [outfile] [timeWindow] [saveTrace] [sol-1] [sol-2] ... \n", argv[0]);
|
||||
printf(" outfile : output root file name\n");
|
||||
printf(" timeWindow : number of tick, 1 tick = %d ns.\n", tick2ns);
|
||||
printf(" saveTrace : 1 = save trace, 0 = no trace\n");
|
||||
printf(" sol-X : the sol file(s)\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
// for( int i = 0; i < argc; i++){
|
||||
// printf("%d | %s\n", i, argv[i]);
|
||||
// }
|
||||
|
||||
TString outFileName = argv[1];
|
||||
int timeWindow = abs(atoi(argv[2]));
|
||||
const bool saveTrace = atoi(argv[3]);
|
||||
|
||||
const int nFile = argc - 4;
|
||||
TString inFileName[nFile];
|
||||
for( int i = 0 ; i < nFile ; i++){
|
||||
inFileName[i] = argv[i+4];
|
||||
}
|
||||
|
||||
//*======================================== setup reader
|
||||
reader = new SolReader*[nFile];
|
||||
hit = new Hit *[nFile];
|
||||
|
||||
for( int i = 0 ; i < nFile ; i++){
|
||||
reader[i] = new SolReader(inFileName[i].Data());
|
||||
hit[i] = reader[i]->hit; //TODO check is file open propertly
|
||||
reader[i]->ReadNextBlock(); // read the first block
|
||||
}
|
||||
|
||||
//*======================================== group files
|
||||
idList.clear();
|
||||
for( int i = 0; i < nFile; i++){
|
||||
TString fn = inFileName[i];
|
||||
|
||||
int pos = fn.Last('/'); // path
|
||||
fn.Remove(0, pos+1);
|
||||
|
||||
pos = fn.First('_'); // expName;
|
||||
fn.Remove(0, pos+1);
|
||||
|
||||
pos = fn.First('_'); // runNum;
|
||||
fn.Remove(0, pos+1);
|
||||
|
||||
pos = fn.First('_'); // digiID
|
||||
TString f1 = fn;
|
||||
int digiID = f1.Remove(pos).Atoi();
|
||||
fn.Remove(0, pos+1);
|
||||
|
||||
pos = fn.Last('_'); // digi serial num
|
||||
f1 = fn;
|
||||
int digisn = f1.Remove(pos).Atoi();
|
||||
fn.Remove(0, pos+1);
|
||||
|
||||
pos = fn.First('.'); // get the file id;
|
||||
int indexID = fn.Remove(pos).Atoi();
|
||||
|
||||
int fileID = i;
|
||||
std::vector<int> haha = {fileID, digiID, indexID, digisn};
|
||||
idList.push_back(haha);
|
||||
}
|
||||
|
||||
// sort by digiID
|
||||
std::sort(idList.begin(), idList.end(), [](const std::vector<int>& a, const std::vector<int>& b){
|
||||
if (a[1] == b[1]) {
|
||||
return a[2] < b[2];
|
||||
}
|
||||
return a[1] < b[1];
|
||||
});
|
||||
|
||||
group.clear(); // group[i][j], i is the group Index = digiID
|
||||
int last_id = 0;
|
||||
std::vector<int> kaka;
|
||||
for( int i = 0; i < (int) idList.size() ; i++){
|
||||
if( i == 0 ) {
|
||||
kaka.clear();
|
||||
last_id = idList[i][1];
|
||||
kaka.push_back(idList[i][0]);
|
||||
continue;
|
||||
}
|
||||
|
||||
if( idList[i][1] != last_id ) {
|
||||
last_id = idList[i][1];
|
||||
group.push_back(kaka);
|
||||
kaka.clear();
|
||||
kaka.push_back(idList[i][0]);
|
||||
}else{
|
||||
kaka.push_back(idList[i][0]);
|
||||
}
|
||||
}
|
||||
group.push_back(kaka);
|
||||
|
||||
printf(" out file : \033[1;33m%s\033[m\n", outFileName.Data());
|
||||
printf(" Event building time window : %d tics = %d nsec \n", timeWindow, timeWindow*tick2ns);
|
||||
printf(" Save Trace ? %s \n", saveTrace ? "Yes" : "No");
|
||||
printf(" Number of input file : %d \n", nFile);
|
||||
for( int i = 0; i < nFile; i++){
|
||||
printf(" %2d| %5.1f MB| %s \n", i, reader[i]->GetFileSize()/1024./1024., inFileName[i].Data());
|
||||
totFileSize += reader[i]->GetFileSize();
|
||||
}
|
||||
printf("------------------------------------\n");
|
||||
for( int i = 0; i < (int) group.size(); i++){
|
||||
printf("Group %d :", i);
|
||||
for( int j = 0; j < (int) group[i].size(); j ++){
|
||||
printf("%d, ", group[i][j]);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
printf("------------------------------------\n");
|
||||
|
||||
//*======================================== setup tree
|
||||
TFile * outRootFile = new TFile(outFileName, "recreate");
|
||||
outRootFile->cd();
|
||||
|
||||
TTree * tree = new TTree("tree", outFileName);
|
||||
|
||||
tree->Branch("evID", &evID, "event_ID/l");
|
||||
tree->Branch("multi", &multi, "multi/i");
|
||||
tree->Branch("bd", bd, "board[multi]/s");
|
||||
tree->Branch("sn", sn, "sn[multi]/s");
|
||||
tree->Branch("ch", ch, "channel[multi]/s");
|
||||
tree->Branch("e", e, "energy[multi]/s");
|
||||
tree->Branch("e2", e2, "energy_short[multi]/s");
|
||||
tree->Branch("e_t", e_t, "timestamp[multi]/l");
|
||||
tree->Branch("e_f", e_t, "fine_timestamp[multi]/s");
|
||||
tree->Branch("lowFlag", lowFlag, "lowFlag[multi]/s");
|
||||
tree->Branch("highFlag", highFlag, "highFlag[multi]/s");
|
||||
|
||||
if( saveTrace){
|
||||
tree->Branch("tl", traceLen, "traceLen[multi]/I");
|
||||
tree->Branch("trace", trace, Form("trace[multi][%d]/I", MAX_TRACE_LEN));
|
||||
}
|
||||
|
||||
//*=========================================== build event
|
||||
|
||||
//@---- using file from group[i][0] first
|
||||
|
||||
//--- find earlist time among the files
|
||||
activeFileID.clear();
|
||||
groupIndex.clear(); //the index of each group
|
||||
|
||||
for(int i = 0; i < (int) group.size(); i++) {
|
||||
groupIndex.push_back(0);
|
||||
activeFileID.push_back(group[i][0]);
|
||||
}
|
||||
|
||||
int fileID = 0;
|
||||
int groupID = 0;
|
||||
findEarliestTime(fileID, groupID);
|
||||
fillData(fileID, saveTrace);
|
||||
|
||||
unsigned long firstTimeStamp = hit[fileID]->timestamp;
|
||||
unsigned long lastTimeStamp = 0;
|
||||
|
||||
int last_precentage = 0;
|
||||
while((activeFileID.size() > 0)){
|
||||
|
||||
findEarliestTime(fileID, groupID);
|
||||
if( reader[fileID]->IsEndOfFile() ){
|
||||
groupIndex[groupID] ++;
|
||||
if( groupIndex[groupID] < (int) group[groupID].size() ){
|
||||
activeFileID[groupID] = group[groupID][groupIndex[groupID]];
|
||||
fileID = activeFileID[groupID];
|
||||
}else{
|
||||
activeFileID.erase(activeFileID.begin() + groupID);
|
||||
}
|
||||
}
|
||||
|
||||
if( hit[fileID]->timestamp - e_t[0] < timeWindow ){
|
||||
fillData(fileID, saveTrace);
|
||||
}else{
|
||||
outRootFile->cd();
|
||||
tree->Fill();
|
||||
evID ++;
|
||||
|
||||
multi = 0;
|
||||
fillData(fileID, saveTrace);
|
||||
}
|
||||
|
||||
///========= calculate progress
|
||||
processedFileSize = 0;
|
||||
for( int p = 0; p < (int) group.size(); p ++){
|
||||
for( int q = 0; q <= groupIndex[p]; q++){
|
||||
if( groupIndex[p] < (int) group[p].size() ){
|
||||
int id = group[p][q];
|
||||
processedFileSize += reader[id]->GetFilePos();
|
||||
}
|
||||
}
|
||||
}
|
||||
double percentage = processedFileSize * 100/ totFileSize;
|
||||
if( percentage >= last_precentage ) {
|
||||
printf("Processed : %llu, %.0f%% | %lu/%lu | ", evID, percentage, processedFileSize, totFileSize);
|
||||
for( int i = 0; i < (int) activeFileID.size(); i++) printf("%d, ", activeFileID[i]);
|
||||
printf(" \n\033[A\r");
|
||||
last_precentage = percentage + 1.0;
|
||||
}
|
||||
}; ///====== end of event building loop
|
||||
|
||||
processedFileSize = 0;
|
||||
for( int p = 0; p < (int) group.size(); p ++){
|
||||
for( int q = 0; q < (int) group[p].size(); q++){
|
||||
int id = group[p][q];
|
||||
processedFileSize += reader[id]->GetFilePos();
|
||||
}
|
||||
}
|
||||
double percentage = processedFileSize * 100/ totFileSize;
|
||||
printf("Processed : %llu, %.0f%% | %lu/%lu \n", evID, percentage, processedFileSize, totFileSize);
|
||||
|
||||
lastTimeStamp = hit[fileID]->timestamp;
|
||||
//*=========================================== save file
|
||||
outRootFile->cd();
|
||||
tree->Fill();
|
||||
evID ++;
|
||||
tree->Write();
|
||||
|
||||
//*=========================================== Save timestamp as TMacro
|
||||
TMacro timeStamp;
|
||||
TString str;
|
||||
str.Form("%lu", firstTimeStamp); timeStamp.AddLine( str.Data() );
|
||||
str.Form("%lu", lastTimeStamp); timeStamp.AddLine( str.Data() );
|
||||
timeStamp.Write("timeStamp");
|
||||
|
||||
unsigned int numBlock = 0;
|
||||
for( int i = 0; i < nFile; i++){
|
||||
//printf("%d | %8ld | %10u/%10u\n", i, reader[i]->GetBlockID() + 1, reader[i]->GetFilePos(), reader[i]->GetFileSize());
|
||||
numBlock += reader[i]->GetBlockID() + 1;
|
||||
}
|
||||
|
||||
printf("===================================== done. \n");
|
||||
printf("Number of Block Scanned : %u\n", numBlock);
|
||||
printf(" Number of Event Built : %lld\n", evID);
|
||||
printf(" Output Root File Size : %.2f MB\n", outRootFile->GetSize()/1024./1024.);
|
||||
printf(" first timestamp : %lu \n", firstTimeStamp);
|
||||
printf(" last timestamp : %lu \n", lastTimeStamp);
|
||||
unsigned long duration = lastTimeStamp - firstTimeStamp;
|
||||
printf(" total duration : %lu = %.2f sec \n", duration, duration * tick2ns * 1.0 / 1e9 );
|
||||
printf("===================================== end of summary. \n");
|
||||
|
||||
|
||||
//^############## delete new
|
||||
for( int i = 0; i < nFile; i++) delete reader[i];
|
||||
delete [] reader;
|
||||
outRootFile->Close();
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -22,38 +22,39 @@ Bool_t GeneralSort::Process(Long64_t entry){
|
|||
|
||||
///initialization
|
||||
for( int i = 0; i < mapping::nDetType; i++){
|
||||
if( mapping::detNum[i] == 0 ) continue;
|
||||
for( int j = 0; j < mapping::detNum[i]; j++){
|
||||
eE[i][j] = TMath::QuietNaN();
|
||||
eT[i][j] = 0;
|
||||
|
||||
if( isTraceExist && traceMethod > 1){
|
||||
if( isTraceExist && traceMethod > 0){
|
||||
teE[i][j] = TMath::QuietNaN();
|
||||
teT[i][j] = TMath::QuietNaN();
|
||||
teR[i][j] = TMath::QuietNaN();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
b_evID->GetEntry(entry);
|
||||
|
||||
multi = 0;
|
||||
b_event_ID->GetEntry(entry);
|
||||
b_multi->GetEntry(entry);
|
||||
b_bd->GetEntry(entry);
|
||||
b_ch->GetEntry(entry);
|
||||
b_e->GetEntry(entry);
|
||||
b_e_t->GetEntry(entry);
|
||||
|
||||
for( unsigned int i = 0 ; i < multi; i++){
|
||||
|
||||
for( int i = 0 ; i < multi; i++){
|
||||
int detID = mapping::map[bd[i]][ch[i]];
|
||||
if( detID < 0 ) continue;
|
||||
int detType = mapping::FindDetTypeIndex(detID);
|
||||
int reducedDetID = detID - (detID/100) * 100;
|
||||
int low = (i == 0 ? 0 : mapping::detMaxID[detType-1]);
|
||||
int reducedDetID = detID - low;
|
||||
|
||||
eE[detType][reducedDetID] = e[i] * mapping::detParity[detType];
|
||||
eT[detType][reducedDetID] = e_t[i];
|
||||
|
||||
}
|
||||
|
||||
//@===================================== Trace
|
||||
if( isTraceExist && traceMethod > 0 ){
|
||||
if( isTraceExist && traceMethod >= 0 ){
|
||||
|
||||
b_tl->GetEntry(entry);
|
||||
b_trace->GetEntry(entry);
|
||||
|
@ -62,9 +63,9 @@ Bool_t GeneralSort::Process(Long64_t entry){
|
|||
|
||||
arr->Clear("C");
|
||||
|
||||
for( unsigned int i = 0; i < multi; i++){
|
||||
for( int i = 0; i < multi; i++){
|
||||
int detID = mapping::map[bd[i]][ch[i]];
|
||||
if( detID < 0 ) continue;
|
||||
|
||||
|
||||
int traceLength = tl[i];
|
||||
gTrace = (TGraph*) arr->ConstructedAt(countTrace, "C");
|
||||
|
@ -79,14 +80,15 @@ Bool_t GeneralSort::Process(Long64_t entry){
|
|||
}
|
||||
|
||||
//***=================== fit
|
||||
if( traceMethod == 2){
|
||||
if( traceMethod == 1){
|
||||
|
||||
int detType = mapping::FindDetTypeIndex(detID);
|
||||
if( mapping::detNum[detType] == 0 ) continue;
|
||||
|
||||
//TODO use a blackList
|
||||
//if( mapping::detTypeName[detType] != "rdt") continue;
|
||||
|
||||
//TODO try custom build fiting algorithm. May be faster?
|
||||
gFit = new TF1("gFit", fitFunc, 0, traceLength, numPara);
|
||||
gFit->SetLineColor(6);
|
||||
gFit->SetRange(0, traceLength);
|
||||
|
||||
gFit->SetParameter(0, e[i]);
|
||||
|
@ -101,17 +103,19 @@ Bool_t GeneralSort::Process(Long64_t entry){
|
|||
|
||||
gTrace->Fit("gFit", "QR", "", 0, traceLength);
|
||||
|
||||
int reducedDetID = detID - (detID/100) * 100;
|
||||
int low = (i == 0 ? 0 : mapping::detMaxID[detType-1]);
|
||||
int reducedDetID = detID - low;
|
||||
|
||||
teE[detType][reducedDetID] = gFit->GetParameter(0);
|
||||
teT[detType][reducedDetID] = gFit->GetParameter(1);
|
||||
teR[detType][reducedDetID] = gFit->GetParameter(2);
|
||||
|
||||
// delete gFit;
|
||||
// gFit = nullptr;
|
||||
delete gFit;
|
||||
gFit = nullptr;
|
||||
}
|
||||
|
||||
//***=================== Trapezoid filter
|
||||
if( traceMethod == 3){
|
||||
if( traceMethod == 2){
|
||||
//TODO
|
||||
}
|
||||
|
||||
|
@ -143,12 +147,12 @@ void GeneralSort::Terminate(){
|
|||
|
||||
printf("=============================== %s\n", __func__);
|
||||
|
||||
// CleanUpMemory(); //? Should Clean?
|
||||
DecodeOption();
|
||||
|
||||
if( !isParallel){
|
||||
stpWatch.Start(kFALSE);
|
||||
saveFile->cd();
|
||||
// newSaveTree->Print("toponly");
|
||||
newSaveTree->Print("toponly");
|
||||
newSaveTree->Write();
|
||||
saveFile->Close();
|
||||
}
|
||||
|
@ -157,8 +161,10 @@ void GeneralSort::Terminate(){
|
|||
saveFile = TFile::Open(saveFileName);
|
||||
if( saveFile->IsOpen() ){
|
||||
TTree * tree = (TTree*) saveFile->FindObjectAny("gen_tree");
|
||||
int validCount = tree->GetEntries();
|
||||
int validCount = tree->GetEntries();
|
||||
|
||||
saveFile->Close();
|
||||
|
||||
printf("=========================================================================\n");
|
||||
PrintTraceMethod();
|
||||
printf("----- saved as \033[1;33m%s\033[0m. valid event: %d\n", saveFileName.Data() , validCount);
|
||||
|
@ -169,9 +175,9 @@ void GeneralSort::Terminate(){
|
|||
//^##############################################################
|
||||
void GeneralSort::Begin(TTree * tree){
|
||||
|
||||
printf( "================================================================================\n");
|
||||
printf( "============================ SOLARIS GeneralSort.C =========================\n");
|
||||
printf( "================================================================================\n");
|
||||
printf( "=================================================================\n");
|
||||
printf( "===================== SOLARIS GeneralSort.C =================\n");
|
||||
printf( "=================================================================\n");
|
||||
|
||||
mapping::PrintMapping();
|
||||
|
||||
|
@ -184,16 +190,16 @@ void GeneralSort::Begin(TTree * tree){
|
|||
}
|
||||
|
||||
void GeneralSort::SlaveBegin(TTree * /*tree*/){
|
||||
|
||||
}
|
||||
|
||||
void GeneralSort::SlaveTerminate(){
|
||||
printf("============= %s\n", __func__);
|
||||
void GeneralSort::SlaveTerminate(){
|
||||
if( isParallel){
|
||||
printf("%s::SaveTree\n", __func__);
|
||||
saveFile->cd();
|
||||
newSaveTree->Write();
|
||||
fOutput->Add(proofFile);
|
||||
saveFile->Close();
|
||||
printf("---- closing this worker\n");
|
||||
}
|
||||
|
||||
}
|
|
@ -50,6 +50,49 @@ double fitFunc(double * x, double * par){
|
|||
return par[3] + par[0] * (1 - TMath::Exp(- (x[0] - par[1]) / par[2]) ) * TMath::Exp(- (x[0] - par[1]) / par[4]);
|
||||
}
|
||||
|
||||
//^######################################### TRAPEZOID
|
||||
TGraph * TrapezoidFilter(TGraph * trace){
|
||||
///Trapezoid filter https://doi.org/10.1016/0168-9002(94)91652-7
|
||||
|
||||
//TODO how to not hard code?
|
||||
int baseLineEnd = 80;
|
||||
int riseTime = 10; //ch
|
||||
int flatTop = 20;
|
||||
float decayTime = 2000;
|
||||
|
||||
TGraph * trapezoid = new TGraph();
|
||||
trapezoid->Clear();
|
||||
|
||||
///find baseline;
|
||||
double baseline = 0;
|
||||
for( int i = 0; i < baseLineEnd; i++){
|
||||
baseline += trace->Eval(i);
|
||||
}
|
||||
baseline = baseline*1./baseLineEnd;
|
||||
|
||||
int length = trace->GetN();
|
||||
|
||||
double pn = 0.;
|
||||
double sn = 0.;
|
||||
for( int i = 0; i < length ; i++){
|
||||
|
||||
double dlk = trace->Eval(i) - baseline;
|
||||
if( i - riseTime >= 0 ) dlk -= trace->Eval(i - riseTime) - baseline;
|
||||
if( i - flatTop - riseTime >= 0 ) dlk -= trace->Eval(i - flatTop - riseTime) - baseline;
|
||||
if( i - flatTop - 2*riseTime >= 0) dlk += trace->Eval(i - flatTop - 2*riseTime) - baseline;
|
||||
|
||||
if( i == 0 ){
|
||||
pn = dlk;
|
||||
sn = pn + dlk*decayTime;
|
||||
}else{
|
||||
pn = pn + dlk;
|
||||
sn = sn + pn + dlk*decayTime;
|
||||
}
|
||||
trapezoid->SetPoint(i, i, sn / decayTime / riseTime);
|
||||
}
|
||||
return trapezoid;
|
||||
}
|
||||
|
||||
TStopwatch stpWatch;
|
||||
|
||||
//^######################################### Class definition
|
||||
|
@ -62,10 +105,10 @@ public :
|
|||
|
||||
// Declaration of leaf types
|
||||
ULong64_t evID;
|
||||
UInt_t multi;
|
||||
UShort_t bd[100]; //[multi]
|
||||
UShort_t ch[100]; //[multi]
|
||||
UShort_t e[100]; //[multi]
|
||||
Int_t multi;
|
||||
Int_t bd[100]; //[multi]
|
||||
Int_t ch[100]; //[multi]
|
||||
Int_t e[100]; //[multi]
|
||||
ULong64_t e_t[100]; //[multi]
|
||||
UShort_t lowFlag[100]; //[multi]
|
||||
UShort_t highFlag[100]; //[multi]
|
||||
|
@ -73,7 +116,7 @@ public :
|
|||
Int_t trace[100][2500]; //[multi]
|
||||
|
||||
// List of branches
|
||||
TBranch *b_evID; //!
|
||||
TBranch *b_event_ID; //!
|
||||
TBranch *b_multi; //!
|
||||
TBranch *b_bd; //!
|
||||
TBranch *b_ch; //!
|
||||
|
@ -88,7 +131,7 @@ public :
|
|||
printf("constructor :: %s\n", __func__);
|
||||
|
||||
isTraceExist = false;
|
||||
traceMethod = 0; // 0 = ignore trace, 1 = no trace fit, 2 = fit, 3 = trapezoid
|
||||
traceMethod = 0; // -1 = ignore trace, 0 = no trace fit, 1 = fit, 2 = trapezoid
|
||||
|
||||
isParallel = false;
|
||||
|
||||
|
@ -129,8 +172,6 @@ public :
|
|||
bool isTraceExist;
|
||||
int traceMethod;
|
||||
|
||||
void CleanUpMemory();
|
||||
|
||||
void SetTraceMethod(int methodID) {traceMethod = methodID;}
|
||||
void PrintTraceMethod();
|
||||
|
||||
|
@ -182,13 +223,12 @@ void GeneralSort::SetUpTree(){
|
|||
newSaveTree->SetDirectory(saveFile);
|
||||
newSaveTree->AutoSave();
|
||||
|
||||
newSaveTree->Branch( "evID", &evID, "evID/l"); // simply copy
|
||||
newSaveTree->Branch( "evID", &evID, "EventID/l"); // simply copy
|
||||
|
||||
eE = new Float_t * [mapping::nDetType];
|
||||
eT = new ULong64_t * [mapping::nDetType];
|
||||
|
||||
for( int i = 0 ; i < mapping::nDetType; i++){
|
||||
if( mapping::detNum[i] == 0 ) continue;
|
||||
eE[i] = new Float_t[mapping::detNum[i]];
|
||||
eT[i] = new ULong64_t[mapping::detNum[i]];
|
||||
|
||||
|
@ -198,26 +238,24 @@ void GeneralSort::SetUpTree(){
|
|||
}
|
||||
|
||||
newSaveTree->Branch( mapping::detTypeName[i].c_str(), eE[i], Form("%s[%d]/F", mapping::detTypeName[i].c_str(), mapping::detNum[i]));
|
||||
newSaveTree->Branch( (mapping::detTypeName[i]+"_t").c_str(), eT[i], Form("%s_t[%d]/l", mapping::detTypeName[i].c_str(), mapping::detNum[i]));
|
||||
newSaveTree->Branch( (mapping::detTypeName[i]+"_t").c_str(), eT[i], Form("%s_Timestamp[%d]/l", mapping::detTypeName[i].c_str(), mapping::detNum[i]));
|
||||
}
|
||||
|
||||
|
||||
if( isTraceExist && traceMethod > 0){
|
||||
if( isTraceExist && traceMethod >= 0){
|
||||
|
||||
arr = new TClonesArray("TGraph");
|
||||
|
||||
newSaveTree->Branch("trace", arr, 256000);
|
||||
arr->BypassStreamer();
|
||||
arr->Clear("C");
|
||||
|
||||
if( traceMethod > 1 ){
|
||||
if( traceMethod > 0 ){
|
||||
|
||||
teE = new Float_t * [mapping::nDetType];
|
||||
teT = new Float_t * [mapping::nDetType];
|
||||
teR = new Float_t * [mapping::nDetType];
|
||||
|
||||
for( int i = 0 ; i < mapping::nDetType; i++){
|
||||
if( mapping::detNum[i] == 0 ) continue;
|
||||
teE[i] = new Float_t[mapping::detNum[i]];
|
||||
teT[i] = new Float_t[mapping::detNum[i]];
|
||||
teR[i] = new Float_t[mapping::detNum[i]];
|
||||
|
@ -231,14 +269,14 @@ void GeneralSort::SetUpTree(){
|
|||
//TODO use a blackList to skip some trace
|
||||
|
||||
newSaveTree->Branch( ("w" + mapping::detTypeName[i]).c_str(), teE[i], Form("trace_%s[%d]/F", mapping::detTypeName[i].c_str(), mapping::detNum[i]));
|
||||
newSaveTree->Branch( ("w" + mapping::detTypeName[i]+"T").c_str(), teT[i], Form("trace_%s_time[%d]/F", mapping::detTypeName[i].c_str(), mapping::detNum[i]));
|
||||
newSaveTree->Branch( ("w" + mapping::detTypeName[i]+"R").c_str(), teR[i], Form("trace_%s_rise[%d]/F", mapping::detTypeName[i].c_str(), mapping::detNum[i]));
|
||||
newSaveTree->Branch( ("w" + mapping::detTypeName[i]+"T").c_str(), teT[i], Form("trace_%s_time[%d]/l", mapping::detTypeName[i].c_str(), mapping::detNum[i]));
|
||||
newSaveTree->Branch( ("w" + mapping::detTypeName[i]+"R").c_str(), teR[i], Form("trace_%s_rise[%d]/l", mapping::detTypeName[i].c_str(), mapping::detNum[i]));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if( !isParallel ) newSaveTree->Print("toponly");
|
||||
newSaveTree->Print("toponly"); //very important, otherwise the mac will blow up.
|
||||
}
|
||||
|
||||
//^##############################################################
|
||||
|
@ -255,21 +293,19 @@ void GeneralSort::DecodeOption(){
|
|||
isParallel = false;
|
||||
}
|
||||
|
||||
PrintTraceMethod();
|
||||
printf(" Parallel: %s \n", isParallel ? "Yes" : "No");
|
||||
printf(" save file: %s \n", saveFileName.Data());
|
||||
printf("|%s| %d %s %d \n", option.Data(), traceMethod, saveFileName.Data(), isParallel);
|
||||
|
||||
}
|
||||
|
||||
//^##############################################################
|
||||
void GeneralSort::Init(TTree *tree){
|
||||
printf("============= %s\n", __func__);
|
||||
|
||||
// Set branch addresses and branch pointers
|
||||
if (!tree) return;
|
||||
fChain = tree;
|
||||
fChain->SetMakeClass(1);
|
||||
|
||||
fChain->SetBranchAddress("evID", &evID, &b_evID);
|
||||
fChain->SetBranchAddress("evID", &evID, &b_event_ID);
|
||||
fChain->SetBranchAddress("multi", &multi, &b_multi);
|
||||
fChain->SetBranchAddress("bd", bd, &b_bd);
|
||||
fChain->SetBranchAddress("ch", ch, &b_ch);
|
||||
|
@ -278,27 +314,30 @@ void GeneralSort::Init(TTree *tree){
|
|||
fChain->SetBranchAddress("lowFlag", lowFlag, &b_lowFlag);
|
||||
fChain->SetBranchAddress("highFlag", highFlag, &b_highFlag);
|
||||
|
||||
TBranch * br = (TBranch *) fChain->GetListOfBranches()->FindObject("traceLen");
|
||||
TBranch * br = (TBranch *) fChain->GetListOfBranches()->FindObject("tl");
|
||||
if( br == NULL ){
|
||||
printf(" ++++++++ no Trace.\n");
|
||||
isTraceExist = false;
|
||||
}else{
|
||||
printf(" ++++++++ Found Trace.\n");
|
||||
isTraceExist = true;
|
||||
fChain->SetBranchAddress("traceLen", tl, &b_tl);
|
||||
fChain->SetBranchAddress("tl", tl, &b_tl);
|
||||
fChain->SetBranchAddress("trace", trace, &b_trace);
|
||||
}
|
||||
|
||||
NumEntries = fChain->GetEntries();
|
||||
printf( " ======== total Entry : %ld\n", NumEntries);
|
||||
printf( " ========== total Entry : %ld\n", NumEntries);
|
||||
|
||||
//########################### Get Option
|
||||
DecodeOption();
|
||||
|
||||
SetUpTree();
|
||||
if( isTraceExist ){
|
||||
PrintTraceMethod();
|
||||
}else{
|
||||
printf("++++++++ no Trace found\n");
|
||||
}
|
||||
|
||||
gFit = new TF1("gFit", fitFunc, 0, 1250, numPara);
|
||||
gFit->SetLineColor(6);
|
||||
SetUpTree();
|
||||
|
||||
printf("---- end of Init %s\n ", __func__);
|
||||
|
||||
|
@ -311,49 +350,13 @@ Bool_t GeneralSort::Notify(){
|
|||
void GeneralSort::PrintTraceMethod(){
|
||||
const char* traceMethodStr;
|
||||
switch(traceMethod) {
|
||||
case 0 : traceMethodStr = "Ignore Trace"; break;
|
||||
case 1 : traceMethodStr = "None and Copy Trace"; break;
|
||||
case 2 : traceMethodStr = "Fit"; break;
|
||||
case 3 : traceMethodStr = "Trapezoid"; break;
|
||||
case -1 : traceMethodStr = "Ignore Trace"; break;
|
||||
case 0 : traceMethodStr = "Copy"; break;
|
||||
case 1 : traceMethodStr = "Fit"; break;
|
||||
case 2 : traceMethodStr = "Trapezoid"; break;
|
||||
default: traceMethodStr = "Unknown"; break;
|
||||
}
|
||||
printf("\033[1;33m ===== Trace method ? %s (%d) \033[m\n", traceMethodStr, traceMethod);
|
||||
}
|
||||
|
||||
void GeneralSort::CleanUpMemory(){
|
||||
printf("Clean up memory");
|
||||
if( traceMethod > 1 ){
|
||||
for( int i = 0 ; i < mapping::nDetType; i++){
|
||||
if( mapping::detNum[i] == 0 ) continue;
|
||||
delete [] teE[i];
|
||||
delete [] teT[i];
|
||||
delete [] teR[i];
|
||||
|
||||
delete [] eE[i];
|
||||
delete [] eT[i];
|
||||
}
|
||||
delete [] teE;
|
||||
delete [] teT;
|
||||
delete [] teR;
|
||||
}
|
||||
|
||||
for( int i = 0 ; i < mapping::nDetType; i++){
|
||||
if( mapping::detNum[i] == 0 ) continue;
|
||||
delete [] eE[i];
|
||||
delete [] eT[i];
|
||||
}
|
||||
delete [] eE;
|
||||
delete [] eT;
|
||||
|
||||
//trace
|
||||
if( arr ) delete arr ;
|
||||
if( gTrace ) delete gTrace;
|
||||
if( gFit ) delete gFit;
|
||||
if( arrTrapezoid ) delete arrTrapezoid ;
|
||||
if( gTrapezoid ) delete gTrapezoid;
|
||||
|
||||
printf(".... done\n");
|
||||
|
||||
printf("\033[1;33m ===== Trace method ? %s \033[m\n", traceMethodStr);
|
||||
}
|
||||
|
||||
#endif // #ifdef GeneralSort_cxx
|
|
@ -1,11 +1,11 @@
|
|||
|
||||
#include "TTree.h"
|
||||
#include "TProof.h"
|
||||
#include "TChain.h"
|
||||
#include "TMacro.h"
|
||||
#include "TFile.h"
|
||||
#include "TProof.h"
|
||||
|
||||
void GeneralSortAgent(Int_t runNum, int nWorker = 1, int traceMethod = 0){
|
||||
void GeneralSortAgent(Int_t runNum, int nWorker = 1, int traceMethod = -1){
|
||||
|
||||
TString name;
|
||||
name.Form("../root_data/run%03d.root", runNum);
|
||||
|
@ -25,7 +25,7 @@ void GeneralSortAgent(Int_t runNum, int nWorker = 1, int traceMethod = 0){
|
|||
if( abs(nWorker) == 1){
|
||||
|
||||
option.Form("%d,../root_data/gen_run%03d.root,%d", traceMethod, runNum, 0);
|
||||
chain->Process("../Armory/GeneralSort.C+", option);
|
||||
chain->Process("../armory/GeneralSort.C+", option);
|
||||
|
||||
}else{
|
||||
|
||||
|
@ -35,7 +35,7 @@ void GeneralSortAgent(Int_t runNum, int nWorker = 1, int traceMethod = 0){
|
|||
|
||||
chain->SetProof();
|
||||
option.Form("%d,../root_data/gen_run%03d.root,%d", traceMethod, runNum, 1);
|
||||
chain->Process("../Armory/GeneralSort.C+", option);
|
||||
chain->Process("../armory/GeneralSort.C+", option);
|
||||
}
|
||||
|
||||
//========== open the output root and copy teh timestamp Marco
|
287
armory/Hit.h
Normal file
|
@ -0,0 +1,287 @@
|
|||
#ifndef HIT_H
|
||||
#define HIT_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <cstdlib>
|
||||
#include <stdint.h>
|
||||
#include <string>
|
||||
|
||||
#define MaxTraceLenght 8100
|
||||
|
||||
enum DataFormat{
|
||||
|
||||
ALL = 0x00,
|
||||
OneTrace = 0x01,
|
||||
NoTrace = 0x02,
|
||||
Minimum = 0x03,
|
||||
MiniWithFineTime = 0x04,
|
||||
Raw = 0x0A,
|
||||
|
||||
};
|
||||
|
||||
namespace DPPType{
|
||||
|
||||
const std::string PHA = "DPP_PHA";
|
||||
const std::string PSD = "DPP_PSD";
|
||||
|
||||
};
|
||||
|
||||
class Hit {
|
||||
public:
|
||||
|
||||
unsigned short dataType;
|
||||
std::string DPPType;
|
||||
|
||||
///============= for dpp-pha
|
||||
uint8_t channel; // 6 bit
|
||||
uint16_t energy; // 16 bit
|
||||
uint16_t energy_short; // 16 bit, only for PSD
|
||||
uint64_t timestamp; // 48 bit
|
||||
uint16_t fine_timestamp; // 16 bit
|
||||
uint16_t flags_low_priority; // 12 bit
|
||||
uint16_t flags_high_priority; // 8 bit
|
||||
size_t traceLenght; // 64 bit
|
||||
uint8_t downSampling; // 8 bit
|
||||
bool board_fail;
|
||||
bool flush;
|
||||
uint8_t analog_probes_type[2]; // 3 bit for PHA, 4 bit for PSD
|
||||
uint8_t digital_probes_type[4]; // 4 bit for PHA, 5 bit for PSD
|
||||
int32_t * analog_probes[2]; // 18 bit
|
||||
uint8_t * digital_probes[4]; // 1 bit
|
||||
uint16_t trigger_threashold; // 16 bit
|
||||
size_t event_size; // 64 bit
|
||||
uint32_t aggCounter; // 32 bit
|
||||
|
||||
///============= for raw
|
||||
uint8_t * data;
|
||||
size_t dataSize; /// number of byte of the data, size/8 = word [64 bits]
|
||||
uint32_t n_events;
|
||||
|
||||
bool isTraceAllZero;
|
||||
|
||||
Hit(){
|
||||
Init();
|
||||
}
|
||||
|
||||
~Hit(){
|
||||
ClearMemory();
|
||||
}
|
||||
|
||||
void Init(){
|
||||
DPPType = DPPType::PHA;
|
||||
dataType = DataFormat::ALL;
|
||||
|
||||
channel = 0;
|
||||
energy = 0;
|
||||
energy_short = 0;
|
||||
timestamp = 0;
|
||||
fine_timestamp = 0;
|
||||
downSampling = 0;
|
||||
board_fail = false;
|
||||
flush = false;
|
||||
flags_low_priority = 0;
|
||||
flags_high_priority = 0;
|
||||
trigger_threashold = 0;
|
||||
event_size = 0;
|
||||
aggCounter = 0;
|
||||
analog_probes[0] = NULL;
|
||||
analog_probes[1] = NULL;
|
||||
digital_probes[0] = NULL;
|
||||
digital_probes[1] = NULL;
|
||||
digital_probes[2] = NULL;
|
||||
digital_probes[3] = NULL;
|
||||
|
||||
analog_probes_type[0] = 0xFF;
|
||||
analog_probes_type[1] = 0xFF;
|
||||
digital_probes_type[0] = 0xFF;
|
||||
digital_probes_type[1] = 0xFF;
|
||||
digital_probes_type[2] = 0xFF;
|
||||
digital_probes_type[3] = 0xFF;
|
||||
data = NULL;
|
||||
|
||||
isTraceAllZero = true; // indicate trace are all zero
|
||||
}
|
||||
|
||||
void ClearMemory(){
|
||||
if( data != NULL ) delete data;
|
||||
|
||||
if( analog_probes[0] != NULL) delete analog_probes[0];
|
||||
if( analog_probes[1] != NULL) delete analog_probes[1];
|
||||
|
||||
if( digital_probes[0] != NULL) delete digital_probes[0];
|
||||
if( digital_probes[1] != NULL) delete digital_probes[1];
|
||||
if( digital_probes[2] != NULL) delete digital_probes[2];
|
||||
if( digital_probes[3] != NULL) delete digital_probes[3];
|
||||
|
||||
isTraceAllZero = true;
|
||||
}
|
||||
|
||||
void SetDataType(unsigned int type, std::string dppType){
|
||||
dataType = type;
|
||||
DPPType = dppType;
|
||||
ClearMemory();
|
||||
|
||||
if( dataType == DataFormat::Raw){
|
||||
data = new uint8_t[20*1024*1024];
|
||||
}else{
|
||||
analog_probes[0] = new int32_t[MaxTraceLenght];
|
||||
analog_probes[1] = new int32_t[MaxTraceLenght];
|
||||
|
||||
digital_probes[0] = new uint8_t[MaxTraceLenght];
|
||||
digital_probes[1] = new uint8_t[MaxTraceLenght];
|
||||
digital_probes[2] = new uint8_t[MaxTraceLenght];
|
||||
digital_probes[3] = new uint8_t[MaxTraceLenght];
|
||||
|
||||
isTraceAllZero = true;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void ClearTrace(){
|
||||
if( isTraceAllZero ) return; // no need to clear again
|
||||
|
||||
for( int i = 0; i < MaxTraceLenght; i++){
|
||||
analog_probes[0][i] = 0;
|
||||
analog_probes[1][i] = 0;
|
||||
|
||||
digital_probes[0][i] = 0;
|
||||
digital_probes[1][i] = 0;
|
||||
digital_probes[2][i] = 0;
|
||||
digital_probes[3][i] = 0;
|
||||
}
|
||||
isTraceAllZero = true;
|
||||
}
|
||||
|
||||
void PrintEnergyTimeStamp(){
|
||||
printf("ch: %2d, energy: %u, timestamp: %lu ch, traceLenght: %lu\n", channel, energy, timestamp, traceLenght);
|
||||
}
|
||||
|
||||
std::string AnaProbeType(uint8_t probeType){
|
||||
|
||||
if( DPPType == DPPType::PHA){
|
||||
switch(probeType){
|
||||
case 0: return "ADC";
|
||||
case 1: return "Time filter";
|
||||
case 2: return "Energy filter";
|
||||
default : return "none";
|
||||
}
|
||||
}else if (DPPType == DPPType::PSD){
|
||||
switch(probeType){
|
||||
case 0: return "ADC";
|
||||
case 9: return "Baseline";
|
||||
case 10: return "CFD";
|
||||
default : return "none";
|
||||
}
|
||||
}else{
|
||||
return "none";
|
||||
}
|
||||
}
|
||||
|
||||
std::string DigiProbeType(uint8_t probeType){
|
||||
|
||||
if( DPPType == DPPType::PHA){
|
||||
switch(probeType){
|
||||
case 0: return "Trigger";
|
||||
case 1: return "Time filter armed";
|
||||
case 2: return "Re-trigger guard";
|
||||
case 3: return "Energy filter baseline freeze";
|
||||
case 4: return "Energy filter peaking";
|
||||
case 5: return "Energy filter peaking ready";
|
||||
case 6: return "Energy filter pile-up guard";
|
||||
case 7: return "Event pile-up";
|
||||
case 8: return "ADC saturation";
|
||||
case 9: return "ADC saturation protection";
|
||||
case 10: return "Post-saturation event";
|
||||
case 11: return "Energy filter saturation";
|
||||
case 12: return "Signal inhibit";
|
||||
default : return "none";
|
||||
}
|
||||
}else if (DPPType == DPPType::PSD){
|
||||
switch(probeType){
|
||||
case 0: return "Trigger";
|
||||
case 1: return "CFD Filter Armed";
|
||||
case 2: return "Re-trigger guard";
|
||||
case 3: return "ADC Input Baseline freeze";
|
||||
case 20: return "ADC Input OverThreshold";
|
||||
case 21: return "Charge Ready";
|
||||
case 22: return "Long Gate";
|
||||
case 7: return "Pile-Up Trig.";
|
||||
case 24: return "Short Gate";
|
||||
case 25: return "Energy Saturation";
|
||||
case 26: return "Charge over-range";
|
||||
case 27: return "ADC Input Neg. OverThreshold";
|
||||
default : return "none";
|
||||
}
|
||||
|
||||
}else{
|
||||
return "none";
|
||||
}
|
||||
}
|
||||
|
||||
std::string HighPriority(uint16_t prio){
|
||||
std::string output;
|
||||
|
||||
bool pileup = prio & 0x1;
|
||||
//bool pileupGuard = (prio >> 1) & 0x1;
|
||||
//bool eventSaturated = (prio >> 2) & 0x1;
|
||||
//bool postSatEvent = (prio >> 3) & 0x1;
|
||||
//bool trapSatEvent = (prio >> 4) & 0x1;
|
||||
//bool SCA_Event = (prio >> 5) & 0x1;
|
||||
|
||||
output = std::string("Pile-up: ") + (pileup ? "Yes" : "No");
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
//TODO LowPriority
|
||||
|
||||
void PrintAll(){
|
||||
|
||||
switch(dataType){
|
||||
case DataFormat::ALL : printf("============= Type : ALL\n"); break;
|
||||
case DataFormat::OneTrace : printf("============= Type : OneTrace\n"); break;
|
||||
case DataFormat::NoTrace : printf("============= Type : NoTrace\n"); break;
|
||||
case DataFormat::MiniWithFineTime : printf("============= Type : Min with FineTimestamp\n"); break;
|
||||
case DataFormat::Minimum : printf("============= Type : Minimum\n"); break;
|
||||
case DataFormat::Raw : printf("============= Type : Raw\n"); return; break;
|
||||
default : return;
|
||||
}
|
||||
|
||||
printf("ch : %2d (0x%02X), fail: %d, flush: %d\n", channel, channel, board_fail, flush);
|
||||
if( DPPType == DPPType::PHA ) printf("energy: %u, timestamp: %lu, fine_timestamp: %u \n", energy, timestamp, fine_timestamp);
|
||||
if( DPPType == DPPType::PSD ) printf("energy: %u, energy_S : %u, timestamp: %lu, fine_timestamp: %u \n", energy, energy_short, timestamp, fine_timestamp);
|
||||
printf("flag (high): 0x%02X, (low): 0x%03X, traceLength: %lu\n", flags_high_priority, flags_low_priority, traceLenght);
|
||||
printf("Agg counter : %u, trigger Thr.: %u, downSampling: %u \n", aggCounter, trigger_threashold, downSampling);
|
||||
printf("AnaProbe Type: %s(%u), %s(%u)\n", AnaProbeType(analog_probes_type[0]).c_str(), analog_probes_type[0],
|
||||
AnaProbeType(analog_probes_type[1]).c_str(), analog_probes_type[1]);
|
||||
printf("DigProbe Type: %s(%u), %s(%u), %s(%u), %s(%u)\n", DigiProbeType(digital_probes_type[0]).c_str(), digital_probes_type[0],
|
||||
DigiProbeType(digital_probes_type[1]).c_str(), digital_probes_type[1],
|
||||
DigiProbeType(digital_probes_type[2]).c_str(), digital_probes_type[2],
|
||||
DigiProbeType(digital_probes_type[3]).c_str(), digital_probes_type[3]);
|
||||
}
|
||||
|
||||
void PrintTrace(unsigned short ID){
|
||||
for(unsigned short i = 0; i < (unsigned short)traceLenght; i++){
|
||||
if( ID == 0 ) printf("%4d| %6d\n", i, analog_probes[0][i]);
|
||||
if( ID == 1 ) printf("%4d| %6d\n", i, analog_probes[1][i]);
|
||||
if( ID == 2 ) printf("%4d| %u\n", i, digital_probes[0][i]);
|
||||
if( ID == 3 ) printf("%4d| %u\n", i, digital_probes[1][i]);
|
||||
if( ID == 4 ) printf("%4d| %u\n", i, digital_probes[2][i]);
|
||||
if( ID == 5 ) printf("%4d| %u\n", i, digital_probes[3][i]);
|
||||
}
|
||||
}
|
||||
|
||||
void PrintAllTrace(){
|
||||
for(unsigned short i = 0; i < (unsigned short)traceLenght; i++){
|
||||
printf("%4d| %6d %6d %1d %1d %1d %1d\n", i, analog_probes[0][i],
|
||||
analog_probes[1][i],
|
||||
digital_probes[0][i],
|
||||
digital_probes[1][i],
|
||||
digital_probes[2][i],
|
||||
digital_probes[3][i]);
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
#endif
|
12
armory/Makefile
Normal file
|
@ -0,0 +1,12 @@
|
|||
CC=g++
|
||||
CFLAG= -g
|
||||
ROOTFLAG=`root-config --cflags --glibs`
|
||||
|
||||
all: EventBuilder
|
||||
|
||||
EventBuilder: EventBuilder.cpp SolReader.h Hit.h
|
||||
$(CC) $(CFLAG) EventBuilder.cpp -o EventBuilder ${ROOTFLAG}
|
||||
|
||||
|
||||
clean:
|
||||
-rm EventBuilder
|
73
armory/Process_BasicConfig
Normal file
|
@ -0,0 +1,73 @@
|
|||
#!/bin/bash -l
|
||||
|
||||
##############################################
|
||||
#
|
||||
# This script define color, PCID, and dataPath
|
||||
#
|
||||
##############################################
|
||||
|
||||
if [ ! -z $RED ]; then
|
||||
echo "Process_BasicConfig already loaded."
|
||||
return
|
||||
fi
|
||||
|
||||
RED='\033[1;31m'
|
||||
YELLOW='\033[1;33m'
|
||||
ORANGE='\033[0;33m'
|
||||
GREEN='\033[1;32m'
|
||||
BLUE='\033[0;34m'
|
||||
CYAN='\033[0;36m'
|
||||
NC='\033[0m' #no color
|
||||
LRED='\033[1;91m'
|
||||
|
||||
############## need to distingish mac and daq
|
||||
Arch="$(uname -s)"
|
||||
PCName="$(hostname)"
|
||||
PCID=-1 #if PCID == 1 (DAQ), 2 (MAC), -1(OTHER)
|
||||
|
||||
#------ Set up data folder, check disk space
|
||||
echo -e "${YELLOW} ##################### Check computer name and arch. ${NC}"
|
||||
echo "PC name : ${PCName}"
|
||||
echo "Archetech: ${Arch}"
|
||||
|
||||
if [ ${Arch} == "Linux" ] && [ ${PCName} == "solaris-daq" ]; then
|
||||
|
||||
PCID=1
|
||||
|
||||
pathsSetting=${HOME}/SOLARIS_QT6_DAQ/programSettings.txt
|
||||
if [ -e ${pathsSetting} ]; then
|
||||
#echo "Found DAQ programSettings.txt for paths settings"
|
||||
|
||||
analysisPath=$(cat ${pathsSetting} | head -n 2 | tail -n 1)
|
||||
|
||||
if [ ! "${analysisPath}" = "$SOLARISANADIR" ]; then
|
||||
echo "The analysisPath from ${analysisPath} is different from present folder $SOLARISANADIR. Abort."
|
||||
exit
|
||||
fi
|
||||
|
||||
rawDataPathParent=$(cat ${pathsSetting} | head -n 3 | tail -n 1)
|
||||
rootDataPathParent=$(cat ${pathsSetting} | head -n 4 | tail -n 1)
|
||||
|
||||
databaseIP=$(cat ${pathsSetting} | head -n 6 | tail -n 1)
|
||||
databaseName=$(cat ${pathsSetting} | head -n 7 | tail -n 1)
|
||||
|
||||
#echo ${rawDataPathParent}
|
||||
#echo ${rootDataPathParent}
|
||||
#echo ${databaseIP}
|
||||
#echo ${databaseName}
|
||||
|
||||
else
|
||||
|
||||
echo "${RED} Cannot found DAQ programSettings.txt for path settings ${NC}"
|
||||
echo "Seek Ryan for help"
|
||||
exit
|
||||
|
||||
fi
|
||||
|
||||
fi
|
||||
|
||||
if [ ${Arch} == "Darwin" ] && [ ${PCName} == "SOLARISs-Mac-Studio.local" ]; then
|
||||
PCID=2
|
||||
rawDataPathParent=${HOME}/experimentalData/
|
||||
rootDataPathParent=${HOME}/experimentalData/
|
||||
fi
|
|
@ -1,7 +1,5 @@
|
|||
#!/bin/bash
|
||||
|
||||
echo -e "${RED}##################### Loading Process_Download.sh ${NC}"
|
||||
|
||||
if [ $# -eq 0 ] || [ $1 == "-help" ]; then
|
||||
echo "$./process_Download [RunNum]"
|
||||
echo " RunNum = run number"
|
||||
|
@ -13,12 +11,10 @@ RUN=$1
|
|||
runNum=${RUN#0} #remove zero
|
||||
RUN=$(printf '%03d' $runNum) ##add back the zero
|
||||
|
||||
source $SOLARISANADIR/Armory/Process_BasicConfig
|
||||
|
||||
if [ -z $expName ]; then
|
||||
source $SOLARISANADIR/working/expName.sh
|
||||
fi
|
||||
source $SOLARISANADIR/armory/Process_BasicConfig
|
||||
source $SOLARISANADIR/working/expName.sh
|
||||
|
||||
MacRawDataPath=$rawDataPathParent/$expName/
|
||||
IP=solarisdaq # defined at ~/.ssh/config
|
||||
USR=solaris
|
||||
|
||||
|
@ -46,7 +42,7 @@ if [ ${RUN} == "all" ]; then
|
|||
fi
|
||||
|
||||
echo -e "$YELLOW=============================================$NC"
|
||||
tail -10 $MacRawDataPath/raw_data/RunTimeStamp.dat
|
||||
tail -10 $MacRawDataPath/data/RunTimeStamp.dat
|
||||
echo -e "$YELLOW=============================================$NC"
|
||||
|
||||
exit 1
|
||||
|
@ -64,7 +60,7 @@ RUN=$(printf '%03d' ${RUN})
|
|||
|
||||
#######################################
|
||||
#################### Download raw data
|
||||
echo -e "${CYAN}>>>>>>>>>>>>>>> Download raw data: run ${RUN}${NC}"
|
||||
echo -e "${RED}######################### Download raw data: run ${RUN}${NC}"
|
||||
if [ ${PCID} -eq 2 ]; then
|
||||
|
||||
#=========== Ping to check the connectivity
|
||||
|
@ -85,25 +81,25 @@ if [ ${PCID} -eq 2 ]; then
|
|||
rsync -avuht --progress $USR@$IP:Analysis/working/expName.sh $SOLARISANADIR/working/.
|
||||
fi
|
||||
else
|
||||
echo -e "$CYAN############### Only in SOLARIS MAC can donwload data. skip.$NC"
|
||||
echo -e "$RED############### Only in SOLARIS MAC can donwload data. skip.$NC"
|
||||
fi
|
||||
|
||||
if [ -z ${rawDataPath}/RunTimeStamp.dat ]; then
|
||||
echo -e "$YELLOW=============================================$NC"
|
||||
tail -10 ${rawDataPath}/RunTimeStamp.dat
|
||||
echo -e "$YELLOW=============================================$NC"
|
||||
fi
|
||||
echo -e "$YELLOW=============================================$NC"
|
||||
tail -10 $MacRawDataPath/data/RunTimeStamp.dat
|
||||
echo -e "$YELLOW=============================================$NC"
|
||||
|
||||
count=`ls -1 ${rawDataPath}/${expName}_${RUN}_*.sol 2>/dev/null | wc -l`
|
||||
echo -e "========================= Number of Files : ${count}${YELLOW}"
|
||||
count=`ls -1 $SOLARISANADIR/data_raw/${expName}_${RUN}_*.sol 2>/dev/null | wc -l`
|
||||
echo -e "========== Number of Files : ${count}${NC}"
|
||||
if [ ${count} -eq 0 ]; then
|
||||
echo "${NC}============================================"
|
||||
echo "============================================"
|
||||
echo "==== RAW Files of RUN-${RUN} not found! "
|
||||
echo "============================================"
|
||||
|
||||
isRunDataExist=false
|
||||
exit 1
|
||||
else
|
||||
du -hc ${rawDataPath}//${expName}_${RUN}_*.sol
|
||||
echo -e "${YELLOW}"
|
||||
du -hc $SOLARISANADIR/data_raw/${expName}_${RUN}_*.sol
|
||||
echo -e "$NC============================================="
|
||||
isRunDataExist=true
|
||||
fi
|
|
@ -1,21 +1,11 @@
|
|||
#!/bin/bash
|
||||
|
||||
echo -e "${RED}##################### Loading Process_EventBuilder.sh ${NC}"
|
||||
|
||||
if [ -z $SOLARISANADIR ]; then
|
||||
echo "###### env variable SOLARISANADIR not defined. Abort. Please run the SOLARIS.sh."
|
||||
echo "better add \"source <path_to_SOLARIS.sh>\" into .bashrc"
|
||||
exit
|
||||
fi
|
||||
|
||||
if command -v EventBuilder > /dev/null 2>&1; then
|
||||
echo "EventBuilder exists"
|
||||
else
|
||||
echo -e "${RED}EventBuilder does not exist${NC}"
|
||||
echo -e "${RED}Create a symbolic link of the EventBuilder from the SOLARIS_DAQ/Aux/${NC}"
|
||||
exit
|
||||
fi
|
||||
|
||||
if [ $# -ne 3 ] || [ $1 == "-help" ]; then
|
||||
echo "$ Process_EventBuilder [RunNum] [EventBuild] [timeWin]"
|
||||
echo " RunNum = run number"
|
||||
|
@ -29,17 +19,23 @@ RUN=$1
|
|||
EventBld=$2
|
||||
timeWin=$3
|
||||
|
||||
source ${SOLARISANADIR}/Armory/Process_BasicConfig
|
||||
if [ -z $expName ]; then
|
||||
source $SOLARISANADIR/working/expName.sh
|
||||
fi
|
||||
source ${SOLARISANADIR}/armory/Process_BasicConfig
|
||||
source ${SOLARISANADIR}/working/expName.sh
|
||||
|
||||
runNum=${RUN#0} #remove zero
|
||||
RUN=$(printf '%03d' $runNum) ##add back the zero
|
||||
|
||||
rawDataPath=$SOLARISANADIR/data_raw
|
||||
rootDataPath=$SOLARISANADIR/root_data
|
||||
|
||||
rawDataPattern="$rawDataPath/${expName}_${RUN}_*.sol"
|
||||
rootDataName="$rootDataPath/run$RUN.root"
|
||||
|
||||
dir=$(pwd)
|
||||
cd ${SOLARISANADIR}/armory
|
||||
make
|
||||
cd ${dir}
|
||||
|
||||
#==== check raw data exist
|
||||
isRawDataExist=`ls -1 ${rawDataPattern}* 2>/dev/null | wc -l`
|
||||
|
||||
|
@ -48,10 +44,11 @@ if [ ! $isRawDataExist -gt 0 ]; then
|
|||
exit
|
||||
fi
|
||||
|
||||
echo -e "${YELLOW} ============== list of files ${NC}"
|
||||
echo -e "${CYAN} ============== list of files ${NC}"
|
||||
\du -h ${rawDataPattern}*
|
||||
|
||||
totSize=$(\du -hc ${rawDataPattern}* | tail -n 1 | awk '{print $1}')
|
||||
echo -e "${YELLOW} ============== total file size : ${totSize}${NC}"
|
||||
echo -e "${CYAN} ============== total file size : ${totSize}${NC}"
|
||||
|
||||
|
||||
#==== check raw data timeStamp
|
|
@ -9,27 +9,16 @@ if [ -z $SOLARISANADIR ]; then
|
|||
exit
|
||||
fi
|
||||
|
||||
if [ "$PWD" != "${SOLARISANADIR}/working" ]; then
|
||||
echo "============= go to the Working directory"
|
||||
cd "${SOLARISANADIR}/working"
|
||||
fi
|
||||
|
||||
if [ $# -eq 0 ] || [ $1 == "-help" ]; then
|
||||
echo "$ Process_Run [RunNum] [EventBuild] [GeneralSort] [Monitor]"
|
||||
echo "$ Process_Run [RunNum] [EventBuild] [GeneralSort] [TraceMethod] [Monitor]"
|
||||
echo " RunNum = run number / \"lastRun\" "
|
||||
echo " EventBld = 2/1/0/-1/-2 || 2 = with Trace"
|
||||
echo " GeneralSort = n/0/-n || n = number of worker + TraceMethod * 100"
|
||||
echo " TraceMethod = 0 no trace"
|
||||
echo " = 1 save trace"
|
||||
echo " = 2 WS fit"
|
||||
echo " = 3 trapezoid(not implemented)"
|
||||
echo " e.g. 208 = WS trace with 8 workers"
|
||||
|
||||
#======== change Monitor to Action.
|
||||
|
||||
echo " GeneralSort = n/0/-n || n = number of worker"
|
||||
echo " TraceMethod = -1/0/1/2 || -1 no trace, 0 save trace, 1 fit, 2 trapezoid(not implemented)"
|
||||
echo " Monitor = 2/1/0 || 1 = single run, 2 = using the list in ChainMonitors.C"
|
||||
echo ""
|
||||
echo " * negative option = force."
|
||||
echo " * negative option = force (except for TraceMethod and Monitor)."
|
||||
echo " * Defult timeWindow for Event builder is 100 tick = 800 ns."
|
||||
echo ""
|
||||
exit 1
|
||||
|
@ -37,25 +26,22 @@ fi;
|
|||
|
||||
RUN=$1
|
||||
runNum=$1
|
||||
EventBld=1
|
||||
EventBld=2
|
||||
nWorker=1
|
||||
TraceMethod=0
|
||||
TraceMethod=-1
|
||||
isMonitor=1
|
||||
|
||||
if [ $# -ge 2 ]; then EventBld=$2; fi
|
||||
if [ $# -ge 3 ]; then nWorker=$3; fi
|
||||
if [ $# -ge 4 ]; then isMonitor=$4; fi
|
||||
if [ $# -ge 4 ]; then TraceMethod=$4; fi
|
||||
if [ $# -ge 5 ]; then isMonitor=$5; fi
|
||||
|
||||
|
||||
temp=$((nWorker / 100));
|
||||
if [ $temp -lt 0 ]; then
|
||||
TraceMethod=$((-1 * temp));
|
||||
if [ "$RUN" == "lastRun" ]; then
|
||||
RUN=$runID
|
||||
fi
|
||||
|
||||
nWorker=$((nWorker % 100 ));
|
||||
|
||||
runNum=${RUN#0} #remove zero
|
||||
RUN=$(printf '%03d' $runNum) ##add back the zero
|
||||
RUN=${RUN##*(0)} #remove zero
|
||||
RUN=$(printf '%03d' $RUN) ##add back the zero
|
||||
|
||||
################################### Setting display
|
||||
echo "#################################################"
|
||||
|
@ -68,11 +54,17 @@ echo "### Trace Method : $TraceMethod"
|
|||
echo "### Monitor : $isMonitor"
|
||||
echo "#################################################"
|
||||
|
||||
source ${SOLARISANADIR}/Armory/Process_BasicConfig
|
||||
source ${rawDataPath}/expName.sh
|
||||
source ${SOLARISANADIR}/armory/Process_BasicConfig
|
||||
source ${SOLARISANADIR}/working/expName.sh
|
||||
|
||||
if [ "$PWD" != "${SOLARISANADIR}/working" ]; then
|
||||
echo "============= go to the Working directory"
|
||||
cd "${SOLARISANADIR}/working"
|
||||
fi
|
||||
|
||||
|
||||
#################################### CHECK IS RUN DATA EXIST
|
||||
isRunDataExist=false
|
||||
isRunDataExist=true
|
||||
|
||||
#################################### EVENT BUILDER
|
||||
source Process_Download $RUN
|
||||
|
@ -91,7 +83,7 @@ fi
|
|||
if [ $isMonitor -eq 0 ]; then
|
||||
echo -e "${LRED}>>>>>>>>>>>>>>>>>>>>> Monitor Skipped by user. ${NC}"
|
||||
elif [ $isMonitor -eq 1 ]; then
|
||||
root -l "ChainMonitors.C($runNum)"
|
||||
root -l "ChainMonitors.C($RUN)"
|
||||
elif [ $isMonitor -eq 2 ]; then
|
||||
root -l "ChainMonitors.C"
|
||||
fi
|
|
@ -1,7 +1,5 @@
|
|||
#!/bin/bash -l
|
||||
|
||||
echo -e "${RED}##################### Loading Process_Sort.sh ${NC}"
|
||||
|
||||
if [ -z $SOLARISANADIR ]; then
|
||||
echo "###### env variable SOLARISANADIR not defined. Abort. Please run the SOLARIS.sh."
|
||||
echo "better add \"source <path_to_SOLARIS.sh>\" into .bashrc"
|
||||
|
@ -21,10 +19,8 @@ RUN=$1
|
|||
nWorker=$2
|
||||
TraceMethod=$3
|
||||
|
||||
source $SOLARISANADIR/Armory/Process_BasicConfig
|
||||
if [ -z $expName ]; then
|
||||
source $SOLARISANADIR/working/expName.sh
|
||||
fi
|
||||
source $SOLARISANADIR/armory/Process_BasicConfig
|
||||
source $SOLARISANADIR/working/expName.sh
|
||||
|
||||
runNum=${RUN#0} #remove zero
|
||||
RUN=$(printf '%03d' $runNum) ##add back the zero
|
||||
|
@ -72,7 +68,7 @@ else
|
|||
|
||||
if [ $nWorker -le -1 ]; then
|
||||
echo -e "${LRED}>>>>>>>>>>>>>>> Force GeneralSort $(date) ${NC}"
|
||||
root -l -q -b "$SOLARISANADIR/Armory/GeneralSortAgent.C($runNum, $nWorker, $TraceMethod)"
|
||||
root -l -q -b "$SOLARISANADIR/armory/GeneralSortAgent.C($runNum, $nWorker, $TraceMethod)"
|
||||
echo -e "${LRED}<<<<<<<<<<<<<<<< Done GeneralSort $(date) ${NC}"
|
||||
fi
|
||||
|
||||
|
@ -81,7 +77,7 @@ else
|
|||
if [ $rootDataTime -ge $genRootDataTime ]; then
|
||||
|
||||
echo -e "${LRED}>>>>>>>>>>>>>>>>>>>>> GeneralSort $(date) ${NC}"
|
||||
root -l -q -b "$SOLARISANADIR/Armory/GeneralSortAgent.C($runNum, $nWorker, $TraceMethod)"
|
||||
root -l -q -b "$SOLARISANADIR/armory/GeneralSortAgent.C($runNum, $nWorker, $TraceMethod)"
|
||||
echo -e "${LRED}<<<<<<<<<<<<<<<< Done GeneralSort $(date) ${NC}"
|
||||
|
||||
else
|
258
armory/SolReader.h
Normal file
|
@ -0,0 +1,258 @@
|
|||
#ifndef SOLREADER_H
|
||||
#define SOLREADER_H
|
||||
|
||||
#include <stdio.h> /// for FILE
|
||||
#include <cstdlib>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <unistd.h>
|
||||
#include <time.h> // time in nano-sec
|
||||
|
||||
#include "Hit.h"
|
||||
|
||||
class SolReader {
|
||||
private:
|
||||
FILE * inFile;
|
||||
unsigned int inFileSize;
|
||||
unsigned int filePos;
|
||||
unsigned int totNumBlock;
|
||||
|
||||
unsigned short blockStartIdentifier;
|
||||
unsigned int numBlock;
|
||||
bool isScanned;
|
||||
|
||||
void init();
|
||||
|
||||
std::vector<unsigned int> blockPos;
|
||||
|
||||
public:
|
||||
SolReader();
|
||||
SolReader(std::string fileName, unsigned short dataType);
|
||||
~SolReader();
|
||||
|
||||
void OpenFile(std::string fileName);
|
||||
int ReadNextBlock(int isSkip = 0); // opt = 0, noraml, 1, fast
|
||||
int ReadBlock(unsigned int index, bool verbose = false);
|
||||
|
||||
void ScanNumBlock();
|
||||
|
||||
bool IsEndOfFile() const {return (filePos >= inFileSize ? true : false);}
|
||||
unsigned int GetBlockID() const {return numBlock - 1;}
|
||||
unsigned int GetNumBlock() const {return numBlock;}
|
||||
unsigned int GetTotalNumBlock() const {return totNumBlock;}
|
||||
unsigned int GetFilePos() const {return filePos;}
|
||||
unsigned int GetFileSize() const {return inFileSize;}
|
||||
|
||||
void RewindFile();
|
||||
|
||||
Hit * hit;
|
||||
|
||||
};
|
||||
|
||||
void SolReader::init(){
|
||||
inFileSize = 0;
|
||||
numBlock = 0;
|
||||
filePos = 0;
|
||||
totNumBlock = 0;
|
||||
hit = new Hit();
|
||||
|
||||
isScanned = false;
|
||||
|
||||
blockPos.clear();
|
||||
|
||||
}
|
||||
|
||||
SolReader::SolReader(){
|
||||
init();
|
||||
}
|
||||
|
||||
SolReader::SolReader(std::string fileName, unsigned short dataType = 0){
|
||||
init();
|
||||
OpenFile(fileName);
|
||||
hit->SetDataType(dataType, DPPType::PHA);
|
||||
}
|
||||
|
||||
SolReader::~SolReader(){
|
||||
if( !inFile ) fclose(inFile);
|
||||
delete hit;
|
||||
}
|
||||
|
||||
inline void SolReader::OpenFile(std::string fileName){
|
||||
inFile = fopen(fileName.c_str(), "r");
|
||||
if( inFile == NULL ){
|
||||
printf("Cannot open file : %s \n", fileName.c_str());
|
||||
}else{
|
||||
fseek(inFile, 0L, SEEK_END);
|
||||
inFileSize = ftell(inFile);
|
||||
rewind(inFile);
|
||||
}
|
||||
}
|
||||
|
||||
inline int SolReader::ReadBlock(unsigned int index, bool verbose){
|
||||
if( isScanned == false) return -1;
|
||||
if( index >= totNumBlock )return -1;
|
||||
fseek(inFile, 0L, SEEK_SET);
|
||||
|
||||
if( verbose ) printf("Block index: %u, File Pos: %u byte\n", index, blockPos[index]);
|
||||
|
||||
fseek(inFile, blockPos[index], SEEK_CUR);
|
||||
|
||||
filePos = blockPos[index];
|
||||
|
||||
numBlock = index;
|
||||
|
||||
return ReadNextBlock();
|
||||
}
|
||||
|
||||
inline int SolReader::ReadNextBlock(int isSkip){
|
||||
if( inFile == NULL ) return -1;
|
||||
if( feof(inFile) ) return -1;
|
||||
if( filePos >= inFileSize) return -1;
|
||||
|
||||
fread(&blockStartIdentifier, 2, 1, inFile);
|
||||
|
||||
if( (blockStartIdentifier & 0xAA00) != 0xAA00 ) {
|
||||
printf("header fail.\n");
|
||||
return -2 ;
|
||||
}
|
||||
|
||||
if( ( blockStartIdentifier & 0xF ) == DataFormat::Raw ){
|
||||
hit->SetDataType(DataFormat::Raw, ((blockStartIdentifier >> 1) & 0xF) == 0 ? DPPType::PHA : DPPType::PSD);
|
||||
}
|
||||
hit->dataType = blockStartIdentifier & 0xF;
|
||||
hit->DPPType = ((blockStartIdentifier >> 4) & 0xF) == 0 ? DPPType::PHA : DPPType::PSD;
|
||||
|
||||
if( hit->dataType == DataFormat::ALL){
|
||||
if( isSkip == 0 ){
|
||||
fread(&hit->channel, 1, 1, inFile);
|
||||
fread(&hit->energy, 2, 1, inFile);
|
||||
if( hit->DPPType == DPPType::PSD ) fread(&hit->energy_short, 2, 1, inFile);
|
||||
fread(&hit->timestamp, 6, 1, inFile);
|
||||
fread(&hit->fine_timestamp, 2, 1, inFile);
|
||||
fread(&hit->flags_high_priority, 1, 1, inFile);
|
||||
fread(&hit->flags_low_priority, 2, 1, inFile);
|
||||
fread(&hit->downSampling, 1, 1, inFile);
|
||||
fread(&hit->board_fail, 1, 1, inFile);
|
||||
fread(&hit->flush, 1, 1, inFile);
|
||||
fread(&hit->trigger_threashold, 2, 1, inFile);
|
||||
fread(&hit->event_size, 8, 1, inFile);
|
||||
fread(&hit->aggCounter, 4, 1, inFile);
|
||||
}else{
|
||||
fseek(inFile, hit->DPPType == DPPType::PHA ? 31 : 33, SEEK_CUR);
|
||||
}
|
||||
fread(&hit->traceLenght, 8, 1, inFile);
|
||||
if( isSkip == 0){
|
||||
fread(hit->analog_probes_type, 2, 1, inFile);
|
||||
fread(hit->digital_probes_type, 4, 1, inFile);
|
||||
fread(hit->analog_probes[0], hit->traceLenght*4, 1, inFile);
|
||||
fread(hit->analog_probes[1], hit->traceLenght*4, 1, inFile);
|
||||
fread(hit->digital_probes[0], hit->traceLenght, 1, inFile);
|
||||
fread(hit->digital_probes[1], hit->traceLenght, 1, inFile);
|
||||
fread(hit->digital_probes[2], hit->traceLenght, 1, inFile);
|
||||
fread(hit->digital_probes[3], hit->traceLenght, 1, inFile);
|
||||
}else{
|
||||
fseek(inFile, 6 + hit->traceLenght*(12), SEEK_CUR);
|
||||
}
|
||||
|
||||
}else if( hit->dataType == DataFormat::OneTrace){
|
||||
if( isSkip == 0 ){
|
||||
fread(&hit->channel, 1, 1, inFile);
|
||||
fread(&hit->energy, 2, 1, inFile);
|
||||
if( hit->DPPType == DPPType::PSD ) fread(&hit->energy_short, 2, 1, inFile);
|
||||
fread(&hit->timestamp, 6, 1, inFile);
|
||||
fread(&hit->fine_timestamp, 2, 1, inFile);
|
||||
fread(&hit->flags_high_priority, 1, 1, inFile);
|
||||
fread(&hit->flags_low_priority, 2, 1, inFile);
|
||||
}else{
|
||||
fseek(inFile, hit->DPPType == DPPType::PHA ? 14 : 16, SEEK_CUR);
|
||||
}
|
||||
fread(&hit->traceLenght, 8, 1, inFile);
|
||||
if( isSkip == 0){
|
||||
fread(&hit->analog_probes_type[0], 1, 1, inFile);
|
||||
fread(hit->analog_probes[0], hit->traceLenght*4, 1, inFile);
|
||||
}else{
|
||||
fseek(inFile, 1 + hit->traceLenght*4, SEEK_CUR);
|
||||
}
|
||||
|
||||
}else if( hit->dataType == DataFormat::NoTrace){
|
||||
if( isSkip == 0 ){
|
||||
fread(&hit->channel, 1, 1, inFile);
|
||||
fread(&hit->energy, 2, 1, inFile);
|
||||
if( hit->DPPType == DPPType::PSD ) fread(&hit->energy_short, 2, 1, inFile);
|
||||
fread(&hit->timestamp, 6, 1, inFile);
|
||||
fread(&hit->fine_timestamp, 2, 1, inFile);
|
||||
fread(&hit->flags_high_priority, 1, 1, inFile);
|
||||
fread(&hit->flags_low_priority, 2, 1, inFile);
|
||||
}else{
|
||||
fseek(inFile, hit->DPPType == DPPType::PHA ? 14 : 16, SEEK_CUR);
|
||||
}
|
||||
|
||||
}else if( hit->dataType == DataFormat::MiniWithFineTime){
|
||||
if( isSkip == 0 ){
|
||||
fread(&hit->channel, 1, 1, inFile);
|
||||
fread(&hit->energy, 2, 1, inFile);
|
||||
if( hit->DPPType == DPPType::PSD ) fread(&hit->energy_short, 2, 1, inFile);
|
||||
fread(&hit->timestamp, 6, 1, inFile);
|
||||
fread(&hit->fine_timestamp, 2, 1, inFile);
|
||||
}else{
|
||||
fseek(inFile, hit->DPPType == DPPType::PHA ? 11 : 13, SEEK_CUR);
|
||||
}
|
||||
|
||||
}else if( hit->dataType == DataFormat::Minimum){
|
||||
if( isSkip == 0 ){
|
||||
fread(&hit->channel, 1, 1, inFile);
|
||||
fread(&hit->energy, 2, 1, inFile);
|
||||
if( hit->DPPType == DPPType::PSD ) fread(&hit->energy_short, 2, 1, inFile);
|
||||
fread(&hit->timestamp, 6, 1, inFile);
|
||||
}else{
|
||||
fseek(inFile, hit->DPPType == DPPType::PHA ? 9 : 11, SEEK_CUR);
|
||||
}
|
||||
|
||||
}else if( hit->dataType == DataFormat::Raw){
|
||||
fread(&hit->dataSize, 8, 1, inFile);
|
||||
if( isSkip == 0){
|
||||
fread(hit->data, hit->dataSize, 1, inFile);
|
||||
}else{
|
||||
fseek(inFile, hit->dataSize, SEEK_CUR);
|
||||
}
|
||||
}
|
||||
|
||||
numBlock ++;
|
||||
filePos = ftell(inFile);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void SolReader::RewindFile(){
|
||||
rewind(inFile);
|
||||
filePos = 0;
|
||||
numBlock = 0;
|
||||
}
|
||||
|
||||
void SolReader::ScanNumBlock(){
|
||||
if( inFile == NULL ) return;
|
||||
if( feof(inFile) ) return;
|
||||
|
||||
numBlock = 0;
|
||||
blockPos.clear();
|
||||
|
||||
blockPos.push_back(0);
|
||||
|
||||
while( ReadNextBlock(1) == 0){
|
||||
blockPos.push_back(filePos);
|
||||
printf("%u, %.2f%% %u/%u\n\033[A\r", numBlock, filePos*100./inFileSize, filePos, inFileSize);
|
||||
}
|
||||
|
||||
totNumBlock = numBlock;
|
||||
numBlock = 0;
|
||||
isScanned = true;
|
||||
printf("\nScan complete: number of data Block : %u\n", totNumBlock);
|
||||
rewind(inFile);
|
||||
filePos = 0;
|
||||
|
||||
//for( int i = 0; i < totNumBlock; i++){
|
||||
// printf("%7d | %u \n", i, blockPos[i]);
|
||||
//}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
|
@ -2,36 +2,107 @@
|
|||
#include "TObjArray.h"
|
||||
#include "TFile.h"
|
||||
#include "TMacro.h"
|
||||
#include "TChain.h"
|
||||
|
||||
TChain *gen_tree = nullptr;
|
||||
std::string create_range_string(const std::vector<int>& nums);
|
||||
|
||||
void ChainMonitors(int RUNNUM = -1, int RUNNUM2 = -1) {
|
||||
///default saveCanvas = false, no save Cavas
|
||||
/// = true, save Canvas
|
||||
|
||||
gen_tree = new TChain("gen_tree");
|
||||
TChain * chain = new TChain("gen_tree");
|
||||
if( RUNNUM == -1){
|
||||
/// this list only for manual Chain sort
|
||||
///********** start Marker for AutoCalibration.
|
||||
|
||||
gen_tree->Add("../root_data/trace_run033.root");
|
||||
chain->Add("../root_data/gen_run005.root");
|
||||
chain->Add("../root_data/gen_run003.root");
|
||||
///chain->Add("../root_data/trace_run135.root");
|
||||
|
||||
///********** end Marker for AutoCalibration.
|
||||
|
||||
|
||||
}else{
|
||||
|
||||
TString fileName;
|
||||
int endRUNNUM = RUNNUM2;
|
||||
if( RUNNUM2 == -1) endRUNNUM = RUNNUM;
|
||||
|
||||
|
||||
for( int i = RUNNUM ; i <= endRUNNUM ; i++){
|
||||
fileName.Form("../root_data/gen_run%03d.root", i);
|
||||
gen_tree->Add(fileName);
|
||||
chain->Add(fileName);
|
||||
}
|
||||
}
|
||||
|
||||
//^============== should have other things, like calibrations.
|
||||
Monitor(gen_tree);
|
||||
TObjArray * fileList = chain->GetListOfFiles();
|
||||
|
||||
printf("\033[0;31m========================================== Number of Files : %2d\n",fileList->GetEntries());
|
||||
fileList->Print();
|
||||
printf("========================================== Number of Files : %2d\033[0m\n",fileList->GetEntries());
|
||||
printf("---------------------------------- Total Number of entries : %llu \n", chain->GetEntries());
|
||||
|
||||
double totDuration = 0;
|
||||
std::vector<ULong64_t> startTime;
|
||||
std::vector<ULong64_t> stopTime;
|
||||
std::vector<int> runList;
|
||||
|
||||
for( int i = 0; i < fileList->GetEntries(); i++){
|
||||
TString fileName = fileList->At(i)->GetTitle();
|
||||
TFile file(fileName);
|
||||
TMacro * timeStamp = (TMacro*) file.FindObjectAny("timeStamp");
|
||||
//timeStamp->Print();
|
||||
|
||||
TString haha = timeStamp->GetListOfLines()->At(0)->GetName();
|
||||
ULong64_t t1 = haha.Atoll();
|
||||
|
||||
haha = timeStamp->GetListOfLines()->At(1)->GetName();
|
||||
ULong64_t t2 = haha.Atoll();
|
||||
|
||||
haha = timeStamp->GetListOfLines()->At(2)->GetName();
|
||||
int RunID = haha.Atoi();
|
||||
|
||||
totDuration += (t2-t1)*8./1e9;
|
||||
startTime.push_back(t1);
|
||||
stopTime.push_back(t2);
|
||||
runList.push_back(RunID);
|
||||
}
|
||||
|
||||
//======== format CanvasTitle
|
||||
std::sort(runList.begin(), runList.end());
|
||||
TString title = "Run:" + create_range_string(runList);
|
||||
title += Form(" | %.0f min", totDuration/60.) ;
|
||||
|
||||
//Some input to TSelector
|
||||
Monitor * selector = new Monitor();
|
||||
selector->SetCanvasTitle(title);
|
||||
selector->SetStartStopTimes(startTime, stopTime);
|
||||
chain->Process(selector, "");
|
||||
|
||||
delete chain;
|
||||
delete selector;
|
||||
|
||||
}
|
||||
|
||||
|
||||
std::string create_range_string(const std::vector<int>& nums) {
|
||||
std::string range_str;
|
||||
int lastNum = nums[0];
|
||||
int rangeStart = lastNum;
|
||||
for (int i = 1; i < nums.size(); i++) {
|
||||
if (nums[i] == lastNum + 1) {
|
||||
lastNum = nums[i];
|
||||
} else {
|
||||
if (rangeStart == lastNum) {
|
||||
range_str += std::to_string(rangeStart) + "_";
|
||||
} else {
|
||||
range_str += std::to_string(rangeStart) + "-" + std::to_string(lastNum) + "_";
|
||||
}
|
||||
rangeStart = lastNum = nums[i];
|
||||
}
|
||||
}
|
||||
// Add the last range
|
||||
if (rangeStart == lastNum) {
|
||||
range_str += std::to_string(rangeStart);
|
||||
} else {
|
||||
range_str += std::to_string(rangeStart) + "-" + std::to_string(lastNum);
|
||||
}
|
||||
return range_str;
|
||||
}
|
30
working/Check_Simulation_Config.txt
Normal file
|
@ -0,0 +1,30 @@
|
|||
/////enum plotID { pEZ, /// 0
|
||||
///// pRecoilXY, /// 1
|
||||
///// pRecoilXY1, /// 2
|
||||
///// pRecoilXY2, /// 3
|
||||
///// pRecoilRZ, /// 4
|
||||
///// pRecoilRTR, /// 5
|
||||
///// pTDiffZ, /// 6
|
||||
///// pThetaCM, /// 7
|
||||
///// pThetaCM_Z, /// 8
|
||||
///// pExCal, /// 9
|
||||
///// pRecoilRThetaCM, /// 10
|
||||
///// pArrayXY, /// 11
|
||||
///// pInfo, /// 12
|
||||
///// pHitID, /// 13
|
||||
///// pElum1XY, /// 14
|
||||
///// pEElum1R, /// 15
|
||||
///// pElum1RThetaCM, /// 16
|
||||
///// pEmpty }; /// 17
|
||||
/////=============================================== User Config
|
||||
{pEZ, pExCal, pThetaCM, pRecoilRZ, break, pThetaCM_Z, pRecoilXY, pInfo, pRecoilRThetaCM} //Canvas config
|
||||
hit == 1 && loop <= 1 && thetaCM > 10
|
||||
60 //elum range
|
||||
{0,50} //thetaCM range
|
||||
false //shownKELines
|
||||
false //isOverRideEx
|
||||
{-0.5, 4.0} // over-rdied Ex range
|
||||
///============================== example of gate
|
||||
hit == 1 && loop <= 1 && thetaCM > 10 && detRowID == 0
|
||||
hit == 1 && loop <= 1
|
||||
15 < rhoElum1 && rhoElum1 < 50 && rhoElum2 > 60
|
|
@ -1,570 +0,0 @@
|
|||
#ifndef ClassMonitorPlotter_H
|
||||
#define ClassMonitorPlotter_H
|
||||
|
||||
#include "../Armory/ClassDetGeo.h"
|
||||
#include "../Armory/ClassReactionConfig.h"
|
||||
#include "../Cleopatra/ClassTransfer.h"
|
||||
#include "../Cleopatra/ClassIsotope.h"
|
||||
|
||||
#include "TH1.h"
|
||||
#include "TH2.h"
|
||||
#include "TCanvas.h"
|
||||
#include "TLine.h"
|
||||
#include "TStyle.h"
|
||||
|
||||
/******************************************************************
|
||||
* This is Plotter for Monitor.C. It contains
|
||||
* 1) Tcanvas
|
||||
* 2) various Histograms ( exclude raw data histogram )
|
||||
*
|
||||
* The reason for having Plotter is suppert multiple arrays.
|
||||
* contained the Canvas and Histogram in a class, have better memory management
|
||||
*
|
||||
*******************************************************************/
|
||||
/******************************************************************
|
||||
* variable and histogram naming rules *
|
||||
* name are case sensitive, so as any C/C++ code *
|
||||
* *
|
||||
* ID is detector ID *
|
||||
* *
|
||||
* raw data from gen_tree are e, xf, xn, ring. *
|
||||
* the x from raw data is x *
|
||||
* *
|
||||
* xf + xn = xs, s for sum *
|
||||
* *
|
||||
* calibrated data are eCal, xfCal, xnCal, ringCal. *
|
||||
* the x from cal data is xCal *
|
||||
* *
|
||||
* xfCal + xnCal = xsCal *
|
||||
* *
|
||||
* since the z is always from xCal, so it calls z. *
|
||||
* *
|
||||
* Excitation energy calls Ex *
|
||||
* *
|
||||
* *
|
||||
* TH2D is always using "_" to seperate 2 variables, like e_x *
|
||||
* *
|
||||
* histogram with TCutG, add suffix "GC" for Graphical-Cut. *
|
||||
* *
|
||||
*******************************************************************/
|
||||
|
||||
class MonPlotter{
|
||||
public:
|
||||
|
||||
MonPlotter(unsigned short arrayID, DetGeo * detGeo, int numRDT);
|
||||
~MonPlotter();
|
||||
|
||||
void SetUpCanvas(TString title, int padSize, int divX, int divY);
|
||||
void SetUpHistograms(int * rawEnergyRange,
|
||||
int * energyRange,
|
||||
double * exRange,
|
||||
int * thetaCMRange,
|
||||
int * rdtDERange,
|
||||
int * rdtERange,
|
||||
int * coinTimeRange);
|
||||
|
||||
void LoadRDTGate(TString rdtCutFile);
|
||||
|
||||
void Plot();
|
||||
|
||||
void PlotRaw(bool isLog = false);
|
||||
void PlotCal();
|
||||
void PlotEZ();
|
||||
void PlotEx();
|
||||
|
||||
void PlotRDT(bool isLog = false);
|
||||
|
||||
TCanvas * canvas;
|
||||
|
||||
//====================== Histograms
|
||||
//======== raw data
|
||||
TH2F * he_ID, * hxf_ID, * hxn_ID; // vs ID
|
||||
|
||||
TH1I * hArrayMulti;
|
||||
|
||||
TH1F ** he, ** hxf, ** hxn; //basic data
|
||||
TH2F ** hxf_xn, ** he_xs; // correlation
|
||||
|
||||
//====== cal data
|
||||
TH1F ** heCal;
|
||||
TH2F ** hxfCal_xnCal;
|
||||
TH2F ** he_xsCal; // raw e vs xf
|
||||
TH2F ** he_x; // raw e vs x
|
||||
TH2F * heCal_ID;
|
||||
|
||||
//===== eCal V z
|
||||
TH2F * heCal_z;
|
||||
TH2F * heCal_zGC;
|
||||
|
||||
//======= Recoil
|
||||
TH2F * hrdt_ID;
|
||||
TH1F ** hrdt; // single recoil
|
||||
|
||||
TH1I * hrdtMulti;
|
||||
|
||||
TH2F ** hrdt2D;
|
||||
TH2F ** hrdt2Dg; // gated
|
||||
|
||||
//====== tDiff
|
||||
TH1F * htDiff;
|
||||
TH1F * htDiffg;
|
||||
|
||||
//====== Ex data
|
||||
TH1F * hEx;
|
||||
TH1F ** hExi;
|
||||
TH2F ** hEx_xCal;
|
||||
|
||||
TH1F * hExCut1;
|
||||
TH1F * hExCut2;
|
||||
|
||||
TH2F * hEx_ThetaCM;
|
||||
//=======================
|
||||
|
||||
//======= Recoil Cut
|
||||
TObjArray * cutList;
|
||||
|
||||
private:
|
||||
|
||||
unsigned short aID;
|
||||
int numDet, colDet, rowDet; //array
|
||||
float detLength;
|
||||
int numRDT;
|
||||
float recoilOutter;
|
||||
double zRange[2] ; // zMin, zMax
|
||||
|
||||
TString canvasTitle;
|
||||
TString suffix;
|
||||
int numPad;
|
||||
|
||||
template<typename T> void CreateListOfHist1D(T ** &histList, int size, const char * namePrefix, const char * TitleForm, int binX, float xMin, float xMax);
|
||||
template<typename T> void CreateListOfHist2D(T ** &histList, int size, const char * namePrefix, const char * TitleForm, int binX, float xMin, float xMax, int binY, float yMin, float yMax);
|
||||
|
||||
};
|
||||
//^#################################################################################
|
||||
MonPlotter::MonPlotter(unsigned short arrayID, DetGeo * detGeo, int numRDT){
|
||||
aID = arrayID;
|
||||
numDet = detGeo->array[aID].numDet;
|
||||
colDet = detGeo->array[aID].colDet;
|
||||
rowDet = numDet/colDet;
|
||||
detLength = detGeo->array[aID].detLength;
|
||||
|
||||
suffix = Form("_%d", arrayID);
|
||||
|
||||
this->numRDT = numRDT;
|
||||
recoilOutter = detGeo->aux[aID].outerRadius;
|
||||
|
||||
zRange[0] = detGeo->array[aID].zMin - 50;
|
||||
zRange[1] = detGeo->array[aID].zMax + 50;
|
||||
|
||||
canvas = nullptr;
|
||||
cutList = nullptr;
|
||||
|
||||
}
|
||||
|
||||
MonPlotter::~MonPlotter(){
|
||||
|
||||
printf("=============== %s\n", __func__);
|
||||
|
||||
delete canvas;
|
||||
|
||||
delete he_ID;
|
||||
delete hxf_ID;
|
||||
delete hxn_ID;
|
||||
delete hArrayMulti;
|
||||
|
||||
delete heCal_ID;
|
||||
delete heCal_zGC;
|
||||
delete heCal_z;
|
||||
|
||||
delete hEx_ThetaCM;
|
||||
delete hExCut1;
|
||||
delete hExCut2;
|
||||
|
||||
delete hrdt_ID;
|
||||
delete hrdtMulti;
|
||||
|
||||
delete htDiff;
|
||||
delete htDiffg;
|
||||
|
||||
for( int i = 0; i < numDet ; i++ ){
|
||||
delete he[i];
|
||||
delete hxf[i];
|
||||
delete hxn[i];
|
||||
delete hxf_xn[i];
|
||||
delete he_xs[i];
|
||||
delete he_x[i];
|
||||
delete heCal[i];
|
||||
delete hExi[i];
|
||||
delete hEx_xCal[i];
|
||||
}
|
||||
|
||||
for( int i = 0; i < numRDT; i++){
|
||||
delete hrdt[i];
|
||||
}
|
||||
for( int i = 0; i < numRDT/2; i++){
|
||||
delete hrdt2D[i];
|
||||
delete hrdt2Dg[i];
|
||||
}
|
||||
|
||||
delete [] he;
|
||||
delete [] hxf;
|
||||
delete [] hxn;
|
||||
delete [] hxf_xn;
|
||||
delete [] he_xs;
|
||||
delete [] he_x;
|
||||
delete [] heCal;
|
||||
delete [] hExi;
|
||||
delete [] hEx_xCal;
|
||||
|
||||
delete [] hrdt;
|
||||
delete [] hrdt2D;
|
||||
delete [] hrdt2Dg;
|
||||
|
||||
delete cutList;
|
||||
|
||||
}
|
||||
|
||||
void MonPlotter::SetUpCanvas(TString title, int padSize, int divX, int divY){
|
||||
|
||||
canvas = new TCanvas("canavs" + suffix, title, 500 * aID, 0, divX * padSize, divY * padSize);
|
||||
canvas->Divide(divX, divY);
|
||||
numPad = divX * divY;
|
||||
canvasTitle = title;
|
||||
|
||||
}
|
||||
|
||||
template<typename T> void MonPlotter::CreateListOfHist1D(T ** &histList,
|
||||
int size,
|
||||
const char * namePrefix,
|
||||
const char * TitleForm,
|
||||
int binX, float xMin, float xMax){
|
||||
|
||||
//printf(" Making %d of %s.\n", size, namePrefix);
|
||||
histList = new T * [size];
|
||||
for(int i = 0; i < size; i++) {
|
||||
histList[i] = new T(Form("%s%d", namePrefix, i) + suffix, Form(TitleForm, i), binX, xMin, xMax);
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T> void MonPlotter::CreateListOfHist2D(T ** &histList,
|
||||
int size,
|
||||
const char * namePrefix,
|
||||
const char * TitleForm,
|
||||
int binX, float xMin, float xMax,
|
||||
int binY, float yMin, float yMax){
|
||||
|
||||
//printf(" Making %d of %s.\n", size, namePrefix);
|
||||
histList = new T * [size];
|
||||
for(int i = 0; i < size; i++) {
|
||||
histList[i] = new T(Form("%s%d", namePrefix, i) + suffix, Form(TitleForm, i), binX, xMin, xMax, binY, yMin, yMax);
|
||||
}
|
||||
}
|
||||
|
||||
void MonPlotter::SetUpHistograms(int * rawEnergyRange,
|
||||
int * energyRange,
|
||||
double * exRange,
|
||||
int * thetaCMRange,
|
||||
int * rdtDERange,
|
||||
int * rdtERange,
|
||||
int * coinTimeRange){
|
||||
|
||||
he_ID = new TH2F("he_ID" + suffix, "Raw e vs array ID; Array ID; Raw e", numDet, 0, numDet, 200, rawEnergyRange[0], rawEnergyRange[1]);
|
||||
hxf_ID = new TH2F("hxf_ID" + suffix, "Raw xf vs array ID; Array ID; Raw xf", numDet, 0, numDet, 200, rawEnergyRange[0], rawEnergyRange[1]);
|
||||
hxn_ID = new TH2F("hxn_ID" + suffix, "Raw xn vs array ID; Array ID; Raw xn", numDet, 0, numDet, 200, rawEnergyRange[0], rawEnergyRange[1]);
|
||||
|
||||
hArrayMulti = new TH1I("hArrayMulti", "Array Multiplicity ( e and (xf or xn) )", numDet, 0, numDet);
|
||||
|
||||
CreateListOfHist1D(he, numDet, "he", "Raw e (ch=%d); e (channel); count", 200, rawEnergyRange[0], rawEnergyRange[1]);
|
||||
CreateListOfHist1D(hxf, numDet, "hxf", "Raw xf (ch=%d); e (channel); count", 200, rawEnergyRange[0], rawEnergyRange[1]);
|
||||
CreateListOfHist1D(hxn, numDet, "hxn", "Raw xn (ch=%d); e (channel); count", 200, rawEnergyRange[0], rawEnergyRange[1]);
|
||||
|
||||
CreateListOfHist2D(hxf_xn, numDet, "hxf_xn", "Raw xf vs. xn (ch=%d);xf (channel);xn (channel)" , 500, rawEnergyRange[0], rawEnergyRange[1], 500, rawEnergyRange[0], rawEnergyRange[1]);
|
||||
CreateListOfHist2D(he_xs, numDet, "he_xs", "Raw e vs xf+xn (ch=%d); xf+xn (channel); e (channel)", 500, rawEnergyRange[0], rawEnergyRange[1], 500, rawEnergyRange[0], rawEnergyRange[1]);
|
||||
|
||||
CreateListOfHist2D(he_x , numDet, "he_x", "Raw e vs x (ch=%d); x (mm); Raw e (channel)", 500, rawEnergyRange[0], rawEnergyRange[1], 500, -0.5, 1.5);
|
||||
CreateListOfHist2D(hxfCal_xnCal, numDet, "hxfCal_xnCal", "Corrected XF vs. XN (ch=%d);XF (channel);XN (channel)", 500, 0, rawEnergyRange[1], 500, 0, rawEnergyRange[1]);
|
||||
CreateListOfHist2D(he_xsCal , numDet, "he_xsCal", "Raw e vs Corrected xf+xn (ch=%d); corrected xf+xn (channel); Raw e (channel)", 500, rawEnergyRange[0], rawEnergyRange[1], 500, rawEnergyRange[0], rawEnergyRange[1]);
|
||||
|
||||
CreateListOfHist1D(heCal, numDet, "heCal", "Corrected e (ch=%d); e (MeV); count", 2000, energyRange[0], energyRange[1]);
|
||||
|
||||
//====================== E-Z plot
|
||||
heCal_ID = new TH2F("heCal_ID" + suffix , "E vs. ID; ID;E (MeV)" , numDet, 0, numDet, 400, energyRange[0], energyRange[1]);
|
||||
heCal_z = new TH2F("heCal_z" + suffix , "E vs. Z;Z (mm);E (MeV)" , 400, zRange[0], zRange[1], 400, energyRange[0], energyRange[1]);
|
||||
heCal_zGC = new TH2F("heCal_zGC" + suffix ,"E vs. Z gated;Z (mm);E (MeV)", 400, zRange[0], zRange[1], 400, energyRange[0], energyRange[1]);
|
||||
|
||||
//===================== Recoil
|
||||
int rdtRange[2];
|
||||
rdtRange[0] = rdtDERange[0] < rdtERange[0] ? rdtDERange[0] : rdtERange[0];
|
||||
rdtRange[1] = rdtDERange[1] > rdtERange[1] ? rdtDERange[1] : rdtERange[1];
|
||||
|
||||
hrdt_ID = new TH2F("hrdt_ID" + suffix, "Raw RDT vs ID; ID; Raw RDT", numRDT, 0, numRDT, 400, rdtRange[0], rdtRange[1]);
|
||||
|
||||
hrdtMulti = new TH1I("hrdtMulti" + suffix, "RDT Multiplicity", numRDT, 0, numRDT);
|
||||
|
||||
hrdt = new TH1F * [numRDT];
|
||||
hrdt2D = new TH2F * [numRDT/2];
|
||||
hrdt2Dg = new TH2F * [numRDT/2];
|
||||
|
||||
for (Int_t i = 0; i < numRDT ; i++) {
|
||||
if( i % 2 == 0 ) hrdt[i] = new TH1F(Form("hrdt%d",i), Form("Raw Recoil E(ch=%d); E (channel)",i), 500, rdtERange[0], rdtERange[1]);
|
||||
if( i % 2 == 1 ) hrdt[i] = new TH1F(Form("hrdt%d",i), Form("Raw Recoil DE(ch=%d); DE (channel)",i), 500, rdtDERange[0], rdtDERange[1]);
|
||||
|
||||
///dE vs E
|
||||
if( i % 2 == 0 ) {
|
||||
int tempID = i / 2;
|
||||
hrdt2D[tempID] = new TH2F(Form("hrdt2D%d",tempID) , Form("Raw Recoil DE vs Eres (dE=%d, E=%d); Eres (channel); DE (channel)", i+1, i), 500, rdtERange[0], rdtERange[1],500,rdtDERange[0],rdtDERange[1]);
|
||||
hrdt2Dg[tempID] = new TH2F(Form("hrdt2Dg%d",tempID), Form("Gated Raw Recoil DE vs Eres (dE=%d, E=%d); Eres (channel); DE (channel)",i+1, i), 500, rdtERange[0], rdtERange[1],500,rdtDERange[0], rdtDERange[1]);
|
||||
}
|
||||
}
|
||||
|
||||
//===================== tDiff = array_t - rdt_t
|
||||
htDiff = new TH1F("htDiff" + suffix, "tDiff = e_t - rdt_t", (coinTimeRange[1]-coinTimeRange[0]), coinTimeRange[0], coinTimeRange[1]);
|
||||
htDiffg = new TH1F("htDiffg" + suffix, "tDiff = e_t - rdt_t (gated)", (coinTimeRange[1]-coinTimeRange[0]), coinTimeRange[0], coinTimeRange[1]);
|
||||
htDiffg->SetLineColor(2);
|
||||
|
||||
//===================== energy spectrum
|
||||
hEx = new TH1F("hEx" + suffix, Form("excitation spectrum w/ goodFlag; Ex [MeV] ; Count / %4.0f keV", exRange[0]), (int) (exRange[2]-exRange[1])/exRange[0]*1000, exRange[1], exRange[2]);
|
||||
|
||||
TString haha = "Ex (det=%i) w/goodFlag; Ex [MeV]; Count / " +std::to_string(exRange[0]) + "keV";
|
||||
|
||||
hExi = new TH1F * [numDet];
|
||||
hEx_xCal = new TH2F * [numDet];
|
||||
for(int i = 0; i < numDet; i++ ){
|
||||
hExi[i] = new TH1F(Form("hExi%d", i) + suffix, haha, (int) (exRange[2]-exRange[1])/exRange[0]*1000, exRange[1], exRange[2]);
|
||||
|
||||
hEx_xCal[i] = new TH2F(Form("hEx_xCal%d", i) + suffix,
|
||||
Form("Ex vs X (ch=%d); X (cm); Ex (MeV)", i),
|
||||
500, -0.1, 1.1,
|
||||
(int) (exRange[2]-exRange[1])/exRange[0]*1000, exRange[1], exRange[2]);
|
||||
}
|
||||
|
||||
hExCut1 = new TH1F("hExCut1" + suffix,Form("excitation spectrum w/ goodFlag; Ex [MeV] ; Count / %4.0f keV", exRange[0]), (int) (exRange[2]-exRange[1])/exRange[0]*1000, exRange[1], exRange[2]);
|
||||
hExCut2 = new TH1F("hExCut2" + suffix,Form("excitation spectrum w/ goodFlag; Ex [MeV] ; Count / %4.0f keV", exRange[0]), (int) (exRange[2]-exRange[1])/exRange[0]*1000, exRange[1], exRange[2]);
|
||||
hExCut1->SetLineColor(2);
|
||||
hExCut2->SetLineColor(4);
|
||||
|
||||
hEx_ThetaCM = new TH2F("hExThetaCM" + suffix, "Ex vs ThetaCM; ThetaCM [deg]; Ex [MeV]", 200, thetaCMRange[0], thetaCMRange[1], (int) (exRange[2]-exRange[1])/exRange[0]*1000, exRange[1], exRange[2]);
|
||||
|
||||
}
|
||||
|
||||
//^####################################################### Plot
|
||||
void MonPlotter::Plot(){
|
||||
|
||||
//TODO a more user-friendly way.
|
||||
//TODO display text on the plot.
|
||||
|
||||
for( int i = 1; i <= numPad; i++ ){
|
||||
canvas->cd(i);
|
||||
switch (i){
|
||||
case 1: heCal_z->Draw("colz");break;
|
||||
case 2: heCal_zGC->Draw("colz");break;
|
||||
case 3: {
|
||||
htDiff->Draw("");
|
||||
htDiffg->Draw("same");
|
||||
}break;
|
||||
case 4: hEx->Draw("colz");break;
|
||||
default:break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//^#######################################################
|
||||
void MonPlotter::LoadRDTGate(TString rdtCutFile){
|
||||
|
||||
if( rdtCutFile == "" ) return ;
|
||||
|
||||
TFile * fCut = new TFile(rdtCutFile);
|
||||
bool isCutFileOpen = fCut->IsOpen();
|
||||
if(!isCutFileOpen) {
|
||||
printf( "Failed to open rdt-cutfile 1 : %s\n" , rdtCutFile.Data());
|
||||
}else{
|
||||
cutList = (TObjArray *) fCut->FindObjectAny("cutList");
|
||||
|
||||
if( cutList ){
|
||||
int numCut = cutList->GetEntries();
|
||||
printf("=========== found %d cutG in %s \n", numCut, fCut->GetName());
|
||||
|
||||
for(int i = 0; i < numCut ; i++){
|
||||
printf("cut name : %s , VarX: %s, VarY: %s, numPoints: %d \n",
|
||||
cutList->At(i)->GetName(),
|
||||
((TCutG*)cutList->At(i))->GetVarX(),
|
||||
((TCutG*)cutList->At(i))->GetVarY(),
|
||||
((TCutG*)cutList->At(i))->GetN()
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//^#######################################################
|
||||
|
||||
void MonPlotter::PlotRaw(bool isLog){
|
||||
|
||||
TCanvas * cRawID = new TCanvas("cRawID", Form("Raw e, Ring, xf, xn vs ID | %s", canvasTitle.Data()), 100 + 500 * aID, 100, 1200, 800);
|
||||
cRawID->Clear(); cRawID->Divide(2,2);
|
||||
cRawID->cd(1); he_ID->Draw("colz");
|
||||
cRawID->cd(2); hArrayMulti->Draw();
|
||||
cRawID->cd(3); hxf_ID->Draw("colz");
|
||||
cRawID->cd(4); hxn_ID->Draw("colz");
|
||||
|
||||
int padSize = 200;
|
||||
int canvasSize[2] = {padSize * colDet, padSize * rowDet};
|
||||
|
||||
TCanvas * cRawE = new TCanvas("cRawE" + suffix,Form("E raw | %s", canvasTitle.Data()), 200 + 500 * aID, 200, canvasSize[0], canvasSize[1]);
|
||||
cRawE->Clear(); cRawE->Divide(colDet,rowDet);
|
||||
for (Int_t i=0; i < numDet; i++) {
|
||||
cRawE->cd(i+1);
|
||||
cRawE->cd(i+1)->SetGrid();
|
||||
if( isLog ) cRawE->cd(i+1)->SetLogy();
|
||||
he[i]->Draw("");
|
||||
}
|
||||
|
||||
TCanvas *cRawXf = new TCanvas("cRawXf" + suffix,Form("Xf raw | %s", canvasTitle.Data()), 300 + 500 * aID, 300, canvasSize[0], canvasSize[1]);
|
||||
cRawXf->Clear(); cRawXf->Divide(colDet,rowDet);
|
||||
for (Int_t i=0; i<numDet; i++) {
|
||||
cRawXf->cd(i+1);
|
||||
cRawXf->cd(i+1)->SetGrid();
|
||||
if( isLog ) cRawXf->cd(i+1)->SetLogy();
|
||||
hxf[i]->Draw("");
|
||||
}
|
||||
|
||||
TCanvas *cRawXn = new TCanvas("cRawXn" + suffix,Form("Xn raw | %s", canvasTitle.Data()), 400 + 500 * aID, 400, canvasSize[0], canvasSize[1]);
|
||||
cRawXn->Clear();cRawXn->Divide(colDet,rowDet);
|
||||
for (Int_t i=0; i<numDet; i++) {
|
||||
cRawXn->cd(i+1);
|
||||
cRawXn->cd(i+1)->SetGrid();
|
||||
if( isLog ) cRawXn->cd(i+1)->SetLogy();
|
||||
hxn[i]->Draw("");
|
||||
}
|
||||
|
||||
TCanvas *cxfxn = new TCanvas("cxfxn" + suffix,Form("XF vs. XN | %s", canvasTitle.Data()), 500 + 500 * aID, 500, canvasSize[0], canvasSize[1]);
|
||||
cxfxn->Clear(); cxfxn->Divide(colDet,rowDet);
|
||||
for (Int_t i=0;i<numDet;i++) {
|
||||
cxfxn->cd(i+1);
|
||||
cxfxn->cd(i+1)->SetGrid();
|
||||
hxf_xn[i]->Draw("col");
|
||||
}
|
||||
|
||||
TCanvas *cxfxne = new TCanvas("cxfxne" + suffix,Form("E - XF+XN | %s", canvasTitle.Data()), 600 + 500 * aID, 600, canvasSize[0], canvasSize[1]);
|
||||
cxfxne->Clear(); cxfxne->Divide(colDet,rowDet);
|
||||
TLine line(0,0, 4000, 4000); line.SetLineColor(2);
|
||||
for (Int_t i=0;i<numDet;i++) {
|
||||
cxfxne->cd(i+1);
|
||||
cxfxne->cd(i+1)->SetGrid();
|
||||
he_xs[i]->Draw("col");
|
||||
line.Draw("same");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void MonPlotter::PlotCal(){
|
||||
|
||||
int padSize = 200;
|
||||
int canvasSize[2] = {padSize * colDet, padSize * rowDet};
|
||||
|
||||
TCanvas *ceVx = new TCanvas("ceVx" + suffix, Form("E vs. X = (xf-xn)/e | %s", canvasTitle.Data()), 100 + 500 * aID, 100, canvasSize[0], canvasSize[1]);
|
||||
ceVx->Clear(); ceVx->Divide(colDet,rowDet);
|
||||
for (Int_t i=0;i<numDet;i++) {
|
||||
ceVx->cd(i+1); he_x[i]->Draw("col");
|
||||
}
|
||||
|
||||
TCanvas *cxfxneC = new TCanvas("cxfxneC" + suffix,Form("Raw E - Corrected XF+XN | %s", canvasTitle.Data()), 200 + 500 * aID, 200, canvasSize[0], canvasSize[1]);
|
||||
cxfxneC->Clear(); cxfxneC->Divide(colDet,rowDet);
|
||||
TLine * line = new TLine(0,0, 4000, 4000);
|
||||
line->SetLineColor(2);
|
||||
for (Int_t i=0;i<numDet;i++) {
|
||||
cxfxneC->cd(i+1);
|
||||
cxfxneC->cd(i+1)->SetGrid();
|
||||
he_xsCal[i]->Draw("col");
|
||||
line->Draw("same");
|
||||
}
|
||||
|
||||
TCanvas *cEC = new TCanvas("cEC" + suffix,Form("E corrected | %s", canvasTitle.Data()), 300 + 500 * aID, 300, canvasSize[0], canvasSize[1]);
|
||||
cEC->Clear();cEC->Divide(colDet,rowDet);
|
||||
for (Int_t i=0; i<numDet; i++) {
|
||||
cEC->cd(i+1);
|
||||
cEC->cd(i+1)->SetGrid();
|
||||
heCal[i]->Draw("");
|
||||
}
|
||||
|
||||
TCanvas *cEC2 = new TCanvas("cEC2" + suffix,Form("E corrected | %s", canvasTitle.Data()), 400 + 500 * aID, 400, canvasSize[0], canvasSize[1]);
|
||||
cEC2->Clear();
|
||||
heCal_ID->Draw("colz");
|
||||
|
||||
TCanvas *cxfxnC = new TCanvas("cxfxnC" + suffix,Form("XF vs XN corrected | %s", canvasTitle.Data()), 500 + 500 * aID, 500, canvasSize[0], canvasSize[1]);
|
||||
cxfxnC->Clear(); cxfxnC->Divide(colDet,rowDet);
|
||||
for (Int_t i=0;i<numDet;i++) {
|
||||
cxfxnC->cd(i+1);
|
||||
cxfxnC->cd(i+1)->SetGrid();
|
||||
hxfCal_xnCal[i]->Draw("col");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void MonPlotter::PlotEZ(){
|
||||
TCanvas *cecalVz = new TCanvas("cevalVz" + suffix,Form("ECALVZ : %s", canvasTitle.Data()),1000, 650);
|
||||
cecalVz->Clear(); cecalVz->Divide(2,1);
|
||||
gStyle->SetOptStat("neiou");
|
||||
cecalVz->cd(1);heCal_z->Draw("col");
|
||||
cecalVz->cd(2);heCal_zGC->Draw("col");
|
||||
|
||||
}
|
||||
|
||||
void MonPlotter::PlotEx(){
|
||||
|
||||
TCanvas *cExVxCal = new TCanvas("cExVxCal" + suffix,Form("EX | %s", canvasTitle.Data()), 200 + 1000 * aID, 200, 1600,1000);
|
||||
cExVxCal->Clear();
|
||||
gStyle->SetOptStat("neiou");
|
||||
cExVxCal->Divide(colDet,rowDet);
|
||||
for( int i = 0; i < numDet; i++){
|
||||
cExVxCal->cd(i+1);
|
||||
hEx_xCal[i]->SetMarkerStyle(7);
|
||||
hEx_xCal[i]->Draw();
|
||||
}
|
||||
|
||||
TCanvas *cexI = new TCanvas("cexI" + suffix,Form("EX : %s", canvasTitle.Data()),300 + 1000 * aID, 300, 1600,1000);
|
||||
cexI->Clear();cexI->Divide(colDet,rowDet);
|
||||
gStyle->SetOptStat("neiou");
|
||||
for( int i = 0; i < numDet; i++){
|
||||
cexI->cd(i+1);
|
||||
hExi[i]->Draw("");
|
||||
}
|
||||
|
||||
TCanvas *cExThetaCM = new TCanvas("cExThetaCM" + suffix,Form("EX - ThetaCM | %s", canvasTitle.Data()), 400 + 1000 * aID, 400, 650,650);
|
||||
cExThetaCM->Clear();
|
||||
gStyle->SetOptStat("neiou");
|
||||
hEx_ThetaCM->Draw("colz");
|
||||
|
||||
TCanvas *cex = new TCanvas("cex" + suffix,Form("EX : %s", canvasTitle.Data()), 500 + 1000 * aID, 500, 1000,650);
|
||||
cex->Clear();
|
||||
gStyle->SetOptStat("neiou");
|
||||
hEx->Draw("");
|
||||
|
||||
}
|
||||
|
||||
void MonPlotter::PlotRDT(bool isLog){
|
||||
|
||||
TCanvas *crdt = new TCanvas("crdt" + suffix,Form("raw RDT | %s", canvasTitle.Data()), 1000, 0, 1000,1000);
|
||||
crdt->Clear();crdt->Divide(numRDT/4,2);
|
||||
|
||||
for( int i = 0; i < numRDT/2; i++){
|
||||
if( isLog ) crdt->cd(i+1)->SetLogz(); crdt->cd(i+1); hrdt2D[i]->Draw("col");
|
||||
}
|
||||
|
||||
TCanvas *crdtID = new TCanvas("crdtID" + suffix,Form("raw RDT ID | %s", canvasTitle.Data()),1100,1100, 500, 500);
|
||||
crdtID->Clear();
|
||||
if( isLog ) crdtID->SetLogz();
|
||||
hrdt_ID->Draw("colz");
|
||||
|
||||
TCanvas *crdtS = new TCanvas("crdtS" + suffix,Form("raw RDT | %s", canvasTitle.Data()),1200, 1200, 1000, 1000);
|
||||
crdtS->Clear(); crdtS->Divide(2,numRDT/2);
|
||||
for( int i = 0; i < numRDT; i ++){
|
||||
crdtS->cd(i+1);
|
||||
if( isLog ) crdtS->cd(i+1)->SetLogy();
|
||||
hrdt[i]->Draw("");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
|
@ -44,7 +44,3 @@
|
|||
#32Si(t,p)34Si 0 0L=0 0+ 0.000 8MeV/u lA #two-nucleon_transfer
|
||||
#36Ar(d,a)34Cl 0 4L=2 3+ 0.000 8MeV/u As # (d,a) reaction
|
||||
|
||||
|
||||
30Si(d,p)31Si 0 1s1/2 1/2+ 0.000 10MeV/u AK
|
||||
# 32Si(d,p)33Si 0 0d5/2 5/2+ 0.197 10MeV/u AK
|
||||
# 32Si(d,3He)31Al 0 0d5/2 5/2+ 0.000 10MeV/u Ax
|
6
working/Ex1.txt
Normal file
|
@ -0,0 +1,6 @@
|
|||
//Ex relative_xsec SF sigma_in_MeV
|
||||
//<--- use "//" for line comment
|
||||
0.000 1.0 1.0 0.0100
|
||||
//4.400 1.0 1.0 0.0100
|
||||
//4.600 1.0 1.0 0.0100
|
||||
#============_End_of_file
|
6
working/Ex2.txt
Normal file
|
@ -0,0 +1,6 @@
|
|||
//Ex relative_xsec SF sigma_in_MeV
|
||||
//<--- use "//" for line comment
|
||||
0.000 1.0 1.0 0.0100
|
||||
//4.400 1.0 1.0 0.0100
|
||||
//4.600 1.0 1.0 0.0100
|
||||
#============_End_of_file
|