rename all Key folders to small letter, update SimHelper and related code

This commit is contained in:
Ryan Tang 2025-05-06 11:01:54 -05:00
parent 46fe71c4eb
commit b404a381ce
59 changed files with 15676 additions and 17 deletions

2
.gitignore vendored
View File

@ -30,5 +30,7 @@ Cleopatra/SimTransfer
Cleopatra/SimTransfer_single
Cleopatra/Cleopatra
EventBuilder
__pycache__
*.DS_Store

View File

@ -4,7 +4,8 @@
"name": "Mac",
"includePath": [
"${workspaceFolder}/**",
"/Applications/root_v6.30.06/include/**"
"/Applications/root_v6.30.06/include/**",
"/opt/homebrew/Cellar/root/6.34.08_1/**"
],
"defines": [],
"compilerPath": "/usr/bin/g++",

View File

@ -258,29 +258,29 @@ inline bool ReactionConfig::LoadReactionConfig(TMacro * macro){
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()));
exList[ID].Add( atoi(dondon[1].c_str())/1000., 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()));
exList[ID].Add( atoi(dondon[1].c_str())/1000., 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()));
exList[ID].Add( atoi(dondon[1].c_str())/1000., 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()));
exList[ID].Add( atoi(dondon[1].c_str())/1000., 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()));
exList[ID].Add( atoi(dondon[1].c_str())/1000., 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()));
exList[ID].Add( atoi(dondon[1].c_str())/1000., 1.0, 1.0, atoi(str[3].c_str()));
}
}

View File

@ -1 +1 @@
/home/ryan/SOLARIS_DAQ/Aux/EventBuilder
/Users/solaris/SOLARIS_DAQ/Aux/EventBuilder

View File

@ -482,6 +482,7 @@ inline void Plotter::Plot(){
}///===== end of pad loop
cCheck->Update();
}
std::vector<double> Plotter::FindRange(TString branch){

View File

@ -44,7 +44,7 @@ void PlotTGraphTObjArray(TString rootFileName, bool isSavePNG = false){
const int n = gList->GetLast() + 1 ;
TGraph * gr[n];
TGraph ** gr = new TGraph *[n];
//Get minimum, maximum Y
double maxY = 0;
@ -94,5 +94,8 @@ void PlotTGraphTObjArray(TString rootFileName, bool isSavePNG = false){
gROOT->ProcessLine(".q");
}
for( int i = 0; i < n; i++) delete gr[i];
delete [] gr;
}

View File

@ -24,6 +24,7 @@
#include "../Cleopatra/ClassIsotope.h"
#include "../Cleopatra/ClassTransfer.h"
#include "../Cleopatra/ClassSimPlotter.h"
#include <vector>
plotID StringToPlotID(TString str);
@ -45,14 +46,14 @@ void SimChecker(TString filename = "transfer.root",
printf(">>>>> %d reactions found.\n", numReact);
std::string reactionList[numReact];
std::vector<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
std::vector<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");
@ -90,8 +91,8 @@ void SimChecker(TString filename = "transfer.root",
//^################################################ Find e-range, z-range
double zRange[numReact][2];
double eMax[numReact];
std::vector<std::vector<double>> zRange(numReact, std::vector<double>(2));
std::vector<double> eMax(numReact);
int count = 0;
for( int i = 0; i < numReact; i++ ){
@ -197,13 +198,14 @@ void SimChecker(TString filename = "transfer.root",
printf("#####################################################\n");
Plotter * plotter[numReact];
Plotter ** plotter = new 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;

View File

@ -96,7 +96,7 @@ void Transfer(
TMacro dwbaExList_Used;
TMacro dwbaReactList_Used;
bool useDWBA[numTransfer];
bool *useDWBA = new bool[numTransfer];
for( int i = 0; i < numTransfer; i++ ) useDWBA[i] = false;
if( distFile->IsOpen() ) {
@ -111,7 +111,7 @@ void Transfer(
int numEx = dwbaExList->GetListOfLines()->GetSize() - 1 ;
ExcitedEnergies dwbaExTemp[numTransfer];
ExcitedEnergies * dwbaExTemp = new ExcitedEnergies[numTransfer];
for( int i = 1; i <= numEx ; i++){
std::string reactionName = dwbaReactList->GetListOfLines()->At(i-1)->GetName();
@ -145,6 +145,8 @@ void Transfer(
}
}
delete [] dwbaExTemp;
}else{
printf("------- no DWBA input. Use the ExList from %s\n", basicConfig.c_str());
}
@ -740,6 +742,7 @@ void Transfer(
delete [] transfer;
delete [] decay;
delete [] helios;
delete [] useDWBA;
distFile->Close();
delete distFile;

392
armory/AnalysisLib.h Normal file
View File

@ -0,0 +1,392 @@
#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

2861
armory/AutoFit.C Normal file

File diff suppressed because it is too large Load Diff

175
armory/ClassCorrParas.h Normal file
View File

@ -0,0 +1,175 @@
#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

268
armory/ClassDetGeo.h Normal file
View File

@ -0,0 +1,268 @@
#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

View File

@ -0,0 +1,345 @@
#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())/1000., 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())/1000., 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())/1000., 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())/1000., 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())/1000., 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())/1000., 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

View File

@ -0,0 +1,158 @@
#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

199
armory/GeneralSort.C Normal file
View File

@ -0,0 +1,199 @@
#define GeneralSort_cxx
#include <iostream>
#include <fstream>
#include <string>
#include "GeneralSort.h"
#include <TH2.h>
#include <TStyle.h>
#include <TString.h>
#include <TSystem.h>
#include <TMath.h>
Long64_t processedEntry = 0;
float lastPercentage = 0;
//^##############################################################
Bool_t GeneralSort::Process(Long64_t entry){
if( entry < 1 ) printf("============================== start processing data\n");
///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){
teE[i][j] = TMath::QuietNaN();
teT[i][j] = TMath::QuietNaN();
teR[i][j] = TMath::QuietNaN();
}
}
}
b_evID->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++){
int detID = mapping::map[bd[i]][ch[i]];
if( detID < 0 ) continue;
int detType = mapping::FindDetTypeIndex(detID);
int reducedDetID = detID - (detID/100) * 100;
eE[detType][reducedDetID] = e[i] * mapping::detParity[detType];
eT[detType][reducedDetID] = e_t[i];
}
//@===================================== Trace
if( isTraceExist && traceMethod > 0 ){
b_tl->GetEntry(entry);
b_trace->GetEntry(entry);
int countTrace = 0;
arr->Clear("C");
for( unsigned 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");
gTrace->Clear();
gTrace->Set(traceLength);
gTrace->SetTitle(Form("ev:%llu,nHit:%d,id:%d,len:%d", evID, i, detID, traceLength));
countTrace ++;
for( int k = 0 ; k < traceLength; k++){
gTrace->SetPoint(k, k, trace[i][k]);
}
//***=================== fit
if( traceMethod == 2){
int detType = mapping::FindDetTypeIndex(detID);
if( mapping::detNum[detType] == 0 ) continue;
//TODO use a blackList
//if( mapping::detTypeName[detType] != "rdt") continue;
gFit->SetRange(0, traceLength);
gFit->SetParameter(0, e[i]);
gFit->SetParameter(1, 100); //triggerTime //TODO how to not hardcode?
gFit->SetParameter(2, 10); //rise time //TODO how to not hardcode?
gFit->SetParameter(3, trace[i][0]); //base line
gFit->SetParameter(4, 100); // decay //TODO how to not hardcode?
gFit->SetParameter(5, -0.01); // pre-rise slope //TODO how to not hardcode?
gFit->SetParLimits(1, 85, 125); //raneg for the trigger time
gFit->SetParLimits(5, -2, 0);
gTrace->Fit("gFit", "QR", "", 0, traceLength);
int reducedDetID = detID - (detID/100) * 100;
teE[detType][reducedDetID] = gFit->GetParameter(0);
teT[detType][reducedDetID] = gFit->GetParameter(1);
teR[detType][reducedDetID] = gFit->GetParameter(2);
// delete gFit;
// gFit = nullptr;
}
//***=================== Trapezoid filter
if( traceMethod == 3){
//TODO
}
}
}
if( !isParallel){
processedEntry ++;
float percentage = processedEntry*100/NumEntries;
if( percentage >= lastPercentage ) {
TString msg; msg.Form("%lu", NumEntries);
int len = msg.Sizeof();
printf("Processed : %*lld, %3.0f%% | Elapsed %6.1f sec | expect %6.1f sec\n\033[A\r", len, entry, percentage, stpWatch.RealTime(), stpWatch.RealTime()/percentage*100);
stpWatch.Start(kFALSE);
lastPercentage = percentage + 1.0;
if( lastPercentage >= 100) printf("\n");
}
}
newSaveTree->Fill();
return kTRUE;
}
//^##############################################################
void GeneralSort::Terminate(){
printf("=============================== %s\n", __func__);
// CleanUpMemory(); //? Should Clean?
if( !isParallel){
stpWatch.Start(kFALSE);
saveFile->cd();
// newSaveTree->Print("toponly");
newSaveTree->Write();
saveFile->Close();
}
//get entries
saveFile = TFile::Open(saveFileName);
if( saveFile->IsOpen() ){
TTree * tree = (TTree*) saveFile->FindObjectAny("gen_tree");
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);
printf("=========================================================================\n");
}
}
//^##############################################################
void GeneralSort::Begin(TTree * tree){
printf( "================================================================================\n");
printf( "============================ SOLARIS GeneralSort.C =========================\n");
printf( "================================================================================\n");
mapping::PrintMapping();
DecodeOption();
if(!isParallel) {
tree->GetEntriesFast();
stpWatch.Start();
}
}
void GeneralSort::SlaveBegin(TTree * /*tree*/){
}
void GeneralSort::SlaveTerminate(){
printf("============= %s\n", __func__);
if( isParallel){
printf("%s::SaveTree\n", __func__);
saveFile->cd();
newSaveTree->Write();
fOutput->Add(proofFile);
saveFile->Close();
printf("---- closing this worker\n");
}
}

359
armory/GeneralSort.h Normal file
View File

@ -0,0 +1,359 @@
#ifndef GeneralSort_h
#define GeneralSort_h
#include <TROOT.h>
#include <TChain.h>
#include <TTree.h>
#include <TFile.h>
#include <TSelector.h>
#include <TObjString.h>
#include <TGraph.h>
#include <TClonesArray.h>
#include <TF1.h>
#include <TStopwatch.h>
#include <TProofOutputFile.h>
//^######################################### Skip list for trace fitting
//TODO
/*********************************=======
the sequence of each method
1) Begin (master, stdout)
2) SlaveBegin (slave)
3) Init
4) Notify
5) Process (looping each event)
6) SlaveTerminate
7) Terminate
// variable in the Master will not pass to Slave
******************************************/
/// in Process_Sort, copy the Mapping.h to ~/.proof/working/
#include "../working/Mapping.h"
//^######################################### FIT FUNCTION
const int numPara = 6;
double fitFunc(double * x, double * par){
/// par[0] = A
/// par[1] = t0
/// par[2] = rise time
/// par[3] = baseline
/// par[4] = decay
/// par[5] = pre-rise slope
if( x[0] < par[1] ) return par[3] + par[5] * (x[0]-par[1]);
return par[3] + par[0] * (1 - TMath::Exp(- (x[0] - par[1]) / par[2]) ) * TMath::Exp(- (x[0] - par[1]) / par[4]);
}
TStopwatch stpWatch;
//^######################################### Class definition
// Header file for the classes stored in the TTree if any.
class GeneralSort : public TSelector {
public :
TTree *fChain; //!pointer to the analyzed TTree or TChain
// Fixed size dimensions of array or collections stored in the TTree if any.
// 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]
ULong64_t e_t[100]; //[multi]
UShort_t lowFlag[100]; //[multi]
UShort_t highFlag[100]; //[multi]
Int_t tl[100]; //[multi]
Int_t trace[100][2500]; //[multi]
// List of branches
TBranch *b_evID; //!
TBranch *b_multi; //!
TBranch *b_bd; //!
TBranch *b_ch; //!
TBranch *b_e; //!
TBranch *b_e_t; //!
TBranch *b_lowFlag; //!
TBranch *b_highFlag; //!
TBranch *b_tl; //!
TBranch *b_trace; //!
GeneralSort(TTree * /*tree*/ =0) : fChain(0) {
printf("constructor :: %s\n", __func__);
isTraceExist = false;
traceMethod = 0; // 0 = ignore trace, 1 = no trace fit, 2 = fit, 3 = trapezoid
isParallel = false;
saveFile = nullptr;
newSaveTree = nullptr;
eE = nullptr;
eT = nullptr;
arr = nullptr;
gTrace = nullptr;
gFit = nullptr;
arrTrapezoid = nullptr;
gTrapezoid = nullptr;
teE = nullptr;
teT = nullptr;
teR = nullptr;
}
virtual ~GeneralSort() { }
virtual Int_t Version() const { return 2; }
virtual void Begin(TTree *tree);
virtual void SlaveBegin(TTree *tree);
virtual void Init(TTree *tree);
virtual Bool_t Notify();
virtual Bool_t Process(Long64_t entry);
virtual Int_t GetEntry(Long64_t entry, Int_t getall = 0) { return fChain ? fChain->GetTree()->GetEntry(entry, getall) : 0; }
virtual void SetOption(const char *option) { fOption = option; }
virtual void SetObject(TObject *obj) { fObject = obj; }
virtual void SetInputList(TList *input) { fInput = input; }
virtual TList *GetOutputList() const { return fOutput; }
virtual void SlaveTerminate();
virtual void Terminate();
ClassDef(GeneralSort,0);
bool isTraceExist;
int traceMethod;
void CleanUpMemory();
void SetTraceMethod(int methodID) {traceMethod = methodID;}
void PrintTraceMethod();
void SetUpTree();
void DecodeOption();
bool isParallel;
unsigned long NumEntries;
TString saveFileName;
TFile * saveFile; //!
TProofOutputFile * proofFile; //!
TTree * newSaveTree; //!
Float_t ** eE; //!
ULong64_t ** eT; //!
//trace
TClonesArray * arr ;//!
TGraph * gTrace; //!
TF1 * gFit; //!
TClonesArray * arrTrapezoid ;//!
TGraph * gTrapezoid; //!
//trace energy, trigger time, rise time
Float_t **teE; //!
Float_t **teT; //!
Float_t **teR; //!
};
#endif
#ifdef GeneralSort_cxx
//^##############################################################
void GeneralSort::SetUpTree(){
printf("%s\n", __func__);
if( isParallel){
proofFile = new TProofOutputFile(saveFileName, "M");
saveFile = proofFile->OpenFile("RECREATE");
}else{
saveFile = new TFile(saveFileName,"RECREATE");
}
newSaveTree = new TTree("gen_tree", "Tree After GeneralSort");
newSaveTree->SetDirectory(saveFile);
newSaveTree->AutoSave();
newSaveTree->Branch( "evID", &evID, "evID/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]];
for( int j = 0; j < mapping::detNum[i]; j++){
eE[i][j] = TMath::QuietNaN();
eT[i][j] = 0;
}
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]));
}
if( isTraceExist && traceMethod > 0){
arr = new TClonesArray("TGraph");
newSaveTree->Branch("trace", arr, 256000);
arr->BypassStreamer();
arr->Clear("C");
if( traceMethod > 1 ){
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]];
for( int j = 0; j <mapping::detNum[i]; j++){
teE[i][j] = TMath::QuietNaN();
teT[i][j] = TMath::QuietNaN();
teR[i][j] = TMath::QuietNaN();
}
//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]));
}
}
}
if( !isParallel ) newSaveTree->Print("toponly");
}
//^##############################################################
void GeneralSort::DecodeOption(){
TString option = GetOption();
if( option != ""){
TObjArray * tokens = option.Tokenize(",");
traceMethod = ((TObjString*) tokens->At(0))->String().Atoi();
saveFileName = ((TObjString*) tokens->At(1))->String();
isParallel = ((TObjString*) tokens->At(2))->String().Atoi();
}else{
traceMethod = -1;
saveFileName = "temp.root";
isParallel = false;
}
PrintTraceMethod();
printf(" Parallel: %s \n", isParallel ? "Yes" : "No");
printf(" save file: %s \n", saveFileName.Data());
}
//^##############################################################
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("multi", &multi, &b_multi);
fChain->SetBranchAddress("bd", bd, &b_bd);
fChain->SetBranchAddress("ch", ch, &b_ch);
fChain->SetBranchAddress("e", e, &b_e);
fChain->SetBranchAddress("e_t", e_t, &b_e_t);
fChain->SetBranchAddress("lowFlag", lowFlag, &b_lowFlag);
fChain->SetBranchAddress("highFlag", highFlag, &b_highFlag);
TBranch * br = (TBranch *) fChain->GetListOfBranches()->FindObject("traceLen");
if( br == NULL ){
printf(" ++++++++ no Trace.\n");
isTraceExist = false;
}else{
printf(" ++++++++ Found Trace.\n");
isTraceExist = true;
fChain->SetBranchAddress("traceLen", tl, &b_tl);
fChain->SetBranchAddress("trace", trace, &b_trace);
}
NumEntries = fChain->GetEntries();
printf( " ======== total Entry : %ld\n", NumEntries);
//########################### Get Option
DecodeOption();
SetUpTree();
gFit = new TF1("gFit", fitFunc, 0, 1250, numPara);
gFit->SetLineColor(6);
printf("---- end of Init %s\n ", __func__);
}
Bool_t GeneralSort::Notify(){
return kTRUE;
}
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;
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");
}
#endif // #ifdef GeneralSort_cxx

56
armory/GeneralSortAgent.C Normal file
View File

@ -0,0 +1,56 @@
#include "TTree.h"
#include "TChain.h"
#include "TMacro.h"
#include "TFile.h"
#include "TProof.h"
void GeneralSortAgent(Int_t runNum, int nWorker = 1, int traceMethod = 0){
TString name;
name.Form("../root_data/run%03d.root", runNum);
TChain * chain = new TChain("tree");
chain->Add(name);
chain->GetListOfFiles()->Print();
printf("\033[1;33m---------------------total number of Events %llu\033[0m\n", chain->GetEntries());
if( chain->GetEntries() == 0 ) return;
//this is the option for TSelector, the first one is traceMethod, 2nd is save fileName;
TString option;
if( abs(nWorker) == 1){
option.Form("%d,../root_data/gen_run%03d.root,%d", traceMethod, runNum, 0);
chain->Process("../Armory/GeneralSort.C+", option);
}else{
TProof * p = TProof::Open("", Form("workers=%d", abs(nWorker)));
p->ShowCache();
printf("----------------------------\n");
chain->SetProof();
option.Form("%d,../root_data/gen_run%03d.root,%d", traceMethod, runNum, 1);
chain->Process("../Armory/GeneralSort.C+", option);
}
//========== open the output root and copy teh timestamp Marco
TFile * f1 = new TFile(Form("../root_data/run%03d.root", runNum), "READ");
TMacro * m = (TMacro* ) f1->Get("timeStamp");
m->AddLine(Form("%d", runNum));
TFile * f2 = new TFile(Form("../root_data/gen_run%03d.root", runNum), "UPDATE");
f2->cd();
m->Write("timeStamp");
f1->Close();
f2->Close();
delete chain;
}

View File

@ -0,0 +1,90 @@
#!/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

109
armory/Process_Download Executable file
View File

@ -0,0 +1,109 @@
#!/bin/bash
echo -e "${RED}##################### Loading Process_Download.sh ${NC}"
if [ $# -eq 0 ] || [ $1 == "-help" ]; then
echo "$./process_Download [RunNum]"
echo " RunNum = run number"
echo " * if RunNum = all, sync all"
exit 1
fi;
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
IP=solarisdaq # defined at ~/.ssh/config
USR=solaris
if [ ${RUN} == "all" ]; then
if [ ${PCID} -eq 2 ]; then
#=========== Ping to check the connectivity
echo "Checking $IP connetivity, max wait for 3 sec...."
ping -c 3 -W 3 $IP #> /dev/null
if [ $? -ne 0 ]; then
echo -e "$RED !!!!!!! $IP is not alive $NC"
else
#============ Get the raw data
rsync -avuht --progress $USR@$IP:$rawDataPath/$expName_* $MacRawDataPath/data/.
echo -e "$YELLOW======== rsync RunTimeStamp.dat $NC"
rsync -avuht --progress $USR@$IP:$rawDataPath/$RunTimeStamp* $MacRawDataPath/data/.
echo -e "$YELLOW======== rsync expName.sh $NC"
rsync -avuht --progress $USR@$IP:Analysis/working/expName.sh $SOLARISANADIR/working/.
fi
else
echo -e "$RED############### Only in SOLARIS MAC can donwload data. skip.$NC"
fi
echo -e "$YELLOW=============================================$NC"
tail -10 $MacRawDataPath/raw_data/RunTimeStamp.dat
echo -e "$YELLOW=============================================$NC"
exit 1
fi
#just in case people put %03d as RUN
if [ "${RUN:0:2}" == "00" ]; then
RUN=${RUN:2:1}
elif [ "${RUN:0:1}" == "0" ]; then
RUN=${RUN:1:2}
else
RUN=$(printf '%d' $RUN)
fi
RUN=$(printf '%03d' ${RUN})
#######################################
#################### Download raw data
echo -e "${CYAN}>>>>>>>>>>>>>>> Download raw data: run ${RUN}${NC}"
if [ ${PCID} -eq 2 ]; then
#=========== Ping to check the connectivity
echo "Checking $IP connetivity, max wait for 3 sec...."
ping -c 3 $IP -W 3 #> /dev/null
if [ $? -ne 0 ]; then
echo -e "$RED !!!!!!! $IP is not alive $NC"
else
#============ Get the raw data
echo -e "================= RUN $RUN: Get the raw data `date`"
rsync -avuht --progress $USR@$IP:$rawDataPath/$expName_$RUN* $MacRawDataPath/data/.
echo -e "$YELLOW======== rsync RunTimeStamp.dat $NC"
rsync -avuht --progress $USR@$IP:$rawDataPath/$RunTimeStamp* $MacRawDataPath/data/.
echo -e "$YELLOW======== rsync expName.sh $NC"
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"
fi
if [ -z ${rawDataPath}/RunTimeStamp.dat ]; then
echo -e "$YELLOW=============================================$NC"
tail -10 ${rawDataPath}/RunTimeStamp.dat
echo -e "$YELLOW=============================================$NC"
fi
count=`ls -1 ${rawDataPath}/${expName}_${RUN}_*.sol 2>/dev/null | wc -l`
echo -e "========================= Number of Files : ${count}${YELLOW}"
if [ ${count} -eq 0 ]; then
echo "${NC}============================================"
echo "==== RAW Files of RUN-${RUN} not found! "
echo "============================================"
isRunDataExist=false
exit 1
else
du -hc ${rawDataPath}//${expName}_${RUN}_*.sol
echo -e "$NC============================================="
isRunDataExist=true
fi

111
armory/Process_EventBuilder Executable file
View File

@ -0,0 +1,111 @@
#!/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"
echo " EventBld = 2/1/0/-1/-2 || 2 = with Trace"
echo " timeWin = number of tick for an event "
echo ""
exit 1
fi;
RUN=$1
EventBld=$2
timeWin=$3
source ${SOLARISANADIR}/Armory/Process_BasicConfig
if [ -z $expName ]; then
source $SOLARISANADIR/working/expName.sh
fi
runNum=${RUN#0} #remove zero
RUN=$(printf '%03d' $runNum) ##add back the zero
rawDataPattern="$rawDataPath/${expName}_${RUN}_*.sol"
rootDataName="$rootDataPath/run$RUN.root"
#==== check raw data exist
isRawDataExist=`ls -1 ${rawDataPattern}* 2>/dev/null | wc -l`
if [ ! $isRawDataExist -gt 0 ]; then
echo -e "${LRED}################# Run Data $rawDataPattern not exist. Abort. ${NC}"
exit
fi
echo -e "${YELLOW} ============== 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}"
#==== check raw data timeStamp
if [ ${Arch} == "Linux" ]; then
rawDataTime=`stat -c "%Z" ${rawDataPattern}* | sort -rn | head -1`
else
rawDataTime=`stat -f "%Sm" -t "%Y%m%d%H%M%S" $rawDataPattern | sort -rn | head -1`
fi
#==== check if root data exist
isRootDataExist=`ls -1 $rootDataName 2>/dev/null | wc -l`
#==== if root data exist, check timeStamp
if [ ${isRootDataExist} -gt 0 ]; then
if [ ${Arch} == "Linux" ]; then
rootDataTime=`stat -c "%Z" $rootDataName | sort -rn | head -1`
else
rootDataTime=`stat -f "%Sm" -t "%Y%m%d%H%M%S" $rootDataName | sort -rn | head -1`
fi
else
rootDataTime=0
fi
if [ ${EventBld} -eq 0 ]; then
echo -e "${LRED}>>>>>>>>>>>>>>>>>>>>> Event Building Skipped by user. ${NC}"
elif [ ${EventBld} -ge 1 ]; then
if [ ${rawDataTime} -ge ${rootDataTime} ]; then
echo -e "${LRED}>>>>>>>>>>>>>>>>>>>>> Event Building $(date) ${NC}"
if [ ${EventBld} -eq 1 ]; then
EventBuilder $rootDataName ${timeWin} 0 $rawDataPattern
elif [ ${EventBld} -eq 2 ]; then
EventBuilder $rootDataName ${timeWin} 1 $rawDataPattern
fi
echo -e "${LRED}<<<<<<<<<<<<<<<< Done Event Building $(date) ${NC}"
else
echo -e "${GREEN} root data are newer than raw data. No need to merged again.${NC}"
echo -e "${GREEN} You can Force merging using option -${EventBld}, ${ORANGE} see ./process_run.sh -help${NC}"
echo -e "${LRED}>>>>>>>>>>>>>>>>>>>>> Event Building Skipped. ${NC}"
fi
else
echo -e "${LRED}>>>>>>>>>>>>>>> Force Event Building $(date) ${NC}"
if [ ${EventBld} -eq -1 ]; then
EventBuilder $rootDataName ${timeWin} 0 $rawDataPattern
elif [ ${EventBld} -eq -2 ]; then
EventBuilder $rootDataName ${timeWin} 1 $rawDataPattern
fi
echo -e "${LRED}<<<<<<<<<<<<<<<< Done Event Building $(date) ${NC}"
fi

96
armory/Process_MultiRuns Executable file
View File

@ -0,0 +1,96 @@
#!/bin/bash -l
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 [ $# -le 2 ] || [ $1 == "-help" ]; then
echo "$./process_MultiRuns [RunNum1] [RunNum2] [EventBuild] [GeneralSort] [numMacTerminal]"
echo " RunNum1 = start run number"
echo " RunNum2 = stop run number"
echo " EventBld = 2/1/0/-1/-2 || 2 = with Trace"
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"
echo " numMacTerminal = n ^ || in order to speed up in Mac "
echo " * negative option = force "
echo " ^ only for mac, and it will override GeneralSort to be 1 worker. "
exit 1
fi;
runID1=$1
runID2=$2
buidEvt=$3
nWorker=0
traceMethod=0
nTerminal=0
if [ $# -ge 4 ]; then nWorker=$4; fi
if [ $# -ge 5 ]; then traceMethod=$5; fi
if [ $# -ge 6 ]; then nTerminal=$6; fi
source ${SOLARISANADIR}/armory/Process_BasicConfig
source ${SOLARISANADIR}/working/expName.sh
if [ $PCID -eq 2 ]; then
if [ $nTerminal -ge 2 ]; then
if [[ $nWorker -ge 0 ]]; then
nWorker=1;
else
nWorker=-1;
fi
fi
else
$nTerminal=0;
fi
if [ $nTerminal -eq 0 ]; then
for i in $(seq $runID1 $runID2); do
Process_Run $i $buidEvt $nWorker $traceMethod 0
done
else
if [ $PCID -ne 2 ]; then
exit 1
fi
# Calculate the size of each segment
segment_size=$(( ($runID2 - $runID1 + 1) / $nTerminal ))
# Iterate through the segments
for i in $(seq 0 $(( $nTerminal - 1 ))); do
start=$(( $runID1 + ($i * $segment_size) ))
end=$(( $start + $segment_size - 1 ))
# Handle the last segment, which may be larger
if [[ $i -eq $(( $nTerminal - 1 )) ]]; then
end=$runID2
fi
echo "Segment $(( $i + 1 )): [$start, $end]"
profile_name="Homebrew"
width=700
height=500
x_pos=200
y_pos=200
osascript <<END_SCRIPT
tell application "Terminal"
activate
set newWindow to do script "cd $SOLARISANADIR/working; Process_MultiRuns $start $end $buidEvt $nWorker $traceMethod"
set current settings of newWindow to settings set "$profile_name"
set size of front window to { $width, $height }
set position of front window to { $x_pos + $(( $i * 100 )), $y_pos + $(( $i * 100 )) }
end tell
END_SCRIPT
done
fi

101
armory/Process_Run Executable file
View File

@ -0,0 +1,101 @@
#!/bin/bash
######## default time window = 100 tick
timeWin=100
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 [ "$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 " 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 " Monitor = 2/1/0 || 1 = single run, 2 = using the list in ChainMonitors.C"
echo ""
echo " * negative option = force."
echo " * Defult timeWindow for Event builder is 100 tick = 800 ns."
echo ""
exit 1
fi;
RUN=$1
runNum=$1
EventBld=1
nWorker=1
TraceMethod=0
isMonitor=1
if [ $# -ge 2 ]; then EventBld=$2; fi
if [ $# -ge 3 ]; then nWorker=$3; fi
if [ $# -ge 4 ]; then isMonitor=$4; fi
temp=$((nWorker / 100));
if [ $temp -lt 0 ]; then
TraceMethod=$((-1 * temp));
fi
nWorker=$((nWorker % 100 ));
runNum=${RUN#0} #remove zero
RUN=$(printf '%03d' $runNum) ##add back the zero
################################### Setting display
echo "#################################################"
echo "### Process_Run #####"
echo "#################################################"
echo "### RunID : ${RUN}"
echo "### Event Builder : $EventBld"
echo "### General Sort : $nWorker worker(s)"
echo "### Trace Method : $TraceMethod"
echo "### Monitor : $isMonitor"
echo "#################################################"
source ${SOLARISANADIR}/Armory/Process_BasicConfig
source ${rawDataPath}/expName.sh
#################################### CHECK IS RUN DATA EXIST
isRunDataExist=false
#################################### EVENT BUILDER
source Process_Download $RUN
if [ $isRunDataExist ]; then
source Process_EventBuilder $RUN $EventBld $timeWin
fi
#################################### GeneralSort
if [ $isRunDataExist ]; then
source Process_Sort $RUN $nWorker $TraceMethod
fi
#################################### Monitor
if [ $isMonitor -eq 0 ]; then
echo -e "${LRED}>>>>>>>>>>>>>>>>>>>>> Monitor Skipped by user. ${NC}"
elif [ $isMonitor -eq 1 ]; then
root -l "ChainMonitors.C($runNum)"
elif [ $isMonitor -eq 2 ]; then
root -l "ChainMonitors.C"
fi

95
armory/Process_Sort Executable file
View File

@ -0,0 +1,95 @@
#!/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"
exit
fi
if [ $# -eq 0 ] || [ $1 == "-help" ]; then
echo "$ Process_Sort [RunNum] [GeneralSort] [TraceMethod]"
echo " RunNum = run number"
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"
echo ""
exit 1
fi;
RUN=$1
nWorker=$2
TraceMethod=$3
source $SOLARISANADIR/Armory/Process_BasicConfig
if [ -z $expName ]; then
source $SOLARISANADIR/working/expName.sh
fi
runNum=${RUN#0} #remove zero
RUN=$(printf '%03d' $runNum) ##add back the zero
if [ ${nWorker} -eq 0 ]; then
echo -e "${LRED}>>>>>>>>>>>>>>>>>>>>> GeneralSort Skipped by user. ${NC}"
else
source $ROOTSYS/bin/thisroot.sh
#--------- Check is runXXX.root exist
rootDataPath=$SOLARISANADIR/root_data
rootDataName="$rootDataPath/run$RUN.root"
isRootDataExist=`ls -1 $rootDataName 2>/dev/null | wc -l`
#==== if root data exist, check timeStamp
if [ $isRootDataExist -gt 0 ]; then
if [ ${Arch} == "Linux" ]; then
rootDataTime=`stat -c "%Z" $rootDataName | sort -rn | head -1`
else
rootDataTime=`stat -f "%Sm" -t "%Y%m%d%H%M%S" $rootDataName | sort -rn | head -1`
fi
else
rootDataTime=0
echo -e "$LRED ################# run$RUN.root does not exist. Abort. $NC"
exit 1
fi
#-------- check gen_root timestamp
genRootDataName="$rootDataPath/gen_run$RUN.root"
isGenRootDataExist=`ls -1 $genRootDataName 2>/dev/null | wc -l`
#----- if gen_runXXX.data exist, check timeStamp
if [ $isGenRootDataExist -gt 0 ]; then
if [ ${Arch} == "Linux" ]; then
genRootDataTime=`stat -c "%Z" $genRootDataName | sort -rn | head -1`
else
genRootDataTime=`stat -f "%Sm" -t "%Y%m%d%H%M%S" $genRootDataName | sort -rn | head -1`
fi
else
genRootDataTime=0
fi
mkdir -p ~/.proof/working
cp ${SOLARISANADIR}/working/Mapping.h ~/.proof/working/.
if [ $nWorker -le -1 ]; then
echo -e "${LRED}>>>>>>>>>>>>>>> Force GeneralSort $(date) ${NC}"
root -l -q -b "$SOLARISANADIR/Armory/GeneralSortAgent.C($runNum, $nWorker, $TraceMethod)"
echo -e "${LRED}<<<<<<<<<<<<<<<< Done GeneralSort $(date) ${NC}"
fi
if [ $nWorker -ge 1 ]; then
if [ $rootDataTime -ge $genRootDataTime ]; then
echo -e "${LRED}>>>>>>>>>>>>>>>>>>>>> GeneralSort $(date) ${NC}"
root -l -q -b "$SOLARISANADIR/Armory/GeneralSortAgent.C($runNum, $nWorker, $TraceMethod)"
echo -e "${LRED}<<<<<<<<<<<<<<<< Done GeneralSort $(date) ${NC}"
else
echo -e "${GREEN} gen_run$RUN.root is newer than run$RUN.root. No need to GeneralSort again.${NC}"
echo -e "${GREEN} You can Force GeneralSort using option -${nWorker}, ${ORANGE} see Process_Run -help${NC}"
echo -e "${LRED}>>>>>>>>>>>>>>>>>>>>> GeneralSort Skipped. ${NC}"
fi
fi
fi

144
armory/readRawTrace.C Normal file
View File

@ -0,0 +1,144 @@
#include <TROOT.h>
#include <TChain.h>
#include <TStyle.h>
#include <TSystem.h>
#include <TFile.h>
#include <TSelector.h>
#include <TCanvas.h>
#include <TGraph.h>
#include <TClonesArray.h>
#include <TBenchmark.h>
#include <TMath.h>
#include <TLatex.h>
#include <TF1.h>
#include <TLine.h>
#include <iostream>
#include "../working/Mapping.h"
void readRawTrace(TString fileName, int minDetID = 0, int maxDetID = 1000){
/**///==============================================================
TFile * f1 = new TFile (fileName, "read");
TTree * tree = (TTree *) f1->Get("tree");
if( tree == NULL ) {
printf("===== Are you using gen_runXXX.root ? please use runXXX.root\n");
return;
}
int totnumEntry = tree->GetEntries();
printf( "========== total Entry : %d \n", totnumEntry);
TCanvas * cRead = new TCanvas("cRead", "Read Raw Trace", 0, 1500, 800, 300);
cRead->Divide(1,1);
for( int i = 1; i <= 2 ; i++){
cRead->cd(i)->SetGrid();
}
cRead->SetGrid();
gStyle->SetOptFit(0);
/**///==============================================================
Int_t bd[200];
Int_t ch[200];
Int_t numHit;
Int_t trace[200][2500];
Int_t traceLength[200];
tree->SetBranchAddress("bd", bd);
tree->SetBranchAddress("ch", ch);
tree->SetBranchAddress("multi", &numHit);
tree->SetBranchAddress("trace", trace);
tree->SetBranchAddress("tl", traceLength);
TLatex text ;
text.SetNDC();
text.SetTextFont(62);
text.SetTextSize(0.06);
text.SetTextColor(2);
bool breakFlag = false;
bool lastEvFlag = false;
std::vector<int> oldEv;
int evPointer = 0;
TGraph * graph = new TGraph();
for( int ev = 0; ev < totnumEntry; ev++){
if( lastEvFlag ) {
ev = oldEv[evPointer];
lastEvFlag = false;
}
tree->GetEntry(ev);
int countJ = 0;
for( int j = 0; j < numHit ; j++){
int detID = mapping[bd[j]][ch[j]];
if( !(minDetID <= detID && detID <= maxDetID ) ) continue;
if( countJ == 0 ) printf("-------------------------------- ev : %d, evPointer : %d| num Trace : %d\n", ev, evPointer, numHit);
printf("nHit: %d, id : %d, trace Length : %u ( enter = next , q = stop, w = last)\n", j, detID, traceLength[j]);
graph->Clear();
graph->Set(traceLength[j]);
for( int k = 0; k < traceLength[j] ; k++){
graph->SetPoint(k, k, trace[j][k]);
//printf("%4d, %5d |", k, trace[j][k]);
//if( k % 10 ==0 ) printf("\n");
}
graph->SetTitle(Form("ev: %d, nHit : %d, id : %d, trace Length : %u\n", ev, j, detID, traceLength[j]));
cRead->cd(1);
cRead->Clear();
graph->Draw("Al");
//g->GetXaxis()->SetRangeUser(0, g->GetN());
//g->GetYaxis()->SetRangeUser(7500, 35000);
cRead->Update();
gSystem->ProcessEvents();
char s[80];
fgets(s, sizeof s, stdin);
if( s[0] == 113 ) { // 'q' = 113
breakFlag = true;
break;
}else if( s[0] == 119 ) { // 'w' = 119
if( j > 0 || countJ > 0 ) {
j = j - 2;
}
if( (j == 0 && (int)oldEv.size() >= 0 && evPointer > 0 ) || countJ == 0 ) {
if( evPointer > 0 ) evPointer --;
if( evPointer == 0 ) printf(" the first event!!! \n");
lastEvFlag = true;
//printf(" ev : %d, evPt : %d \n", oldEv[evPointer], evPointer);
break;
}
}
countJ ++;
}
if( breakFlag ) break;
if( lastEvFlag == false && countJ > 0 ){
if( oldEv.size() == evPointer ) oldEv.push_back(ev);
evPointer ++;
}
}
//gROOT->ProcessLine(".q");
}

171
armory/readTrace.C Normal file
View File

@ -0,0 +1,171 @@
#include <TROOT.h>
#include <TChain.h>
#include <TStyle.h>
#include <TSystem.h>
#include <TFile.h>
#include <TSelector.h>
#include <TCanvas.h>
#include <TGraph.h>
#include <TClonesArray.h>
#include <TBenchmark.h>
#include <TMath.h>
#include <TLatex.h>
#include <TF1.h>
#include <TLine.h>
#include <iostream>
void readTrace(TString fileName, int minDetID = 0, int maxDetID = 1000, bool isGoodOnly = false){
/**///==============================================================
TFile * f1 = new TFile (fileName, "read");
TTree * tree = (TTree *) f1->Get("gen_tree");
int totnumEntry = tree->GetEntries();
printf( "========== total Entry : %d \n", totnumEntry);
TCanvas * cRead = new TCanvas("cRead", "Read Trace", 0, 1500, 800, 300);
cRead->Divide(1,1);
for( int i = 1; i <= 2 ; i++){
cRead->cd(i)->SetGrid();
}
cRead->SetGrid();
gStyle->SetOptFit(0);
/**///==============================================================
TClonesArray * arr = new TClonesArray("TGraph");
tree->SetBranchAddress("trace", &arr);
//TODO UP-Down arrow for pervious-next control
TLine timeVLine;
TLatex text ;
text.SetNDC();
text.SetTextFont(62);
text.SetTextSize(0.06);
text.SetTextColor(2);
bool breakFlag = false;
bool lastEvFlag = false;
std::vector<int> oldEv;
int evPointer = 0;
for( int ev = 0; ev < totnumEntry; ev++){
if( lastEvFlag ) {
ev = oldEv[evPointer];
lastEvFlag = false;
}
tree->GetEntry(ev);
int nTrace = arr->GetEntriesFast();
int countJ = 0;
for( int j = 0; j < nTrace ; j++){
TGraph * g = (TGraph*) arr->At(j);
TString gTitle;
gTitle = g->GetTitle();
///printf("TGraph Title : %s\n", gTitle.Data());
int detID = 0;
int pos = gTitle.Index("id:");
gTitle.Remove(0, pos+3);
gTitle.Remove(3);
detID = gTitle.Atoi();
if( !(minDetID <= detID && detID <= maxDetID ) ) continue;
if( countJ == 0 ) printf("-------------------------------- ev : %d, evPointer : %d| num Trace : %d\n", ev, evPointer, nTrace);
TF1 * gFit = (TF1 *) g->FindObject("gFit");
TString kTitle;
if( gFit != NULL ){
double base, time = 0, riseTime, energy, chiSq;
energy = gFit->GetParameter(0);
time = gFit->GetParameter(1);
riseTime = gFit->GetParameter(2);
base = gFit->GetParameter(3);
chiSq = gFit->GetChisquare()/gFit->GetNDF();
int kind = gFit->GetLineColor();
int det = gFit->GetLineStyle();
///if( !(minDetID <= det && det <= maxDetID ) ) continue;
if( isGoodOnly){
if( abs(energy) < 1.5* g->GetRMS(2) ) continue;
if( time > gFit->GetXmax() || time < gFit->GetXmin()) continue;
if( time > 200 || time < 20) continue;
if( riseTime > gFit->GetXmax()/7. || riseTime < 0 ) continue;
}
//if( energy < 400 ) continue;
kTitle = Form("(%3d,%d), base: %8.1f, rise: %6.2f, time: %6.1f, energy: %8.1f | chi2: %8.1f, RMS: %6.1f",
det, kind, base, riseTime, time, energy, chiSq, g->GetRMS(2));
printf("%s |(q = break, w = last one)", kTitle.Data());
timeVLine.SetX1(time);
timeVLine.SetX2(time);
timeVLine.SetY1(-1000);
timeVLine.SetY2(20000);
timeVLine.SetLineColor(4);
}
cRead->cd(1);
//cRead->Clear();
g->Draw("AC");
//g->GetXaxis()->SetRangeUser(0, g->GetN());
//g->GetYaxis()->SetRangeUser(7500, 35000);
timeVLine.Draw("same");
if( gFit != NULL ) text.DrawText(0.11, 0.85, kTitle.Data());
cRead->Update();
gSystem->ProcessEvents();
char s[80];
fgets(s, sizeof s, stdin);
if( s[0] == 113 ) { // 'q' = 113
breakFlag = true;
break;
}else if( s[0] == 119 ) { // 'w' = 119
if( j > 0 || countJ > 0 ) {
j = j - 2;
}
if( (j == 0 && (int)oldEv.size() >= 0 && evPointer > 0 ) || countJ == 0 ) {
if( evPointer > 0 ) evPointer --;
if( evPointer == 0 ) printf(" the first event!!! \n");
lastEvFlag = true;
//printf(" ev : %d, evPt : %d \n", oldEv[evPointer], evPointer);
break;
}
}
countJ ++;
}
if( breakFlag ) break;
if( lastEvFlag == false && countJ > 0 ){
if( oldEv.size() == evPointer ) oldEv.push_back(ev);
evPointer ++;
}
}
//gROOT->ProcessLine(".q");
}

View File

@ -0,0 +1,656 @@
#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;
}

180
cleopatra/ClassDecay.h Normal file
View File

@ -0,0 +1,180 @@
#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

551
cleopatra/ClassHelios.h Normal file
View File

@ -0,0 +1,551 @@
#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

520
cleopatra/ClassIsotope.h Normal file
View File

@ -0,0 +1,520 @@
/***********************************************************************
*
* This is Isotope.h, To extract the isotope mass from massXX.txt
*
*-------------------------------------------------------
* created by Ryan (Tsz Leung) Tang, Nov-18, 2018
* email: goluckyryan@gmail.com
* ********************************************************************/
#ifndef ISOTOPE_H
#define ISOTOPE_H
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <stdio.h>
#include <stdlib.h>
#include "constant.h" // amu
#include <stdlib.h> //atoi
#include <algorithm>
std::string massData="../Cleopatra/mass20.txt";
// about the mass**.txt
// Mass Excess = (ATOMIC MASS - A)*amu | e.g. n : (1.088664.91585E-6-1)*amu
// mass excess uncertaintly
// BEA = (Z*M(1H) + N*M(1n) - Me(A,Z))/A , Me is the mass with electrons
// BEA = (Z*mp + N*mn - M(A,Z))/A , M is the mass without electrons
class Isotope {
public:
int A, Z;
double Mass, MassError, BEA;
std::string Name, Symbol;
std::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;}
void SetIso(int a, int z);
void SetIsoByName(std::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
double CalBeta(double T){
double Etot = Mass + T;
double gamma = 1 + T/Mass;
double beta = sqrt(1 - 1 / gamma / gamma ) ;
return beta;
}
void Print();
void ListShell();
private:
void FindMassByAZ(int a, int z); // give mass, massError, BEA, Name, Symbol;
void FindMassByName(std::string name); // give Z, mass, massError, BEA;
int TwoJ(int nShell);
std::string Orbital(int nShell);
int magic(int i){
switch (i){
case 0: return 2; break;
case 1: return 8; break;
case 2: return 20; break;
case 3: return 28; break;
case 4: return 40; break;
case 5: return 50; break;
case 6: return 82; break;
case 7: return 128; break;
}
return 0;
}
int magicShellID(int i){
switch (i){
case 0: return 0; break;
case 1: return 2; break;
case 2: return 5; break;
case 3: return 6; break;
case 4: return 9; break;
case 5: return 10; break;
case 6: return 15; break;
case 7: return 21; break;
}
return 0;
}
int fileStartLine;
int fileEndLine;
int lineMass050_099;
int lineMass100_149;
int lineMass150_199;
int lineMass200;
void setFileLines(){
fileStartLine = 37;
fileEndLine = 3594;
lineMass050_099 = 466;
lineMass100_149 = 1160;
lineMass150_199 = 1994;
lineMass200 = 2774;
}
bool isFindOnce;
};
void Isotope::SetIso(int a, int z){
this->A = a;
this->Z = z;
FindMassByAZ(a,z);
}
void Isotope::SetIsoByName(std::string name){
FindMassByName(name);
}
void Isotope::FindMassByAZ(int A, int Z){
std::string line;
int lineNum=0;
int list_A, list_Z;
std::ifstream myfile;
int flag=0;
setFileLines();
int numLineStart = fileStartLine;
int numLineEnd = fileEndLine;
if ( A >= 50 && A < 100) numLineStart = lineMass050_099;
if ( A >=100 && A < 150) numLineStart = lineMass100_149;
if ( A >=150 && A < 200) numLineStart = lineMass150_199;
if ( A >=200 ) numLineStart = lineMass200;
myfile.open(dataSource.c_str());
if (myfile.is_open()) {
while (/*! myfile.eof() &&*/ flag == 0 && lineNum <numLineEnd){
lineNum ++ ;
//printf("%3d ",lineNum);
getline (myfile,line);
if (lineNum >= numLineStart ){
list_Z = atoi((line.substr(10,5)).c_str());
list_A = atoi((line.substr(15,5)).c_str());
if ( A == list_A && Z == list_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);
str.erase(remove(str.begin(), str.end(), ' '), str.end());
this->Symbol = str;
std::ostringstream ss;
ss << A << this->Symbol;
this->Name = ss.str();
flag = 1;
}else if ( list_A > A) {
this->BEA = -404;
this->Mass = -404;
this->MassError = -404;
this->Symbol = "non";
this->Name = "non";
break;
}
}
}
if( this->Name == "1H" ) this->Name = "p";
if( this->Name == "2H" ) this->Name = "d";
if( this->Name == "3H" ) this->Name = "t";
if( this->Name == "4He" ) this->Name = "a";
myfile.close();
}else {
printf("Unable to open %s\n", dataSource.c_str());
}
}
void Isotope::FindMassByName(std::string name){
// done seperate the Mass number and the name
if( name == "n" ) {
this->Name = "1n";
this->BEA = 0;
this->Mass = mn;
this->MassError = 0;
this->Name = "n";
this->A = 1;
this->Z = 0;
return;
}
if( name == "p" ) name = "1H";
if( name == "d" ) name = "2H";
if( name == "t" ) name = "3H";
if( name == "a" ) name = "4He";
std::string temp = name;
int lastDigit = 0;
for(int i=0; temp[i]; i++){
if(temp[i] == '0') lastDigit = i;
if(temp[i] == '1') lastDigit = i;
if(temp[i] == '2') lastDigit = i;
if(temp[i] == '3') lastDigit = i;
if(temp[i] == '4') lastDigit = i;
if(temp[i] == '5') lastDigit = i;
if(temp[i] == '6') lastDigit = i;
if(temp[i] == '7') lastDigit = i;
if(temp[i] == '8') lastDigit = i;
if(temp[i] == '9') lastDigit = i;
}
this->Symbol = temp.erase(0, lastDigit +1);
//check is Symbol is 2 charaters, if not, add " " at the end
if( this->Symbol.length() == 1 ){
this->Symbol = this->Symbol + " ";
}
temp = name;
int len = temp.length();
temp = temp.erase(lastDigit+1, len);
this->A = atoi(temp.c_str());
//printf(" Symbol = |%s| , Mass = %d\n", this->Symbol.c_str(), this->A);
// find the nucleus in the data
std::string line;
int lineNum=0;
int list_A;
std::string list_symbol;
std::ifstream myfile;
int flag=0;
setFileLines();
int numLineStart = fileStartLine;
int numLineEnd = fileEndLine;
if ( A >= 50 && A < 100) numLineStart = lineMass050_099;
if ( A >=100 && A < 150) numLineStart = lineMass100_149;
if ( A >=150 && A < 200) numLineStart = lineMass150_199;
if ( A >=200 ) numLineStart = lineMass200;
myfile.open(dataSource.c_str());
if (myfile.is_open()) {
while (/*! myfile.eof() &&*/ flag == 0 && lineNum <numLineEnd){
lineNum ++ ;
//printf("%3d ",lineNum);
getline (myfile,line);
if (lineNum >= numLineStart ){
list_symbol = line.substr(20,2);
list_A = atoi((line.substr(15,5)).c_str());
//printf(" A = %d, Sym = |%s| \n", list_A, list_symbol.c_str());
if ( this->A == list_A && this->Symbol == list_symbol) {
this->Z = atoi((line.substr(10,5)).c_str());
this->BEA = atof((line.substr(54,11)).c_str());
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);
str.erase(remove(str.begin(), str.end(), ' '), str.end());
this->Symbol = str;
std::ostringstream ss;
ss << this->A << this->Symbol;
this->Name = ss.str();
flag = 1;
}else if ( list_A > this->A) {
this->BEA = -404;
this->Mass = -404;
this->MassError = -404;
this->Symbol = "non";
this->Name = "non";
break;
}
}
}
myfile.close();
}else {
printf("Unable to open %s\n", dataSource.c_str());
}
}
double Isotope::CalSp(int Np, int Nn){
Isotope nucleusD(A - Np - Nn, Z - Np);
if( nucleusD.Mass != -404){
return nucleusD.Mass + Nn*mn + Np*mp - this->Mass;
}else{
return -404;
}
}
double Isotope::CalSp2(int a, int z){
Isotope nucleusD(A - a , Z - z);
Isotope nucleusS(a,z);
if( nucleusD.Mass != -404 && nucleusS.Mass != -404){
return nucleusD.Mass + nucleusS.Mass - this->Mass;
}else{
return -404;
}
}
int Isotope::TwoJ(int nShell){
switch(nShell){
case 0: return 1; break; // 0s1/2
case 1: return 3; break; // 0p3/2
case 2: return 1; break; // 0p1/2 -- 8
case 3: return 5; break; // 0d5/2
case 4: return 1; break; // 1s1/2
case 5: return 3; break; // 0d3/2 -- 20
case 6: return 7; break; // 0f7/2 -- 28
case 7: return 3; break; // 1p3/2
case 8: return 1; break; // 1p1/2
case 9: return 5; break; // 0f5/2 -- 40
case 10: return 9; break; // 0g9/2 -- 50
case 11: return 7; break; // 0g7/2
case 12: return 5; break; // 1d5/2
case 13: return 11; break; // 0h11/2
case 14: return 3; break; // 1d3/2
case 15: return 1; break; // 2s1/2 -- 82
case 16: return 9; break; // 0h9/2
case 17: return 7; break; // 1f7/2
case 18: return 13; break; // 0i13/2
case 19: return 3; break; // 2p3/2
case 20: return 5; break; // 1f5/2
case 21: return 1; break; // 1p1/2 -- 126
case 22: return 9; break; // 1g9/2
case 23: return 11; break; // 0i11/2
case 24: return 15; break; // 0j15/2
case 25: return 5; break; // 2d5/2
case 26: return 1; break; // 3s1/2
case 27: return 3; break; // 2d3/2
case 28: return 7; break; // 1g7/2
}
return 0;
}
std::string Isotope::Orbital(int nShell){
switch(nShell){
case 0: return "0s1 "; break; //
case 1: return "0p3 "; break; //
case 2: return "0p1 "; break; //-- 8
case 3: return "0d5 "; break; //
case 4: return "1s1 "; break; //
case 5: return "0d3 "; break; //-- 20
case 6: return "0f7 "; break; //-- 28
case 7: return "1p3 "; break; //
case 8: return "1p1 "; break; //
case 9: return "0f5 "; break; //-- 40
case 10: return "0g9 "; break; //-- 50
case 11: return "0g7 "; break; //
case 12: return "1d5 "; break; //
case 13: return "0h11"; break; //
case 14: return "1d3 "; break; //
case 15: return "2s1 "; break; //-- 82
case 16: return "0h9 "; break; //
case 17: return "1f7 "; break; //
case 18: return "0i13"; break; //
case 19: return "2p3 "; break; //
case 20: return "1f5 "; break; //
case 21: return "1p1 "; break; //-- 126
case 22: return "1g9 "; break; //
case 23: return "0i11"; break; //
case 24: return "0j15"; break; //
case 25: return "2d5 "; break; //
case 26: return "3s1 "; break; //
case 27: return "2d3 "; break; //
case 28: return "1g7 "; break; //
}
return "nan";
}
void Isotope::ListShell(){
if( Mass < 0 ) return;
int n = A-Z;
int p = Z;
int k = std::min(n,p);
int nMagic = 0;
for( int i = 0; i < 7; i++){
if( magic(i) < k && k <= magic(i+1) ){
nMagic = i;
break;
}
}
int coreShell = magicShellID(nMagic-1);
int coreZ1 = magic(nMagic-1);
int coreZ2 = magic(nMagic);
Isotope core1( 2*coreZ1, coreZ1);
Isotope core2( 2*coreZ2, coreZ2);
printf("------------------ Core:%3s, inner Core:%3s \n", (core2.Name).c_str(), (core1.Name).c_str());
printf(" || ");
int t = std::max(n,p);
int nShell = 0;
do{
int occ = TwoJ(nShell)+1;
if( nShell > coreShell) {
printf("%4s", Orbital(nShell).c_str());
if( nShell == 0 || nShell == 2 || nShell == 5 || nShell ==6 || nShell == 9 || nShell == 10 || nShell == 15 || nShell == 21){
printf("|");
}else{
printf(",");
}
}
t = t - occ;
nShell++;
}while( t > 0 && nShell < 29);
for( int i = 1; i <= 6; i++){
if (nShell < 28) {
printf("%4s,", Orbital(nShell).c_str());
}else if( nShell == 28 ) {
printf("%4s", Orbital(nShell).c_str());
}
nShell ++;
}
if (nShell < 29) printf("%4s", Orbital(nShell).c_str());
printf("\n");
printf(" Z = %3d || ", p);
nShell = 0;
do{
int occ = TwoJ(nShell)+1;
if( nShell > coreShell ){
if( p > occ ) {
printf("%-4d", occ);
if( nShell == 0 || nShell == 2 || nShell == 5 || nShell ==6 || nShell == 9 || nShell == 10 || nShell == 15 || nShell == 21){
printf("|");
}else{
printf(",");
}
}else{
printf("%-4d", p);
}
}
p = p - occ;
nShell++;
}while( p > 0 && nShell < 29);
printf("\n");
printf(" N = %3d || ", n);
nShell = 0;
do{
int occ = TwoJ(nShell)+1;
if ( nShell > coreShell ){
if( n > occ ) {
printf("%-4d", occ);
if( nShell == 0 || nShell == 2 || nShell == 5 || nShell ==6 || nShell == 9 || nShell == 10 || nShell == 15 || nShell == 21){
printf("|");
}else{
printf(",");
}
}else{
printf("%-4d", n);
}
}
n = n - occ;
nShell++;
}while( n > 0 && nShell < 29);
printf("\n");
printf("------------------ \n");
}
void Isotope::Print(){
if (Mass > 0){
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.);
printf(" mass in amu : %12.5f u\n",Mass/amu);
printf(" mass excess : %12.5f MeV\n", Mass + Z*0.510998950 - A*amu);
printf("-------------- Seperation energy \n");
printf(" S1p: %8.4f| S1n: %8.4f| S(2H ): %8.4f| S1p1n : %8.4f\n", CalSp(1, 0), CalSp(0, 1), CalSp2(2, 1), CalSp(1, 1));
printf(" S2p: %8.4f| S2n: %8.4f| S(3He): %8.4f| S(3H) : %8.4f\n", CalSp(2, 0), CalSp(0, 2), CalSp2(3, 2), CalSp2(3, 1));
printf(" S3p: %8.4f| S3n: %8.4f| S(4He): %8.4f|\n", CalSp(3, 0), CalSp(0, 3), CalSp2(4, 2));
printf(" S4p: %8.4f| S4n: %8.4f| \n", CalSp(4, 0), CalSp(0, 4));
}else{
printf("Error %6.0f, no nucleus with (Z,A) = (%3d,%3d). \n", Mass, Z, A);
}
}
#endif

301
cleopatra/ClassKnockout.h Normal file
View File

@ -0,0 +1,301 @@
#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

503
cleopatra/ClassSimPlotter.h Normal file
View File

@ -0,0 +1,503 @@
#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
cCheck->Update();
}
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

View File

@ -0,0 +1,202 @@
#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], &paraStraggling[0]);
gD = new TGraph(energy.size(), &energy[0], &prepStraggling[0]);
}
#endif

593
cleopatra/ClassTransfer.h Normal file
View File

@ -0,0 +1,593 @@
#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

111
cleopatra/Cleopatra.C Normal file
View File

@ -0,0 +1,111 @@
/***********************************************************************
*
* This is Cleopatra, a sucessor of Ptolemy
* only for (d,p), (d,p), (d,d), or (p,p)
*
* 1) it read a simple infile.in from reaction_setting file
* 2) use Ptolemy to calculate the the creation
* 3) extract the cross sec distribution into txt and root file
*
* -----------------------------------------------------
* This program will call the root library and compile in g++
* compilation:
* g++ cleopatra.C -o cleopatra `root-config --cflags --glibs`
*
*------------------------------------------------------
* The reaction_setting file is simple like:
*
* 206Hg(d,p)207Hg(1s1/2 0.000) 10MeV/u AK
*
* the first is similar to usual reaction setting, the word AK is a
* short name for Optical Potential, user can put as many line as
* they like, Cleopatra can create the suitable infile.in for Ptolomy
*
* ------------------------------------------------------
* created by Ryan (Tsz Leung) Tang, Nov-18, 2018
* email: goluckyryan@gmail.com
* ********************************************************************/
#include <fstream>
#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>
#include "InFileCreator.h"
#include "ExtractXSec.h"
#include <TApplication.h>
#include "PlotTGraphTObjArray.h"
int main (int argc, char *argv[]) { //TODO add angle range
printf("=================================================================\n");
printf("===== Cleopatra, Ptolemy for (d,p),(p,d), (p,p) and (d,d) =====\n");
printf("=================================================================\n");
if(argc < 2 || argc > 5) {
printf("Usage: ./Cleopatra input_file (angMin = 0 deg, angMax = 180 deg, angStep = 1 deg)\n");
printf("Usage: ./Cleopatra input_file angMin angMax (angStep = 1 deg)\n");
printf("Usage: ./Cleopatra input_file angMin angMax angStep\n");
exit(0);
}else{
printf("From file : %s \n", argv[1]);
}
//================= read infile. extract the reactions, write pptolemy infile for each reaction
std::string readFile = argv[1];
double angMin = 0.;
double angMax = 180.;
double angStep = 1.;
if( argc >= 4 ){
angMin = atof(argv[2]);
angMax = atof(argv[3]);
}
if( argc == 5 ){
angStep = atof(argv[4]);
}
std::string ptolemyInFileName = argv[1];
ptolemyInFileName += ".in";
printf("=================== Create InFile\n");
InFileCreator( readFile, ptolemyInFileName, angMin, angMax, angStep);
//================= run ptolemy
std::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();
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;
}
//================= extract the Xsec and save as txt and root
printf("=================== Extract Cross-section\n");
ExtractXSec(ptolemyOutFileName);
//================= Call root to plot the d.s.c.
printf("=================== Plot Result using ROOT.\n");
std::string rootFileName = argv[1];
rootFileName += ".root";
TApplication app ("app", &argc, argv);
PlotTGraphTObjArray(rootFileName);
app.Run(); //nothing run after
return 0;
}

48
cleopatra/ExtractXSec.C Normal file
View File

@ -0,0 +1,48 @@
/***********************************************************************
*
* This is ExtractXSec for *.out for Ptolemy
*
* This program will extract cross section distribution from Ptolmey output.
* save as *.Xsec.txt and *.root for distribution
*
* save ExPtolemy.txt for excitation energies and total X-section
* -----------------------------------------------------
* This program will call the root library and compile in g++
* compilation:
* g++ ExtractXSec.C -o ExtractXSec `root-config --cflags --glibs`
*
* ------------------------------------------------------
* created by Ryan (Tsz Leung) Tang, Nov-18, 2018
* email: goluckyryan@gmail.com
* ********************************************************************/
#include <fstream>
#include <stdlib.h>
#include "ExtractXSec.h"
using namespace std;
int main (int argc, char *argv[]) {
printf("=================================================================\n");
printf("========== Extract Cross-Section From Ptolemy out file ==========\n");
printf("=================================================================\n");
if(argc < 2 || argc > 3) {
printf("Usage: ./ExtractXSec input_file <ElasticFlag>\n");
printf(" ElasticFlag = 1 , default, extarct Ratio to Rutherford\n");
printf(" ElasticFlag = 2 , extarct Total Xsec\n");
printf(" ElasticFlag = 3 , Rutherford\n");
exit(0);
}else{
printf("From file : %s \n", argv[1]);
}
string readFile = argv[1];
int ElasticFlag = 1;
if( argc == 3 ){
ElasticFlag = atoi(argv[2]);
}
ExtractXSec(readFile, ElasticFlag);
}

546
cleopatra/ExtractXSec.h Normal file
View File

@ -0,0 +1,546 @@
/***********************************************************************
*
* This is ExtractXSec for *.out for Ptolemy
*
* This program will extract cross section distribution from Ptolmey output.
* save as *.Xsec.txt and *.root for distribution
*
* save ExPtolemy.txt for excitation energies and total X-section
* -----------------------------------------------------
* This program will call the root library and compile in g++
* compilation:
* g++ ExtractXSec.C -o ExtractXSec `root-config --cflags --glibs`
*
* ------------------------------------------------------
* created by Ryan (Tsz Leung) Tang, Nov-18, 2018
* email: goluckyryan@gmail.com
* ********************************************************************/
#include <stdlib.h>
#include <vector>
#include <TROOT.h>
#include <TFile.h>
#include <TString.h>
#include <TMath.h>
#include <TGraph.h>
#include <TMacro.h>
#include <TF1.h>
#include <TObjArray.h>
#include "../Armory/AnalysisLib.h"
using namespace std;
TObjArray * gList = NULL;
double distfunct(double *x, double *par){
TGraph * gTemp = (TGraph *) gList->At(par[0]);
return (gTemp->Eval(x[0]))* sin(x[0] * TMath::DegToRad());
}
bool isFloat( string str ) {
int length = str.length();
for( int i = 0; i < length; i++){
string it = str.substr(i,1);
if( it == " " || it == "."|| it == "1"|| it == "2"||
it == "3"|| it == "4"|| it == "5"|| it == "6"|| it == "7"|| it == "8"|| it == "9"|| it == "0"){
continue;
}else{
return false;
}
}
return true;
}
int ExtractXSec (string readFile, int indexForElastic=1) {
//indexForElastic = 1 ; for Ratio
//indexForElastic = 2 ; for Total
//indexForElastic = 3 ; for Rutherford
//--- open file.out
ifstream file_in;
file_in.open(readFile.c_str(), ios::in);
if( !file_in){
printf("Unable to open %s \n", readFile.c_str());
exit(1);
}
//---- variable for Xsec
vector<string> title;
vector<vector<double>> dataMatrix;
vector<double> angle;
vector<double> Ex;
vector<double> totalXsec;
vector<string> reaction;
double angleMin = 0;
double angleMax = 0;
double angleStep = -1;
//================================== read file.out
string line;
int lineNum = 0;
vector<double> dataXsec;
bool startExtract = false;
bool angleFilled = false;
int numCal = 0;
int reactionFlag = 0;
bool preFindForElastic = false;
printf("======================================================\n");
while(getline(file_in, line)){
lineNum ++;
//printf("%d , %s\n", lineNum, line.c_str());
size_t pos;
string findStr;
int findLen;
//---- find Title
findStr = "$============================================";
findLen = findStr.length();
pos = line.find(findStr);
if( pos != string::npos){
title.push_back(line.substr(pos + findLen+1));
pos = title.back().find("(");
string ex = title.back().substr(3, pos-3);
Ex.push_back( atof(ex.c_str()) );
//clear dataXsex for new data set
dataXsec.clear();
numCal ++;
continue;
}
//---- find Reaction
findStr = "0INPUT... CHANNEL";
findLen = findStr.length();
pos = line.find(findStr);
if( pos != string::npos ) {
reaction.push_back( line.substr(pos + findLen + 1) );
reactionFlag = 1; // 1 for (d,d) or (p,p)
///printf("%d |----------- (d,d), %d\n", lineNum, reactionFlag);
continue; // nextline
}
findStr = "REACTION:";
findLen = findStr.length();
pos = line.find(findStr);
if( pos != string::npos ) {
reaction.push_back( line.substr(pos + findLen + 1) );
reactionFlag = 2; // 2 for (d,p) or (p,d)
///printf("%d |----------- (d,p), %d\n", lineNum, reactionFlag);
continue; // nextline
}
//----- pre find for Elastic scattering
findStr = "0 OPTICAL MODEL SCATTERING FOR THE OUTGOING CHANNEL";
pos = line.find(findStr);
if( pos != string::npos ) {
preFindForElastic = true;
///printf("%d |----------- pre Elastics Flag : %d\n", lineNum, preFindForElastic);
continue;
}
//----- find angle stetting when not known
if( angleStep == -1 ){
findStr = "anglemin=";
findLen = findStr.length();
pos = line.find(findStr);
if( pos != string::npos){
size_t pos1 = line.find("anglemax=");
angleMin = atof( line.substr(pos+findLen, pos1 - pos - findLen).c_str() );
pos = pos1;
pos1 = line.find("anglestep=");
angleMax = atof( line.substr(pos+findLen, pos1 - pos - findLen).c_str() );
angleStep = atof( line.substr(pos1 + findLen+1).c_str() );
//printf("%d |---- angle range found.\n", lineNum);
}
continue; //nextline
}
//----- check if start extracting Xsec or not
findStr = "dumpdumpdump";
if( reactionFlag == 1 && preFindForElastic ){
findStr = "C.M. LAB RUTHERFORD";
}
if( reactionFlag == 2 ){
findStr = "0 C.M. REACTION REACTION LOW L HIGH L % FROM";
}
pos = line.find(findStr);
if( pos != string::npos ) {
startExtract = true;
//printf("%d |----- start extraction \n", lineNum);
continue;
}
//----- start extracting Xsec
if( startExtract ){
if( line.length() < 20 ) continue;
///printf("%d |%s \n", line.length(), line.c_str());
double numAngle, numXsec;
if( reactionFlag == 1 ){ // Elastics (d,d) or (p,p)
numAngle = atof( line.substr(0, 7).c_str());
if( indexForElastic == 1 ){
numXsec = atof( line.substr(15, 15).c_str());
}else if( indexForElastic == 2 ){
if ( line.length() > 60 ) {
numXsec = atof( line.substr(30, 13).c_str());
}else{
numXsec = -404;
}
}else{
if ( line.length() > 60 ) {
numXsec = atof( line.substr(57, 14).c_str());
}else{
numXsec = -404;
}
}
}
if( reactionFlag == 2 ){ // InElastics (d,p) or (p,d)
if( isFloat( line.substr(0, 7) ) ){
numAngle = atof( line.substr(0, 7).c_str());
numXsec = atof( line.substr(7, 19).c_str());
}else{
numAngle = -1.0;
numXsec = -1.0;
}
}
if( numAngle != numXsec && numXsec > 0. ){
if( !angleFilled ) angle.push_back(numAngle);
dataXsec.push_back(numXsec);
///printf(" %f , %f \n", angle.back(), dataXsec.back());
}
}
//------ find total Xsec, if found stop extraction
findStr = "dumpdumpdump";
if( reactionFlag == 1 && preFindForElastic){
findStr = "0TOTAL REACTION CROSS SECTION =";
}
if( reactionFlag == 2){
findStr = "0TOTAL:";
}
findLen = findStr.length();
pos = line.find(findStr);
if( pos != string::npos ) {
totalXsec.push_back( atof(line.substr(pos + findLen).c_str()) );
printf("%2d | %s | total Xsec(4pi): %f mb \n", numCal, title.back().c_str(), totalXsec.back());
//push back dataXsec to dataMatrix
dataMatrix.push_back(dataXsec);
//printf("%d |----- end extraction \n", lineNum);
angleFilled = true;
startExtract = false;
reactionFlag = 0;
preFindForElastic = false;
continue;
}
}
file_in.close();
//================================== summary
printf("====================== Total number of line read : %d \n", lineNum);
printf("Angle : %5.2f, %5.2f | step : %5.2f \n", angleMin, angleMax, angleStep);
printf("Number of Angle read : %lu \n", angle.size());
printf("Number of data read : %lu \n", dataXsec.size());
printf("Number of Reaction : %lu \n", reaction.size());
printf("----------------------------- list of Calculation \n");
//... find suitable lenght for displaying reaction string
int reactionStrLen = 0;
for( int i = 0; i < numCal ; i++){
int len = reaction[i].length();
if( len > reactionStrLen ) reactionStrLen = len;
}
vector<double> partialXsec;
partialXsec.clear();
for( int i = 0; i < numCal ; i++){
double partialSumXsec = 0.0;
for( int j = 0; j < (dataMatrix[i]).size() ; j++ ){
//double theta = (angle[j] + angleStep/2.) * TMath::DegToRad();
double theta = (angle[j]) * TMath::DegToRad();
double dTheta = angleStep * TMath::DegToRad();
double phi = TMath::TwoPi();
partialSumXsec += dataMatrix[i][j] * sin( theta ) * dTheta * phi ;
}
partialXsec.push_back(partialSumXsec);
size_t pos = title[i].find(")");
printf("%*s| %s | Xsec(%3.0f-%3.0f deg) : %f mb\n", reactionStrLen + 3, reaction[i].c_str(), title[i].substr(pos+1).c_str(), angleMin, angleMax, partialSumXsec);
}
printf("---------------------------------------------------\n");
//================================== save file.Xsec.txt
string saveFileName = readFile;
int len = saveFileName.length();
saveFileName = saveFileName.substr(0, len - 4);
saveFileName += ".Xsec.txt";
printf("Output : %s \n", saveFileName.c_str());
FILE * file_out;
file_out = fopen(saveFileName.c_str(), "w+");
for( int i = 0; i < numCal ; i++){
fprintf(file_out, "#%14s\n", reaction[i].c_str());
}
int space = 19;
fprintf(file_out, "%8s\t", "Angle");
for( int i = 0; i < numCal ; i++){
fprintf(file_out, "%*s", space, title[i].c_str());
}
fprintf(file_out, "\n");
for( int i = 0; i < angle.size() ; i ++){
fprintf(file_out, "%8.3f\t", angle[i]);
for( int j = 0; j < numCal ; j++){
fprintf(file_out, "%*f", space, dataMatrix[j][i]);
}
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();
saveFileName = saveFileName.substr(0, len - 9);
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();
fList->SetName("TF1 of distributions = d.s.c. * sin()");
TGraph ** gGraph = new TGraph *[numCal];
TF1 ** dist = new TF1*[numCal];
for( int i = 0; i < numCal ; i++){
gGraph[i] = new TGraph();
TString name = reaction[i];
name += "|";
name += title[i];
gGraph[i]->SetName(name);
for( int j = 0; j < angle.size() ; j++){
gGraph[i]->SetPoint(j, angle[j], dataMatrix[i][j]);
}
gList->Add(gGraph[i]);
name.Form("dist%d", i);
dist[i] = new TF1(name, distfunct, angleMin, angleMax, 1 );
dist[i]->SetParameter(0, i);
fList->Add(dist[i]);
}
gList->Write("thetaCM_TGraph", 1);
fList->Write("thetaCM_TF1", 1);
ExList.Write("ExList");
ReactList.Write("ReactionList");
fileOut->Write();
fileOut->Close();
printf("---------------------------------------------------\n");
return 0;
}
int ExtractXSecFromText(string readFile){
//read file
ifstream file_in;
file_in.open(readFile.c_str(), ios::in);
if( !file_in){
printf("Unable to open %s \n", readFile.c_str());
exit(1);
}
//---- variable for Xsec
vector<vector<double>> dataMatrix;
vector<double> angle;
vector<double> Ex;
//================================== read file.out
string line;
int lineNum = 0;
vector<double> dataXsec;
int numCal = 0;
printf("======================================================\n");
bool headerDone = false;
while(getline(file_in, line)){
lineNum ++;
if( line.substr(0,1) == "#" ) continue;
//printf("%d | %s\n", lineNum, line.c_str());
//after the comment line, the next line must be column name
vector<string> header= AnalysisLib::SplitStr(line, " ");
//printf("---%lu #", header.size());
//for( int i = 0; i < header.size(); i++){
// printf("%s|", header[i].c_str());
//}
//printf("\n");
if ( !headerDone ) {
for( int i = 1 ; i < header.size(); i++){
string energy = header[i].substr(3, header[i].length());
Ex.push_back(atof(energy.c_str()));
//printf("%f---\n", Ex.back());
}
headerDone = true;
}else{
vector<double> temp;
for( int i = 0; i < header.size(); i++){
if( i == 0 ) angle.push_back(atof(header[i].c_str()));
if( i > 0 ) temp.push_back(atof(header[i].c_str()));
}
dataMatrix.push_back(temp);
}
}
file_in.close();
double angleMin = angle.front();
double angleMax = angle.back();
double angleStep = (angleMax - angleMin)/(angle.size()-1);
//------ print out read data
printf("====================== data read as:\n");
printf("%5s, ", "Ex");
for(int i = 0; i < Ex.size(); i++){
printf("%6.3f|", Ex[i]);
}
printf("\n");
for(int i = 0; i < dataMatrix.size(); i++){
printf("%5.2f, ", angle[i]);
for( int j = 0; j < dataMatrix[i].size(); j++) printf("%6.3f|", dataMatrix[i][j]);
printf("\n");
}
printf("---------------------------------\n");
printf("angle min :%f\n", angleMin);
printf("angle max :%f\n", angleMax);
printf("angle step:%f\n", angleStep);
printf("---------------------------------\n");
//------- calculate summed cross section
vector<double> partialXsec(Ex.size());
for( int i = 0; i < dataMatrix.size() ; i++){
for( int j = 0; j < (dataMatrix[i]).size() ; j++ ){
//double theta = (angle[j] + angleStep/2.) * TMath::DegToRad();
double theta = (angle[i]) * TMath::DegToRad();
double dTheta = angleStep * TMath::DegToRad();
double phi = TMath::TwoPi();
partialXsec[j] += dataMatrix[i][j] * sin( theta ) * dTheta * phi ;
}
}
for(int i = 0; i < Ex.size(); i++){
printf("Ex=%6.3f| Xsec(%3.0f-%3.0f deg) : %f mb\n", Ex[i] , angleMin, angleMax, partialXsec[i]);
}
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___SF____sigma\n");
for( int i = 0; i < Ex.size() ; 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 in ROOT
string saveFileName = readFile;
len = saveFileName.length();
saveFileName = saveFileName.substr(0, len - 4);
TString fileName = saveFileName;
fileName += ".root";
printf("Output : %s \n", fileName.Data());
TFile * fileOut = new TFile(fileName, "RECREATE" );
gList = new TObjArray();
gList->SetName("TGraph of d.s.c");
TObjArray * fList = new TObjArray();
fList->SetName("TF1 of distributions = d.s.c. * sin()");
TGraph ** gGraph = new TGraph *[numCal];
TF1 ** dist = new TF1*[numCal];
for( int i = 0; i < Ex.size() ; i++){
gGraph[i] = new TGraph();
TString name ;
name.Form("Ex=%6.3f MeV", Ex[i]);
gGraph[i]->SetName(name);
for( int j = 0; j < angle.size() ; j++){
gGraph[i]->SetPoint(j, angle[j], dataMatrix[j][i]);
}
gList->Add(gGraph[i]);
name.Form("dist%d", i);
dist[i] = new TF1(name, distfunct, angleMin, angleMax, 1 );
dist[i]->SetParameter(0, i);
fList->Add(dist[i]);
//delete tempFunc;
}
gList->Write("qList", 1);
fList->Write("pList", 1);
fileOut->Write();
fileOut->Close();
printf("---------------------------------------------------\n");
return 0;
}

View File

@ -0,0 +1,41 @@
/***********************************************************************
*
* This is ExtractXSecFromText for *.txt file
*
* This program will extract cross section distribution
* save as *.root for distribution
*
* save *.Ex.txt for excitation energies and total X-section
* -----------------------------------------------------
* This program will call the root library and compile in g++
* compilation:
* g++ ExtractXSecFromText.C -o ExtractXSecFromText `root-config --cflags --glibs`
*
* ------------------------------------------------------
* created by Ryan (Tsz Leung) Tang, Dec-29, 2019
* email: goluckyryan@gmail.com
* ********************************************************************/
#include <fstream>
#include <stdlib.h>
#include "ExtractXSec.h"
using namespace std;
int main (int argc, char *argv[]) {
printf("=================================================================\n");
printf("========== Extract Cross-Section From text file ==========\n");
printf("=================================================================\n");
if(argc < 2 ) {
printf("Usage: ./ExtractXSecFromText input_file\n");
exit(0);
}else{
printf("From file : %s \n", argv[1]);
}
string readFile = argv[1];
ExtractXSecFromText(readFile);
}

56
cleopatra/FindThetaCM.C Normal file
View File

@ -0,0 +1,56 @@
/***********************************************************************
*
* This is FindThetaCM.C, To calculate the thetaCM convrage for each detector
*
* This required two inout files: basicReactionConfig.txt
* detectorGeo.txt
*
*-------------------------------------------------------
* created by Ryan (Tsz Leung) Tang, Nov-18, 2018
* email: goluckyryan@gmail.com
* ********************************************************************/
#include <fstream>
#include <stdlib.h> /* atof */
#include <cmath>
#include <vector>
#include "FindThetaCM.h"
int main(int argc, char *argv[]){
printf("=================================================================\n");
printf("=== Find ThetaCM convrage for each detector at Ex ====\n");
printf("=================================================================\n");
if(argc < 2 || argc > 7) {
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);
}
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;
}
FindThetaCM(Ex, nDiv, xRatio, reactionTxt, detGeoTxt, ID);
return 0;
}

143
cleopatra/FindThetaCM.h Normal file
View File

@ -0,0 +1,143 @@
/***********************************************************************
*
* This is FindThetaCM.h, To calculate the thetaCM convrage for each detector
*
* This required two inout files: basicReactionConfig.txt
* detectorGeo.txt
*
*-------------------------------------------------------
* created by Ryan (Tsz Leung) Tang, Nov-18, 2018
* email: goluckyryan@gmail.com
* ********************************************************************/
#include "TFile.h"
#include "TTree.h"
#include "TF1.h"
#include "TMacro.h"
#include "TObjArray.h"
#include "TGraph.h"
#include "../Cleopatra/ClassHelios.h"
#include "../Cleopatra/ClassTransfer.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){
///========================================================= load files
TransferReaction reaction(reactionConfigFileName, ID);
reaction.SetExB(Ex);
reaction.CalReactionConstant();
reaction.PrintReaction(false);
ReactionConfig reConfig = reaction.GetRectionConfig();
Recoil recoil = reaction.GetRecoil();
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;
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();
}
//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);
TGraph * tx = new TGraph(nData, px, py);
tx->SetName(Form("tx"));
tx->SetLineColor(4);
//Remove nan data
for( int i = tx->GetN() -1 ; i >= 0 ; i--){
if( TMath::IsNaN(tx->GetPointX(i)) ) tx->RemovePoint(i);
}
// tx->Draw("AC");
///========================================================= result
int iDet = array.colDet;
double length = array.detLength;
std::vector<double> midPos;
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());
}
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 ;
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");
}

68
cleopatra/InFileCreator.C Normal file
View File

@ -0,0 +1,68 @@
/***********************************************************************
*
* This is InFileCreator, To creator the in-file for Ptolemy
* only for (d,p), (d,p), (d,d), or (p,p)
*
* It read a simple infile.in from reaction_setting file
*
* -----------------------------------------------------
* This program will call the root library and compile in g++
* compilation:
* g++ InFileCreator.C -o InFileCreator `root-config --cflags --glibs`
*
*------------------------------------------------------
* The reaction_setting file is simple like:
*
* 206Hg(d,p)207Hg(1s1/2 0.000) 10MeV/u AK
*
* the first is similar to usual reaction setting, the word AK is a
* short name for Optical Potential, user can put as many line as
* they like, Cleopatra can create the suitable infile.in for Ptolomy
*
* ------------------------------------------------------
* created by Ryan (Tsz Leung) Tang, Nov-18, 2018
* email: goluckyryan@gmail.com
* ********************************************************************/
#include <fstream>
#include <stdlib.h> /* atof */
#include <cmath>
#include <vector>
#include "InFileCreator.h"
using namespace std;
int main (int argc, char *argv[]) {
printf("=================================================================\n");
printf("=== InfileCreator, Ptolemy for p,d,t,3He ====\n");
printf("=================================================================\n");
if(argc < 2 || argc > 5) {
printf("Usage: ./InfileCreator input_file (angMin = 0 deg, angMax = 180 deg, angStep = 1 deg)\n");
printf("Usage: ./InfileCreator input_file angMin angMax (angStep = 1 deg)\n");
printf("Usage: ./InfileCreator input_file angMin angMax angStep\n");
exit(0);
}else{
printf("From file : %s \n", argv[1]);
}
//================= read infile. extract the reactions, write pptolemy infile for each reaction
string readFile = argv[1];
double angMin = 0.;
double angMax = 180.;
double angStep = 1.;
if( argc >= 4 ){
angMin = atof(argv[2]);
angMax = atof(argv[3]);
}
if( argc == 5 ){
angStep = atof(argv[4]);
}
string ptolemyInFileName = argv[1];
ptolemyInFileName += ".in";
InFileCreator( readFile, ptolemyInFileName, angMin, angMax, angStep);
}

404
cleopatra/InFileCreator.h Normal file
View File

@ -0,0 +1,404 @@
/***********************************************************************
*
* This is InFileCreator, To creator the in-file for Ptolemy
* only for (x,y), x or y = n, p, d, t, 3He
*
* It read a simple infile.in from reaction_setting file
*
* -----------------------------------------------------
* This program will call the root library and compile in g++
* compilation:
* g++ InFileCreator.C -o InFileCreator `root-config --cflags --glibs`
*
*------------------------------------------------------
* The reaction_setting file is simple like:
*
* 206Hg(d,p)207Hg(1s1/2 0.000) 10MeV/u AK
*
* the first is similar to usual reaction setting, the word AK is a
* short name for Optical Potential, user can put as many line as
* they like, Cleopatra can create the suitable infile.in for Ptolomy
*
* ------------------------------------------------------
* created by Ryan (Tsz Leung) Tang, Nov-18, 2018
* email: goluckyryan@gmail.com
* ********************************************************************/
#include <stdlib.h> /* atof */
#include <vector>
#include "../Cleopatra/ClassIsotope.h" // for geting Z
#include "potentials.h"
#include "../Armory/AnalysisLib.h"
using namespace std;
int GetLValue(string spdf){
if( spdf == "s" ) return 0;
if( spdf == "p" ) return 1;
if( spdf == "d" ) return 2;
if( spdf == "f" ) return 3;
if( spdf == "g" ) return 4;
if( spdf == "h" ) return 5;
if( spdf == "i" ) return 6;
if( spdf == "j" ) return 7;
return -1;
}
int InFileCreator(string readFile, string infile, double angMin, double angMax, double angStep) {
//================= read infile. extract the reactions, write pptolemy infile for each reaction
ifstream file_in;
file_in.open(readFile.c_str(), ios::in);
if( !file_in ){
printf(" cannot read file. \n");
return 0 ;
}
printf("Save to infile : %s \n", infile.c_str());
FILE * file_out;
file_out = fopen (infile.c_str(), "w+");
printf("Angle setting (%5.2f, %5.2f) deg | Step : %5.2f deg\n", angMin, angMax, angStep);
printf("---------------------------\n");
//extract information
int numOfReaction = 0;
while( file_in.good() ) {
string tempLine;
getline(file_in, tempLine );
if( tempLine.substr(0, 1) == "#" ) continue;
if( tempLine.size() < 5 ) continue;
//split line using space
vector<string> str0 = AnalysisLib::SplitStr(tempLine, " ");
if ( str0.size() == 0 ) continue;
printf(" %s\n", tempLine.c_str());
///for( int i = 0 ; i < str0.size() ; i++){
/// printf(" str0[%d] %s \n", i, str0[i].c_str());
///}
vector<string> str1 = AnalysisLib::SplitStr(str0[0], "(", 0);
vector<string> str2 = AnalysisLib::SplitStr(str1[1], ")", 1);
str2[0] = "(" + str2[0];
int lenStr20 = str2[0].length();
size_t posTemp1 = str2[0].find(",");
string mass_a = str2[0].substr(1, posTemp1-1);
size_t posTemp2 = str2[0].find(")");
string mass_b = str2[0].substr(posTemp1+1, posTemp2-posTemp1-1);
///printf(" mass_a : |%s| , mass_b : |%s| \n", mass_a.c_str(), mass_b.c_str());
Isotope iso_a(mass_a);
Isotope iso_b(mass_b);
// Check is the Reaction supported
bool isReactionSupported = false;
bool isTransferReaction = true;
if( iso_a.A <= 4 && iso_a.Z <= 2 && iso_b.A <=4 && iso_b.Z <=2 ) isReactionSupported = true;
///======= elastics-ish scattering
if( iso_a.Mass == iso_b.Mass ) isTransferReaction = false;
///======= p/n-exchange is not supported
if( iso_a.A == iso_b.A && iso_a.Z != iso_b.Z ) isReactionSupported = false;
///======= 3-nucleons transfer is not supported. e.g. (n,a), (p,a), (a,n), (a,p)
int numNucleonsTransfer = iso_a.A - iso_b.A;
if( abs(numNucleonsTransfer) >= 3 ) isReactionSupported = false;
if( isReactionSupported == false ){
printf(" ===> Ignored. Reaction type not supported. \n");
continue;
}
// Continues to decode the input string
string gsSpinA = str0[1];
string orbital = str0[2];
string spinParity = str0[3];
int lenSpinParity = spinParity.length();
string spin = spinParity.substr(0, lenSpinParity-1);
string parity = spinParity.substr(lenSpinParity-1);
string Ex = str0[4];
string reactionEnergy = str0[5];
string potential = str0[6];
string isoA = str1[0];
string isoB = str2[1];
string reactionType = str2[0];
Isotope iso_A(str1[0]);
Isotope iso_B(str2[1]);
/// check is iso_A or iso_B exist in the mass table
if( iso_A.Mass == -404 || iso_B.Mass == -404 ){
printf(" ===> Error! mass does not found. \n");
continue;
}
/// check reaction valid by balancing the A and Z number;
if( iso_A.A + iso_a.A != iso_B.A + iso_b.A || iso_A.Z + iso_a.Z != iso_B.Z + iso_b.Z ) {
printf("====> ERROR! A-number or Z-number not balanced. \n");
Isotope isotopeK(iso_A.A + iso_a.A - iso_b.A, iso_A.Z + iso_a.Z - iso_b.Z);
printf(" try : %s(%s,%s)%s ??\n", iso_A.Name.c_str(), iso_a.Name.c_str(), iso_b.Name.c_str(), isotopeK.Name.c_str());
continue;
}
if( isTransferReaction && potential.length() != 2 ){
printf("====> ERROR! Potential input should be 2 charaters! skipped. \n");
continue;
}
string node ;
string jValue ;
string lValue ;
int spdf = -1;
if( isTransferReaction ) {
///printf("------------ %d nucleon(s) transfer \n", abs(iso_a.A - iso_b.A));
node = orbital.substr(0,1);
// single nucleon transfer
if( abs(iso_a.A - iso_b.A) == 1 ){
lValue = orbital.substr(1,1);
jValue = orbital.substr(2);
///printf(" l : %s, j : %s \n", lValue.c_str(), jValue.c_str());
spdf = GetLValue(lValue);
}
// two-nucleons transfer
if( abs(iso_a.A - iso_b.A) == 2 ){
size_t posEq = orbital.find('=');
lValue = orbital.substr(posEq+1,1);
spdf=atoi(lValue.c_str());
}
if( abs(iso_a.A - iso_b.A) == 0 ){
printf(" ===? skipped. p-n exchange reaction does not support. \n");
}
if( spdf == -1 ){
printf(" ===> skipped. Not reconginzed orbital-label. (user input : l=%s | %s) \n", lValue.c_str(), orbital.c_str());
continue;
}
}
//get Beam energy, distingusih MeV or MeV/u
int pos = reactionEnergy.length() - 1;
for( int i = pos; i >= 0 ; i--){
if( isdigit(reactionEnergy[i]) ) {
pos = i;
break;
}
}
string unit = reactionEnergy.substr(pos+1);
int factor = 1;
if( unit == "MeV/u") factor = iso_a.A;
double totalBeamEnergy = atof(reactionEnergy.substr(0, pos+1).c_str()) * factor;
///printf("unit : |%s| , %f\n", unit.c_str(), totalBeamEnergy);
///printf(" target nucleus : %s \n", isoA.c_str());
///printf(" reaction : %s \n", reactionType.c_str());
///printf(" remain : %s \n", isoB.c_str());
///printf(" reaction energy : %s \n", reactionEnergy.c_str());
///printf(" Potential : %s \n", potential.c_str());
///printf(" orbital : %s \n", orbital.c_str());
///printf(" Ex [MeV] : %s \n", Ex.c_str());
double Qvalue = iso_a.Mass + iso_A.Mass - iso_b.Mass - iso_B.Mass;
///printf("Q-Value = %f MeV\n", Qvalue);
//##########################################################
//============ write ptolmey infile
numOfReaction ++ ;
//================ elastic-ish transfer
if( isTransferReaction == false ){
if ( atof(Ex.c_str()) == 0.0 ) {
fprintf(file_out, "$============================================ ELab=%5.2f(%s+%s)%s\n",
totalBeamEnergy, mass_a.c_str(), isoA.c_str(), potential.c_str());
fprintf(file_out, "reset\n");
fprintf(file_out, "CHANNEL %s + %s\n", mass_a.c_str(), isoA.c_str());
fprintf(file_out, "r0target\n");
fprintf(file_out, "ELAB = %f\n", totalBeamEnergy);
fprintf(file_out, "JBIGA=%s\n", gsSpinA.c_str());
string pot1Name = potential.substr(0,1);
string pot1Ref = potentialRef(pot1Name);
fprintf(file_out, "$%s\n", pot1Ref.c_str());
CallPotential(pot1Name, iso_A.A, iso_A.Z, totalBeamEnergy, iso_a.Z);
fprintf(file_out, "v = %7.3f r0 = %7.3f a = %7.3f\n", v, r0, a);
fprintf(file_out, "vi = %7.3f ri0 = %7.3f ai = %7.3f\n", vi, ri0, ai);
fprintf(file_out, "vsi = %7.3f rsi0 = %7.3f asi = %7.3f\n", vsi, rsi0, asi);
fprintf(file_out, "vso = %7.3f rso0 = %7.3f aso = %7.3f\n", vso, rso0, aso);
fprintf(file_out, "vsoi = %7.3f rsoi0 = %7.3f asoi = %7.3f rc0 = %7.3f\n", vsoi, rsoi0, asoi, rc0);
fprintf(file_out, "ELASTIC SCATTERING\n");
fprintf(file_out, ";\n");
}else{
fprintf(file_out, "$============================================ Ex=%s(%s+%s|%s%s)%s,ELab=%5.2f\n",
Ex.c_str(), mass_a.c_str(), isoA.c_str(), spin.c_str(), parity.c_str(), potential.c_str(),totalBeamEnergy);
fprintf(file_out, "reset\n");
fprintf(file_out, "REACTION: %s%s%s(%s%s %s) ELAB=%7.3f\n",
isoA.c_str(), reactionType.c_str(), isoB.c_str(), spin.c_str(), parity.c_str(), Ex.c_str(), totalBeamEnergy);
fprintf(file_out, "PARAMETERSET ineloca2 r0target\n");
fprintf(file_out, "JBIGA=%s\n", gsSpinA.c_str());
if( str0.size() >= 8 ){
fprintf(file_out, "BETA=%s\n", str0[7].c_str()); //deformation length
}
string pot1Name = potential.substr(0,1);
string pot1Ref = potentialRef(pot1Name);
fprintf(file_out, "$%s\n", pot1Ref.c_str());
CallPotential(pot1Name, iso_A.A, iso_A.Z, totalBeamEnergy, iso_a.Z);
fprintf(file_out, "INCOMING\n");
fprintf(file_out, "v = %7.3f r0 = %7.3f a = %7.3f\n", v, r0, a);
fprintf(file_out, "vi = %7.3f ri0 = %7.3f ai = %7.3f\n", vi, ri0, ai);
fprintf(file_out, "vsi = %7.3f rsi0 = %7.3f asi = %7.3f rc0 = %7.3f\n", vsi, rsi0, asi, rc0);
///fprintf(file_out, "vso = %7.3f rso0 = %7.3f aso = %7.3f\n", vso, rso0, aso);
///fprintf(file_out, "vsoi = %7.3f rsoi0 = %7.3f asoi = %7.3f rc0 = %7.3f\n", vsoi, rsoi0, asoi, rc0);
fprintf(file_out, ";\n");
fprintf(file_out, "OUTGOING\n");
fprintf(file_out, "$%s\n", pot1Ref.c_str());
CallPotential(pot1Name, iso_A.A, iso_A.Z, totalBeamEnergy - atof(Ex.c_str()), iso_a.Z);
fprintf(file_out, "v = %7.3f r0 = %7.3f a = %7.3f\n", v, r0, a);
fprintf(file_out, "vi = %7.3f ri0 = %7.3f ai = %7.3f\n", vi, ri0, ai);
fprintf(file_out, "vsi = %7.3f rsi0 = %7.3f asi = %7.3f rc0 = %7.3f\n", vsi, rsi0, asi, rc0);
///fprintf(file_out, "vsi = %7.3f rsi0 = %7.3f asi = %7.3f\n", vsi, rsi0, asi);
///fprintf(file_out, "vso = %7.3f rso0 = %7.3f aso = %7.3f\n", vso, rso0, aso);
///fprintf(file_out, "vsoi = %7.3f rsoi0 = %7.3f asoi = %7.3f rc0 = %7.3f\n", vsoi, rsoi0, asoi, rc0);
fprintf(file_out, ";\n");
}
}
//================ Transfer reaction
if( isTransferReaction ){
fprintf(file_out, "$============================================ Ex=%s(%s)%s\n", Ex.c_str(), orbital.c_str(), potential.c_str());
fprintf(file_out, "reset\n");
fprintf(file_out, "REACTION: %s%s%s(%s%s %s) ELAB=%7.3f\n",
isoA.c_str(), reactionType.c_str(), isoB.c_str(), spin.c_str(), parity.c_str(), Ex.c_str(), totalBeamEnergy);
//-------- Projectile (the light particle)
if( abs(numNucleonsTransfer) == 1 ){
if( iso_a.A <= 2 && iso_a.Z <= 1 && iso_b.A <=2 && iso_b.Z <= 1){ // incoming d or p
fprintf(file_out, "PARAMETERSET dpsb r0target \n");
fprintf(file_out, "lstep=1 lmin=0 lmax=30 maxlextrap=0 asymptopia=50 \n");
fprintf(file_out, "\n");
fprintf(file_out, "PROJECTILE \n");
fprintf(file_out, "wavefunction av18 \n");
fprintf(file_out, "r0=1 a=0.5 l=0 rc0=1.2\n");
}
if( (3 <= iso_a.A && iso_a.A <= 4) || (3 <= iso_b.A && iso_b.A <= 4) ){
fprintf(file_out, "PARAMETERSET alpha3 r0target \n");
fprintf(file_out, "lstep=1 lmin=0 lmax=30 maxlextrap=0 asymptopia=50 \n");
fprintf(file_out, "\n");
fprintf(file_out, "PROJECTILE \n");
fprintf(file_out, "wavefunction phiffer \n");
if( iso_a.Z + iso_b.Z == 2){ // (t,d) or (d,t)
fprintf(file_out, "nodes=0 l=0 jp=1/2 spfacp=1.30 v=172.88 r=0.56 a=0.69 param1=0.64 param2=1.15 rc=2.0\n");
}
if( iso_a.Z + iso_b.Z == 3){ // (3He,d) or (d, 3He)
fprintf(file_out, "nodes=0 l=0 jp=1/2 spfacp=1.31 v=179.94 r=0.54 a=0.68 param1=0.64 param2=1.13 rc=2.0\n");
}
if( iso_b.A == 4 ){
fprintf(file_out, "nodes=0 l=0 jp=1/2 spfacp=1.61 v=202.21 r=.93 a=.66 param1=.81 param2=.87 rc=2.0 $ rc=2 is a quirk\n");
}
}
}else if( abs(numNucleonsTransfer) == 2 ){ // 2 nucleons transfer
fprintf(file_out, "PARAMETERSET alpha3 r0target\n");
fprintf(file_out, "lstep=1 lmin=0 lmax=30 maxlextrap=0 ASYMPTOPIA=40\n");
fprintf(file_out, "\n");
fprintf(file_out, "PROJECTILE\n");
fprintf(file_out, "wavefunction phiffer\n");
fprintf(file_out, "L = 0 NODES=0 R0 = 1.25 A = .65 RC0 = 1.25\n");
}
fprintf(file_out, ";\n");
//===== TARGET
fprintf(file_out, "TARGET\n");
///check Ex is above particle threshold
double nThreshold = iso_B.CalSp(0,1);
double pThreshold = iso_B.CalSp(1,0);
bool isAboveThreshold = false;
double ExEnergy = atof(Ex.c_str());
if( ExEnergy > nThreshold || ExEnergy > pThreshold ) {
isAboveThreshold = true;
printf(" Ex = %.3f MeV is above thresholds; Sp = %.3f MeV, Sn = %.3f MeV\n", ExEnergy, pThreshold, nThreshold);
}
if( abs(iso_a.A-iso_b.A) == 1 ){
fprintf(file_out, "JBIGA=%s\n", gsSpinA.c_str());
if( isAboveThreshold ) {
fprintf(file_out, "nodes=%s l=%d jp=%s E=-.2 $node is n-1, set binding 200 keV \n", node.c_str(), spdf, jValue.c_str());
}else{
fprintf(file_out, "nodes=%s l=%d jp=%s $node is n-1 \n", node.c_str(), spdf, jValue.c_str());
}
fprintf(file_out, "r0=1.25 a=.65 \n");
fprintf(file_out, "vso=6 rso0=1.10 aso=.65 \n");
fprintf(file_out, "rc0=1.3 \n");
}
if( abs(iso_a.A-iso_b.A) == 2 ){
fprintf(file_out, "JBIGA=%s\n", gsSpinA.c_str());
if( isAboveThreshold ){
fprintf(file_out, "nodes=%s L=%d E=-.2 $node is n-1, binding by 200 keV \n", node.c_str(), spdf);
}else{
fprintf(file_out, "nodes=%s L=%d $node is n-1 \n", node.c_str(), spdf);
}
}
fprintf(file_out, ";\n");
//===== POTENTIAL
string pot1Name = potential.substr(0,1);
string pot1Ref = potentialRef(pot1Name);
fprintf(file_out, "INCOMING $%s\n", pot1Ref.c_str());
CallPotential(pot1Name, iso_A.A, iso_A.Z, totalBeamEnergy, iso_a.Z);
fprintf(file_out, "v = %7.3f r0 = %7.3f a = %7.3f\n", v, r0, a);
fprintf(file_out, "vi = %7.3f ri0 = %7.3f ai = %7.3f\n", vi, ri0, ai);
fprintf(file_out, "vsi = %7.3f rsi0 = %7.3f asi = %7.3f\n", vsi, rsi0, asi);
fprintf(file_out, "vso = %7.3f rso0 = %7.3f aso = %7.3f\n", vso, rso0, aso);
fprintf(file_out, "vsoi = %7.3f rsoi0 = %7.3f asoi = %7.3f rc0 = %7.3f\n", vsoi, rsoi0, asoi, rc0);
fprintf(file_out, ";\n");
string pot2Name = potential.substr(1,1);
string pot2Ref = potentialRef(pot2Name);
fprintf(file_out, "OUTGOING $%s\n", pot2Ref.c_str());
//printf(" total Beam Energy : %f | Qvalue : %f | Ex : %f \n", totalBeamEnergy, Qvalue, atof(Ex.c_str()));
double eBeam = totalBeamEnergy + Qvalue - atof(Ex.c_str());
CallPotential(pot2Name, iso_B.A, iso_B.Z, eBeam, iso_b.Z);
fprintf(file_out, "v = %7.3f r0 = %7.3f a = %7.3f\n", v, r0, a);
fprintf(file_out, "vi = %7.3f ri0 = %7.3f ai = %7.3f\n", vi, ri0, ai);
fprintf(file_out, "vsi = %7.3f rsi0 = %7.3f asi = %7.3f\n", vsi, rsi0, asi);
fprintf(file_out, "vso = %7.3f rso0 = %7.3f aso = %7.3f\n", vso, rso0, aso);
fprintf(file_out, "vsoi = %7.3f rsoi0 = %7.3f asoi = %7.3f rc0 = %7.3f\n", vsoi, rsoi0, asoi, rc0);
fprintf(file_out, ";\n");
}
fprintf(file_out, "anglemin=%f anglemax=%f anglestep=%f\n", angMin, angMax, angStep);
fprintf(file_out, ";\n");
}
printf("================= end of input. Number of Reaction : %d \n", numOfReaction);
fprintf(file_out, "end $================================== end of input\n");
file_in.close();
fclose(file_out);
return 1;
}

64
cleopatra/Isotope.C Normal file
View File

@ -0,0 +1,64 @@
/***********************************************************************
*
* This is Isotope.C for isotope mass-related quatilies
*
* -----------------------------------------------------
* To compile
*
* g++ Isotope.C -o Isotope
*
* ------------------------------------------------------
* created by Ryan (Tsz Leung) Tang, Feb-20, 2021
* email: goluckyryan@gmail.com
* ********************************************************************/
#include <fstream>
#include <stdlib.h>
#include "ClassIsotope.h"
using namespace std;
void Usage(){
cout << "./Isotope Sym" << endl;
cout << "./Isotope A Z" << endl;
///cout << "./Isotope A Z A' Z'" << endl;
///cout << " Opt = rkm, e.g. 001 only calculate mass" << endl;
///cout << " |||_ mass " << endl;
///cout << " ||__ kinematics " << endl;
///cout << " |___ reaction kinematics " << endl;
exit(0);
}
int main (int argc, char *argv[]) {
printf("=================================================================\n");
printf("========== Isotope mass-related quantities ==========\n");
printf("=================================================================\n");
if ( argc != 2 && argc != 3 && argc != 6) Usage();
Isotope iso1, iso2;
int Z, A, Za, Aa;
//string Opt = argv[1];
if (argc == 2){
iso1.SetIsoByName(argv[1]);
}
if (argc == 3){
A= atoi(argv[1]);
Z= atoi(argv[2]);
iso1.SetIso(A, Z);
//}else if ( argc == 6){
// A= atoi(argv[2]);
// Z= atoi(argv[3]);
// Aa= atoi(argv[4]);
// Za= atoi(argv[5]);
// iso1.SetIso(A, Z);
// iso2.SetIso(Aa,Za);
}
iso1.Print();
iso1.ListShell();
}

View File

@ -0,0 +1,58 @@
/***********************************************************************
*
* This is PlotResultInRoot.C for ExtractXSec *.root output
*
* The Xsec are stored in (TObjArray *) gList
*
* This program is simple get plot all the member in the gList
*
* -----------------------------------------------------
* This program will call the root library and compile in g++
* compilation:
* g++ PlotResultInROOT.C -o PlotResultInROOT `root-config --cflags --glibs`
*
* ------------------------------------------------------
* created by Ryan (Tsz Leung) Tang, Nov-18, 2018
* email: goluckyryan@gmail.com
* ********************************************************************/
#include <fstream>
#include <stdlib.h>
#include <TApplication.h>
#include "PlotTGraphTObjArray.h"
using namespace std;
int main (int argc, char *argv[]) {
printf("=================================================================\n");
printf("==================== Plot Results in ROOT =======================\n");
printf("=================================================================\n");
if(argc < 2) {
printf("Usage: ./PlotTGraphTObjArray root_file [savePNG]\n");
printf(" savePNG : 1 or 0, default is 0\n");
exit(0);
}else{
printf("From file : %s \n", argv[1]);
printf("=========== Press Ctrl+C to end.\n");
}
string readFile = argv[1];
bool isSavePNG = false;
if( argc >= 3) isSavePNG = atoi(argv[2]);
if( isSavePNG ){
PlotTGraphTObjArray(readFile, true);
}else{
TApplication app ("app", &argc, argv);
PlotTGraphTObjArray(readFile);
app.Run(); //anything after this line is not running
}
return 0;
}

View File

@ -0,0 +1,101 @@
/***********************************************************************
*
* This is PlotResultInRoot.C for ExtractXSec *.root output
*
* The Xsec are stored in (TObjArray *) gList
*
* This program is simple get plot all the member in the gList
*
* -----------------------------------------------------
* This program will call the root library and compile in g++
* compilation:
* g++ PlotResultInROOT.C -o PlotResultInROOT `root-config --cflags --glibs`
*
* ------------------------------------------------------
* created by Ryan (Tsz Leung) Tang, Nov-18, 2018
* email: goluckyryan@gmail.com
* ********************************************************************/
#include <TROOT.h>
#include <TFile.h>
#include <TCanvas.h>
#include <TObjArray.h>
#include <TGraph.h>
#include <TF1.h>
#include <TAxis.h>
#include <TH1F.h>
#include <TLegend.h>
void PlotTGraphTObjArray(TString rootFileName, bool isSavePNG = false){
TFile * file = new TFile(rootFileName, "READ");
TObjArray * gList = (TObjArray *) file->FindObjectAny("thetaCM_TGraph");
if( gList == NULL ) {
printf("No Result was found.\n");
return;
}
TCanvas * cPlots = new TCanvas("cPlots", "Ptolemy Results", 0, 0, 800, 600);
cPlots->SetLogy();
TLegend * legend = new TLegend( 0.6, 0.6, 0.9, 0.9); //x1, y1, x2, y2
const int n = gList->GetLast() + 1 ;
TGraph ** gr = new TGraph *[n];
//Get minimum, maximum Y
double maxY = 0;
double minY = 10000000;
for ( int i = 0; i < n ; i++){
gr[i] = (TGraph *) gList->At(i);
gr[i]->SetLineColor(i+1);
gr[i]->GetXaxis()->SetTitle("#theta_{CM} [deg]");
gr[i]->GetYaxis()->SetTitle("d#sigma/d#Omega [mb/sr]");
TString name = gr[i]->GetName();
int pos = name.First("|");
name.Remove(0, pos+1);
legend->AddEntry(gr[i], name);
double miny = gr[i]->GetHistogram()->GetMinimum();
double maxy = gr[i]->GetHistogram()->GetMaximum();
if( miny < minY ) minY = miny;
if( maxy > maxY ) maxY = maxy;
}
for ( int i = 0; i < n ; i++){
gr[i]->Draw("same");
if( i == 0 ){
gr[i]->Draw();
gr[i]->GetYaxis()->SetRangeUser(minY * 0.8, maxY * 1.2);
}else{
gr[i]->Draw("same");
}
}
legend->Draw();
cPlots->Update();
cPlots->Draw();
if( isSavePNG ){
TDatime dateTime;
TString outPNGName = Form("Xsec_%d%02d%02d_%06d.png", dateTime.GetYear(), dateTime.GetMonth(), dateTime.GetDay(), dateTime.GetTime());
cPlots->SaveAs(outPNGName);
printf("%s\n", outPNGName.Data());
gROOT->ProcessLine(".q");
}
for( int i = 0; i < n; i++) delete gr[i];
delete [] gr;
}

132
cleopatra/PySimHelper.py Executable file
View File

@ -0,0 +1,132 @@
#!/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())

181
cleopatra/SimAlpha.C Normal file
View File

@ -0,0 +1,181 @@
#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;
}

237
cleopatra/SimChecker.C Normal file
View File

@ -0,0 +1,237 @@
#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"
#include <vector>
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::vector<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];
}
std::vector<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
std::vector<std::vector<double>> zRange(numReact, std::vector<double>(2));
std::vector<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 = new 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;
}

599
cleopatra/SimHelper.C Normal file
View File

@ -0,0 +1,599 @@
#include <TGClient.h>
#include <TCanvas.h>
#include <TF1.h>
#include <TRandom.h>
#include <TGButton.h>
#include <TGLabel.h>
#include <TGFrame.h>
#include <TGComboBox.h>
#include <TGTextEditor.h>
#include <TGNumberEntry.h>
#include <TGComboBox.h>
#include <TRootEmbeddedCanvas.h>
#include <RQ_OBJECT.h>
#include "../Cleopatra/SimTransfer.C"
#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 <iostream>
#include <stdexcept>
#include <stdio.h>
#include <string>
#ifdef __linux__
#define OS_Type 1
#elif __APPLE__
#define OS_Type 0
#endif
TString isoFileName;
class 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 ;
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::MyMainFrame(const TGWindow *p,UInt_t w,UInt_t h) {
// Create a main frame
fMain = new TGMainFrame(p,w,h);
TGHorizontalFrame *hframe = new TGHorizontalFrame(fMain,600,600 );
fMain->AddFrame(hframe, new TGLayoutHints(kLHintsCenterX | kLHintsExpandX | kLHintsExpandY, 2,2,2,2));
TGVerticalFrame *hframe1 = new TGVerticalFrame(fMain,600,600 );
hframe->AddFrame(hframe1);
TGVerticalFrame *hframe2 = new TGVerticalFrame(fMain,600,1000 );
hframe->AddFrame(hframe2,new TGLayoutHints( kLHintsExpandX | kLHintsExpandY, 2,2,2,2));
fileName = "../working/detectorGeo.txt";
TGHorizontalFrame *hframe00 = new TGHorizontalFrame(hframe2,600,600 );
hframe2->AddFrame(hframe00, new TGLayoutHints(kLHintsCenterX | kLHintsExpandX , 2,2,2,2));
fileLabel = new TGLabel(hframe00, "");
fileLabel->SetWidth(370);
fileLabel->SetHeight(20);
fileLabel->SetTextColor(kRed);
fileLabel->ChangeOptions(kFixedSize | kSunkenFrame);
fileLabel->SetText(fileName);
hframe00->AddFrame(fileLabel, new TGLayoutHints(kLHintsLeft, 2,2,2,2));
TGTextButton *save = new TGTextButton(hframe00,"Save");
save->SetWidth(100);
save->SetHeight(20);
save->ChangeOptions( save->GetOptions() | kFixedSize );
save->Connect("Clicked()","MyMainFrame",this,"Command(=3)");
hframe00->AddFrame(save, new TGLayoutHints(kLHintsLeft,5,5,3,4));
TGTextButton *help = new TGTextButton(hframe00, "Help");
help->SetWidth(100);
help->SetHeight(20);
help->ChangeOptions( help->GetOptions() | kFixedSize );
help->Connect("Clicked()","MyMainFrame",this,"Command(=4)");
hframe00->AddFrame(help,new TGLayoutHints(kLHintsLeft, 5,5,3,4));
editor = new TGTextEdit(hframe2, 600, 700);
editor->LoadFile(fileName);
hframe2->AddFrame(editor, new TGLayoutHints(kLHintsCenterX | kLHintsExpandX | kLHintsExpandY, 2,2,2,2));
statusLabel = new TGLabel(hframe2, "");
statusLabel->SetWidth(600);
statusLabel->SetHeight(20);
statusLabel->SetTextJustify(kTextLeft);
statusLabel->SetTextColor(1);
statusLabel->ChangeOptions(kFixedSize | kSunkenFrame);
hframe2->AddFrame(statusLabel, new TGLayoutHints(kLHintsLeft | kLHintsExpandX, 2,2,2,2));
{//================= Simulation group
TGGroupFrame * simFrame = new TGGroupFrame(hframe1, "Kinematics Simulation", kVerticalFrame);
hframe1->AddFrame(simFrame, new TGLayoutHints(kLHintsCenterX, 5,5,3,4));
TGTextButton *openDet = new TGTextButton(simFrame, "detector Geo.");
openDet->SetWidth(150);
openDet->SetHeight(20);
openDet->ChangeOptions( openDet->GetOptions() | kFixedSize );
openDet->Connect("Clicked()","MyMainFrame",this, "OpenFile(=0)");
simFrame->AddFrame(openDet,new TGLayoutHints(kLHintsRight, 5,5,3,4));
TGTextButton *openRec = new TGTextButton(simFrame, "reaction Config");
openRec->SetWidth(150);
openRec->SetHeight(20);
openRec->ChangeOptions( openRec->GetOptions() | kFixedSize );
openRec->Connect("Clicked()","MyMainFrame",this, "OpenFile(=1)");
simFrame->AddFrame(openRec,new TGLayoutHints(kLHintsRight, 5,5,3,4));
withDWBA = new TGCheckButton(simFrame, "Sim with DWBA");
withDWBA->SetWidth(140);
withDWBA->ChangeOptions(kFixedSize );
simFrame->AddFrame(withDWBA, new TGLayoutHints(kLHintsRight, 5,5,3,4));
TGTextButton *Sim = new TGTextButton(simFrame,"Simulate");
Sim->SetWidth(150);
Sim->SetHeight(40);
Sim->ChangeOptions( Sim->GetOptions() | kFixedSize );
Sim->Connect("Clicked()","MyMainFrame",this,"Command(=1)");
simFrame->AddFrame(Sim, new TGLayoutHints(kLHintsRight,5,5,3,4));
TGTextButton *openSimChk = new TGTextButton(simFrame, "Config Simulation Plot");
openSimChk->SetWidth(150);
openSimChk->SetHeight(20);
openSimChk->ChangeOptions( openSimChk->GetOptions() | kFixedSize );
openSimChk->Connect("Clicked()","MyMainFrame",this, "OpenFile(=4)");
simFrame->AddFrame(openSimChk,new TGLayoutHints(kLHintsRight, 5,5,3,4));
TGTextButton *SimChk = new TGTextButton(simFrame,"Re-Plot Simulation");
SimChk->SetWidth(150);
//SimChk->SetHeight(40);
SimChk->ChangeOptions( SimChk->GetOptions() | kFixedSize );
SimChk->Connect("Clicked()","MyMainFrame",this,"Command(=2)");
simFrame->AddFrame(SimChk, new TGLayoutHints(kLHintsRight,5,5,3,4));
TGTextButton *autoFit = new TGTextButton(simFrame,"AutoFit ExCal");
autoFit->SetWidth(150);
//autoFit->SetHeight(40);
autoFit->ChangeOptions( autoFit->GetOptions() | kFixedSize );
autoFit->Connect("Clicked()","MyMainFrame",this,"Command(=5)");
simFrame->AddFrame(autoFit, new TGLayoutHints(kLHintsRight,5,5,3,4));
}
{//================= DWBA group
TGGroupFrame * DWBAFrame = new TGGroupFrame(hframe1, "DWBA calculation", kVerticalFrame);
hframe1->AddFrame(DWBAFrame, new TGLayoutHints(kLHintsCenterX, 5,5,3,4));
TGTextButton *openDWBA = new TGTextButton(DWBAFrame, "DWBA setting");
openDWBA->SetWidth(150);
openDWBA->SetHeight(20);
openDWBA->ChangeOptions( openDWBA->GetOptions() | kFixedSize );
openDWBA->Connect("Clicked()","MyMainFrame",this, "OpenFile(=3)");
DWBAFrame->AddFrame(openDWBA,new TGLayoutHints(kLHintsRight, 5,5,3,4));
TGTextButton *openInFile = new TGTextButton(DWBAFrame, "InFile");
openInFile->SetWidth(150);
openInFile->SetHeight(20);
openInFile->ChangeOptions( openDWBA->GetOptions() | kFixedSize );
openInFile->Connect("Clicked()","MyMainFrame",this, "OpenFile(=5)");
DWBAFrame->AddFrame(openInFile,new TGLayoutHints(kLHintsRight, 5,5,3,4));
TGTextButton *openOutFile = new TGTextButton(DWBAFrame, "OutFile");
openOutFile->SetWidth(150);
openOutFile->SetHeight(20);
openOutFile->ChangeOptions( openDWBA->GetOptions() | kFixedSize );
openOutFile->Connect("Clicked()","MyMainFrame",this, "OpenFile(=6)");
DWBAFrame->AddFrame(openOutFile,new TGLayoutHints(kLHintsRight, 5,5,3,4));
TGTextButton *xsecFile = new TGTextButton(DWBAFrame, "X-Sec");
xsecFile->SetWidth(150);
xsecFile->SetHeight(20);
xsecFile->ChangeOptions( openDWBA->GetOptions() | kFixedSize );
xsecFile->Connect("Clicked()","MyMainFrame",this, "OpenFile(=7)");
DWBAFrame->AddFrame(xsecFile,new TGLayoutHints(kLHintsRight, 5,5,3,4));
//-------- angle setting
TGHorizontalFrame * hframe000 = new TGHorizontalFrame(DWBAFrame, 150, 30, kFixedSize);
DWBAFrame->AddFrame(hframe000);
TGLabel * lb1 = new TGLabel(hframe000, "angMin");
lb1->SetWidth(50); lb1->ChangeOptions( kFixedSize);
hframe000->AddFrame(lb1, new TGLayoutHints(kLHintsCenterX | kLHintsCenterY, 5, 5, 0, 0));
TGLabel * lb2 = new TGLabel(hframe000, "angMax");
lb2->SetWidth(50); lb2->ChangeOptions( kFixedSize);
hframe000->AddFrame(lb2, new TGLayoutHints(kLHintsCenterX | kLHintsCenterY, 5, 5, 0, 0));
TGLabel * lb3 = new TGLabel(hframe000, "angStep");
lb3->SetWidth(50); lb3->ChangeOptions( kFixedSize);
hframe000->AddFrame(lb3, new TGLayoutHints(kLHintsCenterX | kLHintsCenterY, 5, 5, 0, 0));
TGHorizontalFrame * hframe001 = new TGHorizontalFrame(DWBAFrame, 150, 30, kFixedSize);
DWBAFrame->AddFrame(hframe001);
angMin = new TGNumberEntry(hframe001, 0, 0, 0, TGNumberFormat::kNESInteger, TGNumberFormat::kNEANonNegative);
angMin->SetWidth(50);
angMin->SetLimits(TGNumberFormat::kNELLimitMinMax, 0, 180);
hframe001->AddFrame(angMin, new TGLayoutHints(kLHintsCenterX , 5, 5, 0, 0));
angMax = new TGNumberEntry(hframe001, 60, 0, 0, TGNumberFormat::kNESInteger, TGNumberFormat::kNEANonNegative);
angMax->SetWidth(50);
angMax->SetLimits(TGNumberFormat::kNELLimitMinMax, 0, 180);
hframe001->AddFrame(angMax, new TGLayoutHints(kLHintsCenterX , 5, 5, 0, 0));
angStep = new TGNumberEntry(hframe001, 1, 0, 0, TGNumberFormat::kNESRealOne, TGNumberFormat::kNEAPositive);
angStep->SetWidth(50);
angStep->SetLimits(TGNumberFormat::kNELLimitMinMax, 0, 30);
hframe001->AddFrame(angStep, new TGLayoutHints(kLHintsCenterX, 5, 5, 0, 0));
//------- Check Boxes
isInFile = new TGCheckButton(DWBAFrame, "Create inFile");
isInFile->SetWidth(100);
isInFile->ChangeOptions(kFixedSize );
isInFile->SetState(kButtonDown);
DWBAFrame->AddFrame(isInFile, new TGLayoutHints(kLHintsLeft, 5,5,3,4));
isRun = new TGCheckButton(DWBAFrame, "Run Ptolemy");
isRun->SetWidth(100);
isRun->ChangeOptions(kFixedSize );
isRun->SetState(kButtonDown);
DWBAFrame->AddFrame(isRun, new TGLayoutHints(kLHintsLeft, 5,5,3,4));
isExtract = new TGCheckButton(DWBAFrame, "Extract Xsec");
isExtract->SetWidth(100);
isExtract->ChangeOptions(kFixedSize );
isExtract->SetState(kButtonDown);
DWBAFrame->AddFrame(isExtract, new TGLayoutHints(kLHintsLeft, 5,5,3,4));
isPlot = new TGCheckButton(DWBAFrame, "Plot");
isPlot->SetWidth(100);
isPlot->ChangeOptions(kFixedSize );
isPlot->SetState(kButtonDown);
DWBAFrame->AddFrame(isPlot, new TGLayoutHints(kLHintsLeft, 5,5,3,4));
extractFlag = new TGComboBox(DWBAFrame, 100);
extractFlag->SetWidth(130);
extractFlag->SetHeight(30);
extractFlag->AddEntry("Xsec.", 2);
extractFlag->AddEntry("Ratio to Ruth.", 1);
extractFlag->AddEntry("Rutherford", 3);
extractFlag->Select(2);
DWBAFrame->AddFrame(extractFlag, new TGLayoutHints(kLHintsLeft, 5,5,3,4));
TGTextButton *DWBA = new TGTextButton(DWBAFrame, "DWBA");
DWBA->SetWidth(150);
DWBA->SetHeight(40);
DWBA->ChangeOptions( DWBA->GetOptions() | kFixedSize );
DWBA->Connect("Clicked()","MyMainFrame",this,"Command(=0)");
DWBAFrame->AddFrame(DWBA,new TGLayoutHints(kLHintsRight, 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));
// 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);
// 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);
// 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);
exit->SetHeight(40);
exit->ChangeOptions( exit->GetOptions() | kFixedSize );
hframe1->AddFrame(exit, new TGLayoutHints(kLHintsCenterX | kLHintsExpandX, 5,5,3,4));
// Set a name to the main frame
fMain->SetWindowName("Simulation Helper");
// Map all subwindows of main frame
fMain->MapSubwindows();
// Initialize the layout algorithm
fMain->Resize(fMain->GetDefaultSize());
// Map main frame
fMain->MapWindow();
int versionInt = gROOT->GetVersionInt();
if( versionInt < 62600 ) {
statusLabel->SetText(Form("Root version : %s. Please Update Root to v6.26/00",gROOT->GetVersion()));
}else{
statusLabel->SetText(Form("Root version : %s",gROOT->GetVersion()));
}
}
bool MyMainFrame::IsFileExist(TString filename){
ifstream file (filename.Data());
return file.is_open();
}
void MyMainFrame::OpenFile(int ID){
editor->SaveFile(fileName);
TString oldFileName = fileName;
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";
if ( ID == 8 ) fileName = isoFileName;
//test if file exist
if ( IsFileExist(fileName) ){
fileLabel->SetText(fileName);
editor->LoadFile(fileName);
if( ID >= 6 ) {
editor->SetReadOnly(true);
}else{
editor->SetReadOnly(false);
}
editor->ShowBottom();
if( ID < 6){
statusLabel->SetText(fileName + " opened.");
}else{
statusLabel->SetText(fileName + " opened. (READ ONLY)");
}
}else{
statusLabel->SetText(fileName + " not exist.");
fileName = oldFileName;
}
}
void MyMainFrame::GetData(){
TString name = txtName->GetText();
TString maxEx = txtEx->GetText();
TString cmd = "../Cleopatra/nuclear_data.py " + name + " " + maxEx;
system(cmd.Data());
statusLabel->SetText("Check termial.");
//isoFileName = name + ".txt";
//OpenFile(8);
}
void MyMainFrame::Command(int ID) {
editor->SaveFile(fileName);
if( ID == 0 ){
if( isInFile->GetState()) {
double aMin = angMin->GetNumber();
double aMax = angMax->GetNumber();
double aStep = angStep->GetNumber();
statusLabel->SetText("Creating DWBA.in.....");
InFileCreator("DWBA", "DWBA.in", aMin, aMax, aStep);
statusLabel->SetText("in-file created.");
}
bool isRunOK = true;
if( isRun->GetState() && IsFileExist("DWBA.in") ) {
//printf("run ptolemy...........\n");
statusLabel->SetText("Running Ptolemy.....");
int output = 1;
if( OS_Type == 1 ){
output = system("../Cleopatra/ptolemy <DWBA.in> DWBA.out");
}else{
output = system("../Cleopatra/ptolemy_mac <DWBA.in> DWBA.out");
}
statusLabel->SetText("Check terminal, if no massage, Ptolemy run well.");
printf("Ptolemy exist code : %d\n", output);
if( output == 0 ) {
isRunOK = true;
}else{
isRunOK = false;
statusLabel->SetText("Ptolemy exist with problems.");
}
}
if( isRunOK && isExtract->GetState() && IsFileExist("DWBA.out")){
int ElasticFlag = 0; // 1 for ratio to Rutherford, 2 for total Xsec, 3 for (n,n) Xsec
ElasticFlag = extractFlag->GetSelected();
statusLabel->SetText("Extracting X-sec.....");
ExtractXSec("DWBA.out", ElasticFlag);
statusLabel->SetText("X-sec Extracted.");
}
if( isRunOK && isPlot->GetState() && IsFileExist("DWBA.root")){
statusLabel->SetText("Plot X-sec.....");
PlotTGraphTObjArray("DWBA.root");
statusLabel->SetText("Plotted X-sec.");
}
}
if( ID == 1 ){
string basicConfig = "reactionConfig.txt";
string heliosDetGeoFile = "detectorGeo.txt";
TString ptolemyRoot = ""; // when no file, use isotropic distribution of thetaCM
TString saveFileName = "transfer.root";
if( withDWBA->GetState() ) {
ptolemyRoot = "DWBA.root";
}
basicConfig = "reactionConfig.txt";
heliosDetGeoFile = "detectorGeo.txt";
ptolemyRoot = ""; // when no file, use isotropic distribution of thetaCM
saveFileName = "transfer.root";
if( withDWBA->GetState() ) {
ptolemyRoot = "DWBA.root";
}
statusLabel->SetText("Running simulation.......");
Transfer( basicConfig, heliosDetGeoFile, ptolemyRoot, saveFileName);
statusLabel->SetText("Plotting simulation.......");
SimChecker("transfer.root");
statusLabel->SetText("Plotted Simulation result");
}
if( ID == 2 ){
SimChecker("transfer.root");
statusLabel->SetText(" Run Simulation first.");
}
if( ID == 3 ){
if( fileName != "" ){
statusLabel->SetText(fileName + " saved.");
}else{
statusLabel->SetText("cannot save HELP page.");
}
}
if( ID == 4 ){
fileName = "";
statusLabel->SetText("Help Page.");
editor->LoadBuffer("==================== For Simulation");
editor->AddLine("");
editor->AddLine("1) Make sure you check :");
editor->AddLine(" a) reaction Config");
editor->AddLine(" b) detector Geo.");
editor->AddLine(" c) Ex List");
editor->AddLine("");
editor->AddLine("2) Not need to save file, fiel save when any button (except the Exit) is pressed.");
editor->AddLine("");
editor->AddLine("3) There is a checkbox for simulation with DWBA");
editor->AddLine(" This requires the existance of DWBA.root and DWBA.Ex.txt");
editor->AddLine(" These files can be generated by DWBA calculation.");
editor->AddLine(" Please change the angMin = 0 and angMax = 180.");
editor->AddLine("");
editor->AddLine("4) After simulation, it will plot the result.");
editor->AddLine(" To change the plotting, Click on the Config Simulation Plot.");
editor->AddLine("");
editor->AddLine("5) If the transfer.root is already here, simply Plot Simulation.");
editor->AddLine("");
editor->AddLine("========================= For DWBA ");
editor->AddLine("");
editor->AddLine("1) Only need to change the DWBA setting.");
editor->AddLine("");
editor->AddLine("2) The GUI offer a view on the infile and outfile.");
editor->AddLine("");
editor->AddLine("3) For elastics scattering, there is a checkbox for plotting the ratio to RutherFord.");
editor->AddLine("");
editor->AddLine("4) The flow of the DWBA calculation is like this:");
editor->AddLine(" a) read the DWBA file and convert to DWBA.in");
editor->AddLine(" b) run Ptolemy from DWBA.in, and the output is DWBA.out");
editor->AddLine(" c) extract the cross section from the DWBA.out, and save :");
editor->AddLine(" * DWBA.Xsec.txt");
editor->AddLine(" * DWBA.Ex.txt");
editor->AddLine(" * DWBA.root");
editor->AddLine(" d) Plot the cross section from the DWBA.root.");
editor->AddLine("");
editor->AddLine("================ Tips for using the editor, both MAC or LINUX");
editor->AddLine("");
editor->AddLine("Ctrl+U | Delete current line. ");
editor->AddLine("Ctrl+C | Copy ");
editor->AddLine("Ctrl+V | Paste ");
editor->AddLine("=================================================== eof");
TString osTypeStr;
osTypeStr.Form("OS type is %s", (OS_Type == 0 ? "Mac" : "Linux"));
editor->AddLine(osTypeStr);
editor->AddLine(Form("Root version : %s",gROOT->GetVersion()));
int versionInt = gROOT->GetVersionInt();
if( versionInt < 62600 ) {
editor->AddLine("Please Update Root to v6.26/00");
}
}
if( ID == 5) {
//TODO fit all hExCal
TH1F * temp = (TH1F*) gROOT->FindObjectAny("hExCal0");
if( temp != NULL ){
AutoFit::fitAuto(temp, -1);
statusLabel->SetText("Auto Fit hExCal");
}else{
statusLabel->SetText("Cannot find historgram hExCal0. Please Run Plot Simulation first.");
}
//gROOT->ProcessLine("fitAuto(hExCal, -1)");
}
}
MyMainFrame::~MyMainFrame() {
// Clean up used widgets: frames, buttons, layout hints
fMain->Cleanup();
delete fMain;
}
void SimHelper() {
new MyMainFrame(gClient->GetRoot(),800,1000);
}

507
cleopatra/SimKnockout.C Normal file
View File

@ -0,0 +1,507 @@
#include "ClassHelio.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 "TClonesArray.h"
#include <vector>
#include <fstream>
//----------- usage
// $root sim.C+ | tee output.txt
// this will same the massage to output.txt
void knockout(){
//================================================= User Setting
//---- reaction
int AA = 23, ZA = 9;
int Aa = 1, Za = 1;
int A2 = 1, Z2 = 1;
bool isNormalKinematics = false;
bool isOverRideExNegative = true;
double maxkb = 200.;
//---- beam
double KEAmean = 100; // MeV/u
const int nKEA = 1;
double KEAList[nKEA] = {300};
double KEAsigma = 0; //KEAmean*0.001; // MeV/u , assume Guassian
double thetaMean = 0.; // mrad
double thetaSigma = 0.; // mrad , assume Guassian due to small angle
int numEvent = 100000;
//---- HELIOS detector geometry
string heliosDetGeoFile = "";//"detectorGeo_upstream.txt";
double BField = 4.0; // if not detector, must set B-field, else, this value is not used.
double BFieldTheta = 0.; // direction of B-field
double eSigma = 0.0001 ; // detector energy sigma MeV
double zSigma = 0.1 ; // detector position sigma mm
//---- excitation of Beam
int nExA = 1;
double ExAList[nExA];
ExAList[0] = 0.000; // MeV
//ExAList[1] = 1.567;
//---- Separation energy
string separationFile = "separation_energies.txt";
//---- save root file name
TString saveFileName = "knockout.root";
//---- Auxiliary setting
bool isTargetScattering = false;
bool isDecay = false;
bool isReDo = false; // redo calculation until detected.
//---- target
double density = 0.913; // 0.913 g/cm3
double targetThickness = 2./2. * 2.2e-4; // 2.2 um = 201 ug/cm2
string stoppingPowerForA = "208Pb_in_CD2.txt"; // generated by SRIM
string stoppingPowerForb = "1H_in_CD2.txt";
string stoppingPowerForB = "209Pb_in_CD2.txt";
//=============================================================
//=============================================================
//=============================================================
//===== Set Reaction
Knockout reaction;
int AB = AA-A2, ZB = ZA-Z2;
int A1 = Aa , Z1 = Za;
reaction.SetA(AA,ZA);
reaction.Seta(Aa,Za);
reaction.Set2(A2,Z2);
reaction.SetIncidentEnergyAngle(KEAmean, 0, 0);
reaction.OverRideExNegative(isOverRideExNegative);
printf("===================================================\n");
printf("=========== %s ===========\n", reaction.GetReactionName().Data());
printf("=========== KE: %9.4f +- %5.4f MeV/u, dp/p = %5.2f %% \n", KEAmean, KEAsigma, KEAsigma/KEAmean * 50.);
printf("======== theta: %9.4f +- %5.4f MeV/u \n", thetaMean, thetaSigma);
printf("===================================================\n");
//======== Set HELIOS
printf("############################################## HELIOS configuration\n");
HELIOS helios1; // for particle-1
HELIOS helios2; // for particle-2
helios1.SetMagneticFieldDirection(BFieldTheta);
helios2.SetMagneticFieldDirection(BFieldTheta);
bool sethelios1 = helios1.SetDetectorGeometry(heliosDetGeoFile);
bool sethelios2 = helios2.SetDetectorGeometry(heliosDetGeoFile);
if( sethelios1 && sethelios2 ) {
int rowDet = helios1.GetNumberOfDetectorsInSamePos();
printf("========== energy resol.: %f MeV\n", eSigma);
printf("=========== pos-Z resol.: %f mm \n", zSigma);
}else{
helios1.SetMagneticField(BField);
helios2.SetMagneticField(BField);
printf("======== B-field : %5.2f T, Theta: %5.2f deg\n", BField, BFieldTheta);
}
//==== Target scattering, only energy loss
if(isTargetScattering) printf("############################################## Target Scattering\n");
TargetScattering msA;
TargetScattering msB;
TargetScattering msb;
if(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( isTargetScattering ){
msA.LoadStoppingPower(stoppingPowerForA);
msb.LoadStoppingPower(stoppingPowerForb);
msB.LoadStoppingPower(stoppingPowerForB);
}
//======= Decay of particle-B
Decay decay;
decay.SetMotherDaugther(AB, ZB, AB-1,ZB); //neutron decay
//======= loading excitation energy
printf("############################################## excitation energies\n");
vector<double> SpList;
printf("----- loading separation energies.");
ifstream file;
file.open(separationFile.c_str());
string isotopeName;
if( file.is_open() ){
string line;
int i = 0;
while( file >> line){
//printf("%d, %s \n", i, line.c_str());
if( line.substr(0,2) == "//" ) continue;
if( i == 0 ) isotopeName = line;
if ( i >= 1 ){
SpList.push_back(atof(line.c_str()));
}
i = i + 1;
}
file.close();
printf("... done.\n");
printf("========== %s\n", isotopeName.c_str());
int n = SpList.size();
for(int i = 0; i < n ; i++){
if( isDecay ) {
TLorentzVector temp(0,0,0,0);
int decayID = decay.CalDecay(temp, SpList[i], 0);
if( decayID == 1) {
printf("%d, Sp: %6.2f MeV --> Decay. \n", i, SpList[i]);
}else{
printf("%d, Sp: %6.2f MeV\n", i, SpList[i]);
}
}else{
printf("%d, Sp: %6.2f MeV \n", i, SpList[i]);
}
}
}else{
printf("... fail\n");
return;
}
//====================== build tree
TFile * saveFile = new TFile(saveFileName, "recreate");
TTree * tree = new TTree("tree", "tree");
double thetaNN, phiNN;
double theta1, phi1, T1;
double theta2, phi2, T2;
double thetaB, TB;
double Sp, kb, thetab, phib;
int SpID;
double ExA;
int ExAID;
double KEA, KEAscattered, theta, phi;
double mB,mb;
tree->Branch("theta1", &theta1, "theta1/D");
tree->Branch("phi1", &phi1, "phi1/D");
tree->Branch("T1", &T1, "T1/D");
tree->Branch("theta2", &theta2, "theta2/D");
tree->Branch("phi2", &phi2, "phi2/D");
tree->Branch("T2", &T2, "T2/D");
tree->Branch("thetaB", &thetaB, "thetaB/D");
tree->Branch("TB", &TB, "TB/D");
tree->Branch("thetaNN", &thetaNN, "thetaNN/D");
tree->Branch("phiNN", &phiNN, "phiNN/D");
tree->Branch("Sp", &Sp, "Sp/D");
tree->Branch("kb", &kb, "kb/D");
tree->Branch("thetab", &thetab, "thetab/D");
tree->Branch("phib", &phib, "phib/D");
tree->Branch("SpID", &SpID, "SpID/I");
tree->Branch("ExAID", &ExAID, "ExAID/I");
tree->Branch("KEA", &KEA, "KEA/D");
if(isTargetScattering) tree->Branch("KEAscattered", &KEAscattered, "KEAscattered/D");
tree->Branch("theta", &theta, "theta/D");
tree->Branch("phi", &phi, "phi/D");
tree->Branch("mB", &mB, "mB/D");
tree->Branch("mb", &mb, "mb/D");
tree->Branch("Bfield", &BField, "Bfield/D");
TClonesArray * arr = new TClonesArray("TLorentzVector");
tree->Branch("fV", arr, 256000);
arr->BypassStreamer();
TClonesArray * arrN = new TClonesArray("TLorentzVector");
tree->Branch("fVN", arrN, 256000);
arrN->BypassStreamer();
TLorentzVector* fourVector = NULL;
// the output of Helios.CalHit
double e1, z1, t1, rho1, x1h, y1h, r1h;
double e2, z2, t2, rho2, x2h, y2h, r2h;
tree->Branch("e1", &e1, "e1/D");
tree->Branch("z1", &z1, "z1/D");
tree->Branch("t1", &t1, "t1/D");
tree->Branch("x1h", &x1h, "x1h/D"); //at 200 mm downstream
tree->Branch("y1h", &y1h, "y1h/D");
tree->Branch("r1h", &r1h, "r1h/D");
tree->Branch("rho1", &rho1, "rho1/D");
tree->Branch("e2", &e2, "e2/D");
tree->Branch("z2", &z2, "z2/D");
tree->Branch("t2", &t2, "t2/D");
tree->Branch("x2h", &x2h, "x2h/D"); //at 200 mm downstream
tree->Branch("y2h", &y2h, "y2h/D");
tree->Branch("r2h", &r2h, "r2h/D");
tree->Branch("rho2", &rho2, "rho2/D");
double Sp2;
tree->Branch("Sp2", &Sp2, "Sp2/D");
//different coordinate
double a0, a1, a2; // in k1-k2 coordinate
tree->Branch("a0", &a0, "a0/D");
tree->Branch("a1", &a1, "a1/D");
tree->Branch("a2", &a2, "a2/D");
double b; // in THREEDEE coordinate
tree->Branch("b", &b, "b/D");
//========timer
TBenchmark clock;
bool shown ;
clock.Reset();
clock.Start("timer");
shown = false;
printf("############################################## generating %d events \n", numEvent);
//====================================================== calculate
int count = 0;
for( int i = 0; i < numEvent; i++){
bool redoFlag = true;
if( !isReDo ) redoFlag = false;
do{
//==== Set Ex of A
ExAID = gRandom->Integer(nExA);
ExA = ExAList[ExAID];
reaction.SetExA(ExA);
//==== Set Sp of B
SpID = gRandom->Integer(SpList.size());
Sp = SpList[SpID];
//==== Set incident beam
if( KEAsigma == 0 ){
KEA = KEAmean;
}else{
KEA = gRandom->Gaus(KEAmean, KEAsigma);
}
if( thetaSigma == 0 ){
theta = thetaMean;
}else{
theta = gRandom->Gaus(thetaMean, thetaSigma);
}
int rKEA = gRandom->Integer(nKEA);
KEA = KEAList[rKEA];
/*
KEA = 300*gRandom->Rndm();
BField = 4*gRandom->Rndm();
helios1.SetMagneticField(BField);
helios2.SetMagneticField(BField);
*/
reaction.SetIncidentEnergyAngle(KEA, theta, 0.);
/*
//For target scattering
reaction.CalIncidentChannel(isNormalKinematics); // but only need is PA
TLorentzVector PA = reaction.GetPA();
double depth = 0;
if( isTargetScattering ){
//==== Target scattering, only energy loss
depth = targetThickness * gRandom->Rndm();
msA.SetTarget(density, depth);
TLorentzVector PAnew = msA.Scattering(PA);
KEAscattered = msA.GetKE()/AA;
reaction.SetIncidentEnergyAngle(KEAscattered, theta, phi);
}*/
//==== Calculate reaction
thetaNN = TMath::ACos(2 * gRandom->Rndm() - 1) ;
phiNN = TMath::TwoPi() * gRandom->Rndm();
kb = maxkb * gRandom->Rndm();
thetab = TMath::ACos(2 * gRandom->Rndm() - 1);
phib = TMath::TwoPi() * gRandom->Rndm();
reaction.SetBSpk(Sp, kb, thetab, phib);
reaction.CalReactionConstant(isNormalKinematics);
reaction.Event(thetaNN, phiNN);
TLorentzVector PA = reaction.GetPA();
TLorentzVector Pa = reaction.GetPa();
TLorentzVector P1 = reaction.GetP1();
TLorentzVector P2 = reaction.GetP2();
TLorentzVector Pb = reaction.GetPb();
TLorentzVector PB = reaction.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
if( isDecay){
int decayID = decay.CalDecay(PB, Sp, 0); // decay to ground state
if( decayID == 1 ){
PB = decay.GetDaugther_D();
decayTheta = decay.GetAngleChange();
}else{
decayTheta = TMath::QuietNaN();
}
}
*/
//################################### tree branches
//===== reaction
theta1 = P1.Theta() * TMath::RadToDeg();
theta2 = P2.Theta() * TMath::RadToDeg();
thetaB = PB.Theta() * TMath::RadToDeg();
T1 = P1.E() - P1.M();
T2 = P2.E() - P2.M();
TB = PB.E() - PB.M();
phi1 = P1.Phi() * TMath::RadToDeg();
phi2 = P2.Phi() * TMath::RadToDeg();
//--------- diff coordinate
b = TMath::ASin( TMath::Sin(P2.Theta()) * TMath::Sin(P1.Phi() - P2.Phi() )) * TMath::RadToDeg();
TVector3 kA = (PA.Vect()).Unit();
TVector3 k1 = (P1.Vect()).Unit();
TVector3 k2 = (P2.Vect()).Unit();
TVector3 n = (k1.Cross(k2)).Unit();
TVector3 j = (kA - (kA.Dot(n))*n).Unit();
a0 = TMath::ASin(n.Dot(kA)) * TMath::RadToDeg();
a1 = TMath::ACos(k1.Dot(j)) * TMath::RadToDeg();
a2 = TMath::ACos(k2.Dot(j)) * TMath::RadToDeg();
//----------- mass
mB = PB.M();
mb = Pb.M();
TVector3 bA = PA.BoostVector();
for(int i = 0; i < 6 ; i++){
TLorentzVector temp;
double xyzt[4];
switch(i){
case 0: temp = PA; break;
case 1: temp = Pa; break;
case 2: temp = P1; break;
case 3: temp = P2; break;
case 4: temp = PB; break;
case 5: temp = Pb; break;
}
temp.GetXYZT(xyzt);
fourVector = (TLorentzVector*) arr->ConstructedAt(i);
fourVector->SetXYZT(xyzt[0], xyzt[1], xyzt[2], xyzt[3]);
//into normal kinematic
temp.Boost(-bA);
temp.GetXYZT(xyzt);
fourVector = (TLorentzVector*) arrN->ConstructedAt(i);
fourVector->SetXYZT(xyzt[0], xyzt[1], xyzt[2], xyzt[3]);
}
//==== Helios
int hit1 = helios1.CalHit(P1, Z1, PB, ZB);
int hit2 = helios2.CalHit(P2, Z2, PB, ZB);
double recoilZ = 1000;
e1 = helios1.GetEnergy() + gRandom->Gaus(0, eSigma);
z1 = helios1.GetZ() ;
t1 = helios1.GetTime();
rho1 = helios1.GetRho();
x1h = helios1.GetXPos(recoilZ);
y1h = helios1.GetYPos(recoilZ);
r1h = helios1.GetR(recoilZ);
e2 = helios2.GetEnergy() + gRandom->Gaus(0, eSigma);
z2 = helios2.GetZ() ;
t2 = helios2.GetTime();
rho2 = helios2.GetRho();
x2h = helios2.GetXPos(recoilZ);
y2h = helios2.GetYPos(recoilZ);
r2h = helios2.GetR(recoilZ);
double gammaA = PA.Gamma();
double betaA = PA.Beta();
Sp2 = (1-gammaA)* 938.272 - gammaA*(e1+e2) + betaA*gammaA*(P1.Pz() + P2.Pz()) ;
//printf("%f, %f | %f, %f \n", e1, z1, e2, z2);
//change thetaNN into deg
thetaNN = thetaNN * TMath::RadToDeg();
if( hit1 == 1) {
count ++;
}
if( isReDo ){
if( hit1 == 1) {
redoFlag = false;
}else{
redoFlag = true;
//printf("%d, %2d, thetaNN : %f, theta : %f, z0: %f \n", i, hit, thetaNN * 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();
printf("=============== done. saved as %s. count(hit==1) : %d\n", saveFileName.Data(), count);
gROOT->ProcessLine(".q");
/**/
}

813
cleopatra/SimTransfer.C Normal file
View File

@ -0,0 +1,813 @@
#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 = new bool[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 = new ExcitedEnergies[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;
}
}
delete [] dwbaExTemp;
}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;
delete [] useDWBA;
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;
}

View 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 "../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");
}
}
}

View File

@ -0,0 +1,240 @@
#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();
}

71
cleopatra/constant.h Normal file
View File

@ -0,0 +1,71 @@
/***********************************************************************
*
* This is constant.h, to provide various physical constants.
*
*-------------------------------------------------------
* created by Ryan (Tsz Leung) Tang, Nov-18, 2018
* email: goluckyryan@gmail.com
* ********************************************************************/
#ifndef constant
#define constant
#include <cmath>
const double pi = acos(-1.0);
const double E = 2.718281828459 ;
const double hbar_SI = 1.054571628e-34; //Js
const double kB = 1.3806504e-23; //JK^-1
const double e = 1.602176487e-19; //C
const double c_SI = 299792458; //ms^-1
const double me_SI = 9.10938215e-31 ; //kg
const double mp_SI = 1.672621637e-27 ; //kg
const double mn_SI = 1.67492729e-27 ; //kg
const double NA = 6.022141e+23 ; //mol^-1
const double deg2rad = pi/180 ;
const double rad2deg = 180/pi ;
//======================================================================
const double amu = 931.49432; // MeV/c^2
const double hbarc = 197.326979; // MeV fm;
const double c = 299.792458; // mm/ns;
const double ee = 1.439964454; // MeV.fm
//======================================================================
double kg2MeV(double m){
return m*c_SI*c_SI/e/1e6;
}
double T2Brho(double mass, int Z, int A, double T){
//mass in MeV
// Z in e
// T in MeV/A
double gamma = (T*A + mass)/mass;
double beta = sqrt(1-1/gamma/gamma);
return mass*beta*gamma/Z/c;
}
double Brho2T(double mass, int Z, int A, double Brho){
//mass in MeV
// Z in e
return (sqrt(pow(Brho*Z*c,2)+mass*mass)-mass)/A;
}
double T2beta(double mass, int A, double T){
double gamma = 1.0 + T*A/mass;
return sqrt(1-1/gamma/gamma);
}
double ev2nm(double eV){
// photon energy to nm
return hbarc/2/pi/eV;
}
//======================================================================
const double mp = kg2MeV(mp_SI);
const double mn = kg2MeV(mn_SI);
const double hbar = 197.326979;
#endif

41
cleopatra/makefile Normal file
View File

@ -0,0 +1,41 @@
CC = g++
CFLAG = -O2
depend = ClassTransfer.h ClassHelios.h ClassIsotope.h ClassDecay.h constant.h potentials.h
ALL = Isotope InFileCreator ExtractXSec ExtractXSecFromText PlotTGraphTObjArray Cleopatra FindThetaCM SimTransfer SimAlpha
all: $(ALL)
Isotope: ClassIsotope.h Isotope.C
$(CC) $(CFLAG) Isotope.C -o Isotope
InFileCreator: InFileCreator.C InFileCreator.h $(depend)
$(CC) $(CFLAG) InFileCreator.C -o InFileCreator `root-config --cflags --glibs`
ExtractXSec: ExtractXSec.C ExtractXSec.h
$(CC) $(CFLAG) ExtractXSec.C -o ExtractXSec `root-config --cflags --glibs`
ExtractXSecFromText: ExtractXSecFromText.C ExtractXSec.h
$(CC) $(CFLAG) ExtractXSecFromText.C -o ExtractXSecFromText `root-config --cflags --glibs`
PlotTGraphTObjArray: PlotTGraphTObjArray.C PlotTGraphTObjArray.h
$(CC) $(CFLAG) 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 $(depend)
$(CC) $(CFLAG) FindThetaCM.C -o FindThetaCM `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`
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`
clean:
/bin/rm -f $(ALL)

153
cleopatra/nuclear_data.py Executable file
View File

@ -0,0 +1,153 @@
#!/usr/local/bin/python3
################################################
import sys
if len(sys.argv) == 1 :
print( "usage :" )
print( "%s AZ [maxEx]" % sys.argv[0] )
print( "e.g. %s 17O --> 17O ground state data" % sys.argv[0])
print( "e.g. %s 20O 5 --> 20O ground state data and excited state < 5 MeV" % sys.argv[0])
exit()
################################################
import pandas as pd
# the API webpage
# https://www-nds.iaea.org/relnsd/vcharthtml/api_v0_guide.html#examples
# the service URL
livechart = "https://nds.iaea.org/relnsd/v0/data?"
import urllib.request
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))
haha = lc_read_csv(livechart + 'fields=ground_states&nuclides=all')
mp = 938.27208816; #MeV/c^2
mn = 939.56542052;
def FindZ(AZ):
query = livechart + "fields=ground_states&nuclides=" + AZ
temp = lc_read_csv(query);
try :
return temp['z']
except :
return 'na'
def FindSym(Z):
try:
return (haha['symbol'][haha['z']==Z]).iloc[0]
except:
return 'na'
def Mass(A, Z):
try :
BEA = float(haha['binding'][haha['z']==Z][haha['n']==(A-Z)].iloc[0])/1000
return (A-Z)*mn + Z*mp - A * BEA
except :
return -404
def MassSym(AZ):
query = livechart + "fields=ground_states&nuclides=" + AZ
temp = lc_read_csv(query);
Z = temp['z']
N = temp['n']
try :
return Z*mp + N*mn - (Z+N)*temp['binding']/1000
except:
return -404
def Sp(A,Z,a,z):
mA = Mass(A,Z)
mB = Mass(A-a, Z-z)
if z == 0 :
mb = a * mn
elif a == z :
mb = a * mp
else :
mb = Mass(a,z)
if (mB == -404 or mb == -404 or mA == -404) :
return -404
else:
return mB + mb - mA
def Ex(AZ, maxMeV):
query = livechart + "fields=levels&nuclides=" + AZ
tempEx = lc_read_csv(query);
try :
return tempEx[['energy', 'jp']][tempEx['energy']<= maxMeV * 1000]
except:
return -404
def Info(AZ):
query = livechart + "fields=ground_states&nuclides=" + AZ
temp = lc_read_csv(query);
print("============================================== " + AZ )
try :
Z = temp['z'][0]
N = temp['n'][0]
mass = float(Z*mp + N*mn - (Z+N)*temp['binding'].iloc[0]/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))
print("Sn : %8.3f MeV, Sp : %8.3f MeV" % (Sp(Z+N,Z, 1, 0), Sp(Z+N,Z, 1, 1)))
print("S2n : %8.3f MeV, S2p : %8.3f MeV, Sd : %8.3f MeV" % (Sp(Z+N,Z, 2, 0), Sp(Z+N,Z, 2, 2), Sp(Z+N, Z, 2, 1)))
print("S3n : %8.3f MeV, S3p : %8.3f MeV, St : %8.3f MeV, S(3He) : %8.3f MeV" % (Sp(Z+N,Z, 3, 0), Sp(Z+N,Z, 3, 3), Sp(Z+N, Z, 3, 1), Sp(Z+N, Z, 3, 2)))
print("S4n : %8.3f MeV, S4p : %8.3f MeV, Sa : %8.3f MeV" % (Sp(Z+N,Z, 4, 0), Sp(Z+N,Z, 4, 4), Sp(Z+N, Z, 4, 2)))
print(" magnetic dipole : " + temp['magnetic_dipole'][0] + " mu.N")
print("electric quadruple : " + temp['electric_quadrupole'][0] + " barn")
if halfLife > 0 :
print('------------ decay mode:')
for i in range(1, 4) :
print("%5s %s %%" % (temp["decay_%d" % i][0], temp["decay_%d_%%" % i][0]))
print('--------------------------')
except :
dummy = 1
print("====================================================\n")
#outfile = open("%s.txt" % AZ, "w")
#outfile.write("============================================== " + AZ + "\n")
#try :
# Z = temp['z'][0]
# N = temp['n'][0]
# mass = Z*mp + N*mn - (Z+N)*temp['binding']/1000
# halfLife = temp['half_life_sec'][0]
# outfile.write(" A : %3d, Z : %3d, N : %3d, Mass : %.4f MeV \n" % (Z+N, Z, N, mass))
# outfile.write("Jpi : %3s, half-live : %s sec \n" % (temp['jp'][0], halfLife))
# outfile.write("Sn : %8.3f MeV, Sp : %8.3f MeV \n" % (Sp(Z+N,Z, 1, 0), Sp(Z+N,Z, 1, 1)))
# outfile.write("S2n : %8.3f MeV, S2p : %8.3f MeV, Sd : %8.3f MeV \n" % (Sp(Z+N,Z, 2, 0), Sp(Z+N,Z, 2, 2), Sp(Z+N, Z, 2, 1)))
# outfile.write("S3n : %8.3f MeV, S3p : %8.3f MeV, St : %8.3f MeV, S(3He) : %8.3f MeV \n" % (Sp(Z+N,Z, 3, 0), Sp(Z+N,Z, 3, 3), Sp(Z+N, Z, 3, 1), Sp(Z+N, Z, 3, 2)))
# outfile.write("S4n : %8.3f MeV, S4p : %8.3f MeV, Sa : %8.3f MeV \n" % (Sp(Z+N,Z, 4, 0), Sp(Z+N,Z, 4, 4), Sp(Z+N, Z, 4, 2)))
# outfile.write(" magnetic dipole : " + temp['magnetic_dipole'][0] + " mu.N\n")
# outfile.write("electric quadruple : " + temp['electric_quadrupole'][0] + " barn \n")
# if halfLife > 0 :
# outfile.write('------------ decay mode: \n')
# for i in range(1, 4) :
# outfile.write("%5s %s %% \n" % (temp["decay_%d" % i][0], temp["decay_%d_%%" % i][0]))
# outfile.write('-------------------------\n')
#except :
# dummy = 1
#outfile.write("====================================================\n")
#outfile.close();
#
#infile = open("%s.txt" % AZ, "r")
#Lines = infile.readlines()
#
#for line in Lines:
# print(line.strip("\n"))
#
#infile.close();
################################################
AZ = sys.argv[1];
maxEx = 0;
if len(sys.argv) > 2 :
maxEx = float(sys.argv[2]);
Info(AZ)
if maxEx > 0 :
print( Ex(AZ, float(maxEx)) )

1073
cleopatra/potentials.h Normal file

File diff suppressed because it is too large Load Diff

BIN
cleopatra/ptolemy Executable file

Binary file not shown.

2
cleopatra/ptolemy_mac Executable file
View File

@ -0,0 +1,2 @@
#!/bin/bash
docker run --rm --platform linux/amd64 -i -w $PWD tehatanlgov/ptolemy

View File

@ -36,7 +36,7 @@ false //isDacay
#0.000 1.0 1.0 0.01
#1.000 1.0 1.0 0.01
#2.000 1.0 1.0 0.01
1.000 1.0 1.0 0.01
0.000 1.0 1.0 0.01
IAEA + 10 0.01
#==================_reaction_for_2nd_Array_use_ony_when_2nd_array_used