Seperate most of the class into its files: should avoid using Reactionparas struc, use ClassTransfer instead
This commit is contained in:
parent
fa514b16f6
commit
c44fd38783
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -8,6 +8,7 @@ EventBuilder
|
|||
|
||||
.gdb_history
|
||||
|
||||
data
|
||||
data_raw
|
||||
root_data
|
||||
|
||||
|
|
4
.vscode/settings.json
vendored
4
.vscode/settings.json
vendored
|
@ -121,7 +121,9 @@
|
|||
"Monitors_Util.C": "cpp",
|
||||
"Monitor_Util.C": "cpp",
|
||||
"script_single.C": "cpp",
|
||||
"script_multi.C": "cpp"
|
||||
"script_multi.C": "cpp",
|
||||
"Isotope.C": "cpp",
|
||||
"classisotope.h": "c"
|
||||
},
|
||||
|
||||
"better-comments.multilineComments": true,
|
||||
|
|
296
Armory/AnalysisLib.h
Normal file
296
Armory/AnalysisLib.h
Normal file
|
@ -0,0 +1,296 @@
|
|||
#ifndef ANALYSIS_LIB_H
|
||||
#define ANALYSIS_LIB_H
|
||||
|
||||
#include <cstdio>
|
||||
#include <vector>
|
||||
#include <fstream>
|
||||
#include <string>
|
||||
|
||||
#include <TMacro.h>
|
||||
#include <TList.h>
|
||||
#include <TFile.h>
|
||||
#include <TMath.h>
|
||||
#include <TObjArray.h>
|
||||
#include <TCutG.h>
|
||||
|
||||
namespace AnalysisLib {
|
||||
|
||||
std::vector<std::string> SplitStr(std::string tempLine, std::string splitter, int shift = 0){
|
||||
|
||||
std::vector<std::string> output;
|
||||
|
||||
size_t pos;
|
||||
do{
|
||||
pos = tempLine.find(splitter); /// fine splitter
|
||||
if( pos == 0 ){ ///check if it is splitter again
|
||||
tempLine = tempLine.substr(pos+1);
|
||||
continue;
|
||||
}
|
||||
|
||||
std::string secStr;
|
||||
if( pos == std::string::npos ){
|
||||
secStr = tempLine;
|
||||
}else{
|
||||
secStr = tempLine.substr(0, pos+shift);
|
||||
tempLine = tempLine.substr(pos+shift);
|
||||
}
|
||||
|
||||
///check if secStr is begin with space
|
||||
while( secStr.substr(0, 1) == " ") secStr = secStr.substr(1);
|
||||
|
||||
///check if secStr is end with space
|
||||
while( secStr.back() == ' ') secStr = secStr.substr(0, secStr.size()-1);
|
||||
|
||||
output.push_back(secStr);
|
||||
///printf(" |%s---\n", secStr.c_str());
|
||||
|
||||
}while(pos != std::string::npos );
|
||||
|
||||
return output;
|
||||
};
|
||||
|
||||
|
||||
//************************************** TCutG
|
||||
|
||||
TObjArray * LoadListOfTCut(TString fileName, TString cutName = "cutList"){
|
||||
|
||||
if( fileName == "" ) return nullptr;
|
||||
|
||||
TObjArray * cutList = nullptr;
|
||||
|
||||
TFile * fCut = new TFile(fileName);
|
||||
bool isCutFileOpen = fCut->IsOpen();
|
||||
if(!isCutFileOpen) {
|
||||
printf( "Failed to open rdt-cutfile 1 : %s\n" , fileName.Data());
|
||||
}else{
|
||||
cutList = (TObjArray *) fCut->FindObjectAny(cutName);
|
||||
|
||||
if( cutList ){
|
||||
int numCut = cutList->GetEntries();
|
||||
printf("=========== found %d cutG in %s \n", numCut, fCut->GetName());
|
||||
|
||||
for(int i = 0; i < numCut ; i++){
|
||||
printf("cut name : %s , VarX: %s, VarY: %s, numPoints: %d \n",
|
||||
cutList->At(i)->GetName(),
|
||||
((TCutG*)cutList->At(i))->GetVarX(),
|
||||
((TCutG*)cutList->At(i))->GetVarY(),
|
||||
((TCutG*)cutList->At(i))->GetN()
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return cutList;
|
||||
}
|
||||
|
||||
TCutG * LoadSingleTCut( TString fileName, TString cutName = "cutEZ"){
|
||||
|
||||
if( fileName == "" ) return nullptr;
|
||||
TCutG * cut = nullptr;
|
||||
|
||||
TFile * fCut = new TFile(fileName);
|
||||
bool isCutFileOpen = fCut->IsOpen();
|
||||
if( !isCutFileOpen) {
|
||||
printf( "Failed to open E-Z cutfile : %s\n" , fileName.Data());
|
||||
}else{
|
||||
cut = (TCutG *) fCut->FindObjectAny(cutName);
|
||||
if( cut != NULL ) {
|
||||
printf("Found EZ cut| name : %s, VarX: %s, VarY: %s, numPoints: %d \n",
|
||||
cut->GetName(),
|
||||
cut->GetVarX(),
|
||||
cut->GetVarY(),
|
||||
cut->GetN()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return cut;
|
||||
}
|
||||
|
||||
|
||||
//************************************** Others
|
||||
std::vector<std::vector<double>> combination(std::vector<double> arr, int r){
|
||||
|
||||
std::vector<std::vector<double>> output;
|
||||
|
||||
int n = arr.size();
|
||||
std::vector<int> v(n);
|
||||
std::fill(v.begin(), v.begin()+r, 1);
|
||||
do {
|
||||
//for( int i = 0; i < n; i++) { printf("%d ", v[i]); }; printf("\n");
|
||||
|
||||
std::vector<double> temp;
|
||||
for (int i = 0; i < n; ++i) {
|
||||
if (v[i]) {
|
||||
//printf("%.1f, ", arr[i]);
|
||||
temp.push_back(arr[i]);
|
||||
}
|
||||
}
|
||||
//printf("\n");
|
||||
|
||||
output.push_back(temp);
|
||||
|
||||
} while (std::prev_permutation(v.begin(), v.end()));
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
double* sumMeanVar(std::vector<double> data){
|
||||
|
||||
int n = data.size();
|
||||
double sum = 0;
|
||||
for( int k = 0; k < n; k++) sum += data[k];
|
||||
double mean = sum/n;
|
||||
double var = 0;
|
||||
for( int k = 0; k < n; k++) var += pow(data[k] - mean,2);
|
||||
|
||||
static double output[3];
|
||||
output[0] = sum;
|
||||
output[1] = mean;
|
||||
output[2] = var;
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
double* fitSlopeIntercept(std::vector<double> dataX, std::vector<double> dataY){
|
||||
|
||||
double * smvY = sumMeanVar(dataY);
|
||||
double sumY = smvY[0];
|
||||
double meanY = smvY[1];
|
||||
|
||||
double * smvX = sumMeanVar(dataX);
|
||||
double sumX = smvX[0];
|
||||
double meanX = smvX[1];
|
||||
double varX = smvX[2];
|
||||
|
||||
int n = dataX.size();
|
||||
double sumXY = 0;
|
||||
for( int j = 0; j < n; j++) sumXY += dataX[j] * dataY[j];
|
||||
|
||||
double slope = ( sumXY - sumX * sumY/n ) / varX;
|
||||
double intercept = meanY - slope * meanX;
|
||||
|
||||
static double output[2];
|
||||
output[0] = slope;
|
||||
output[1] = intercept;
|
||||
|
||||
return output;
|
||||
|
||||
}
|
||||
|
||||
std::vector<std::vector<double>> FindMatchingPair(std::vector<double> enX, std::vector<double> enY){
|
||||
|
||||
//output[0] = fitEnergy;
|
||||
//output[1] = refEnergy;
|
||||
|
||||
int nX = enX.size();
|
||||
int nY = enY.size();
|
||||
|
||||
std::vector<double> fitEnergy;
|
||||
std::vector<double> refEnergy;
|
||||
|
||||
if( nX > nY ){
|
||||
|
||||
std::vector<std::vector<double>> output = combination(enX, nY);
|
||||
|
||||
double * smvY = sumMeanVar(enY);
|
||||
double sumY = smvY[0];
|
||||
double meanY = smvY[1];
|
||||
double varY = smvY[2];
|
||||
|
||||
double optRSquared = 0;
|
||||
double absRSqMinusOne = 1;
|
||||
int maxID = 0;
|
||||
|
||||
for( int k = 0; k < (int) output.size(); k++){
|
||||
|
||||
double * smvX = sumMeanVar(output[k]);
|
||||
double sumX = smvX[0];
|
||||
double meanX = smvX[1];
|
||||
double varX = smvX[2];
|
||||
|
||||
double sumXY = 0;
|
||||
for( int j = 0; j < nY; j++) sumXY += output[k][j] * enY[j];
|
||||
|
||||
double rSq = abs(sumXY - sumX*sumY/nY)/sqrt(varX*varY);
|
||||
|
||||
//for( int j = 0; j < nY ; j++){ printf("%.1f, ", output[k][j]); }; printf("| %.10f\n", rSq);
|
||||
|
||||
if( abs(rSq-1) < absRSqMinusOne ) {
|
||||
absRSqMinusOne = abs(rSq-1);
|
||||
optRSquared = rSq;
|
||||
maxID = k;
|
||||
}
|
||||
}
|
||||
|
||||
fitEnergy = output[maxID];
|
||||
refEnergy = enY;
|
||||
|
||||
printf(" R^2 : %.20f\n", optRSquared);
|
||||
|
||||
//calculation fitting coefficient
|
||||
//double * si = fitSlopeIntercept(fitEnergy, refEnergy);
|
||||
//printf( " y = %.4f x + %.4f\n", si[0], si[1]);
|
||||
|
||||
}else if( nX < nY ){
|
||||
|
||||
std::vector<std::vector<double>> output = combination(enY, nX);
|
||||
|
||||
|
||||
double * smvX = sumMeanVar(enX);
|
||||
double sumX = smvX[0];
|
||||
double meanX = smvX[1];
|
||||
double varX = smvX[2];
|
||||
|
||||
double optRSquared = 0;
|
||||
double absRSqMinusOne = 1;
|
||||
int maxID = 0;
|
||||
|
||||
for( int k = 0; k < (int) output.size(); k++){
|
||||
|
||||
double * smvY = sumMeanVar(output[k]);
|
||||
double sumY = smvY[0];
|
||||
double meanY = smvY[1];
|
||||
double varY = smvY[2];
|
||||
|
||||
double sumXY = 0;
|
||||
for( int j = 0; j < nX; j++) sumXY += output[k][j] * enX[j];
|
||||
|
||||
double rSq = abs(sumXY - sumX*sumY/nX)/sqrt(varX*varY);
|
||||
|
||||
//for( int j = 0; j < nX ; j++){ printf("%.1f, ", output[k][j]); }; printf("| %.10f\n", rSq);
|
||||
|
||||
if( abs(rSq-1) < absRSqMinusOne ) {
|
||||
absRSqMinusOne = abs(rSq-1);
|
||||
optRSquared = rSq;
|
||||
maxID = k;
|
||||
}
|
||||
}
|
||||
|
||||
fitEnergy = enX;
|
||||
refEnergy = output[maxID];
|
||||
printf(" R^2 : %.20f\n", optRSquared);
|
||||
|
||||
}else{
|
||||
fitEnergy = enX;
|
||||
refEnergy = enY;
|
||||
|
||||
//if nX == nY, ther could be cases that only partial enX and enY are matched.
|
||||
|
||||
}
|
||||
|
||||
printf("fitEnergy = ");for( int k = 0; k < (int) fitEnergy.size() ; k++){ printf("%7.2f, ", fitEnergy[k]); }; printf("\n");
|
||||
printf("refEnergy = ");for( int k = 0; k < (int) refEnergy.size() ; k++){ printf("%7.2f, ", refEnergy[k]); }; printf("\n");
|
||||
|
||||
std::vector<std::vector<double>> haha;
|
||||
haha.push_back(fitEnergy);
|
||||
haha.push_back(refEnergy);
|
||||
|
||||
return haha;
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
#endif
|
2861
Armory/AutoFit.C
Normal file
2861
Armory/AutoFit.C
Normal file
File diff suppressed because it is too large
Load Diff
257
Armory/ClassDetGeo.h
Normal file
257
Armory/ClassDetGeo.h
Normal file
|
@ -0,0 +1,257 @@
|
|||
#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{
|
||||
|
||||
double detPerpDist; /// distance from axis
|
||||
double detWidth; /// width
|
||||
double detLength; /// length
|
||||
double blocker;
|
||||
double firstPos; /// meter
|
||||
double eSigma; /// intrinsic energy resolution MeV
|
||||
double zSigma; /// intrinsic position resolution mm
|
||||
bool detFaceOut; ///detector_facing_Out_or_In
|
||||
std::vector<double> pos; /// near position in meter
|
||||
int nDet, mDet; /// nDet = number of different pos, mDet, number of same pos
|
||||
std::vector<double> detPos; ///absolute position of detector
|
||||
|
||||
double zMin, zMax;
|
||||
|
||||
void DeduceAbsolutePos(){
|
||||
nDet = pos.size();
|
||||
detPos.clear();
|
||||
|
||||
for(int id = 0; id < nDet; id++){
|
||||
if( firstPos > 0 ) detPos.push_back(firstPos + pos[id]);
|
||||
if( firstPos < 0 ) detPos.push_back(firstPos - pos[nDet - 1 - id]);
|
||||
///printf("%d | %f, %f \n", id, pos[id], detPos[id]);
|
||||
}
|
||||
|
||||
zMin = TMath::Min(detPos.front(), detPos.back()) - (firstPos < 0 ? detLength : 0);
|
||||
zMax = TMath::Max(detPos.front(), detPos.back()) + (firstPos > 0 ? detLength : 0);
|
||||
}
|
||||
|
||||
void PrintArray() const{
|
||||
for(int i = 0; i < nDet ; i++){
|
||||
if( firstPos > 0 ){
|
||||
printf("%d, %8.2f mm - %8.2f mm \n", i, detPos[i], detPos[i] + detLength);
|
||||
}else{
|
||||
printf("%d, %8.2f mm - %8.2f mm \n", i, detPos[i] - detLength , detPos[i]);
|
||||
}
|
||||
}
|
||||
|
||||
printf(" Blocker Position: %8.2f mm \n", firstPos > 0 ? firstPos - blocker : firstPos + blocker );
|
||||
printf(" First Position: %8.2f mm \n", firstPos);
|
||||
printf(" number of det : %d x %d \n", mDet, nDet);
|
||||
printf(" detector facing : %s\n", detFaceOut ? "Out" : "In");
|
||||
printf(" energy resol.: %f MeV\n", eSigma);
|
||||
printf(" pos-Z resol.: %f mm \n", zSigma);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
class DetGeo {
|
||||
|
||||
public:
|
||||
DetGeo();
|
||||
~DetGeo();
|
||||
|
||||
double Bfield; /// T
|
||||
int BfieldSign ; /// sign of B-field
|
||||
double BfieldTheta; /// rad, 0 = z-axis, pi/2 = y axis, pi = -z axis
|
||||
double bore; /// bore , mm
|
||||
|
||||
double recoilPos; /// recoil, downstream
|
||||
double recoilInnerRadius; /// radius recoil inner
|
||||
double recoilOuterRadius; /// radius recoil outter
|
||||
|
||||
double recoilPos1, recoilPos2; /// imaginary recoils
|
||||
|
||||
double elumPos1, elumPos2; /// imaginary elum, only sensitive to light recoil
|
||||
|
||||
//===================1st array
|
||||
Array array1;
|
||||
|
||||
//==================2nd array
|
||||
bool use2ndArray;
|
||||
Array array2;
|
||||
|
||||
double zMin, zMax; /// range of detectors
|
||||
bool isCoincidentWithRecoil;
|
||||
|
||||
bool LoadDetectorGeo(TString fileName);
|
||||
bool LoadDetectorGeo(TMacro * macro);
|
||||
|
||||
void PrintDetGeo( bool printAll = true) const;
|
||||
|
||||
private:
|
||||
|
||||
};
|
||||
|
||||
inline DetGeo::DetGeo(){
|
||||
|
||||
}
|
||||
|
||||
inline DetGeo::~DetGeo(){
|
||||
|
||||
}
|
||||
|
||||
inline bool DetGeo::LoadDetectorGeo(TString fileName){
|
||||
|
||||
TMacro * haha = new TMacro();
|
||||
if( haha->ReadFile(fileName) > 0 ) {
|
||||
if( LoadDetectorGeo(haha) ){
|
||||
return true;
|
||||
}else{
|
||||
return false;
|
||||
}
|
||||
}else{
|
||||
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){
|
||||
|
||||
if( macro == NULL ) return false;
|
||||
|
||||
TList * haha = macro->GetListOfLines();
|
||||
int numLine = (haha)->GetSize();
|
||||
|
||||
array1.pos.clear();
|
||||
array2.pos.clear();
|
||||
use2ndArray = false;
|
||||
|
||||
int detFlag = 0;
|
||||
int detLine = 0;
|
||||
|
||||
for( int i = 0 ; i < numLine; i++){
|
||||
|
||||
std::vector<std::string> str = AnalysisLib::SplitStr(macro->GetListOfLines()->At(i)->GetName(), " ");
|
||||
|
||||
//printf("%3d | %s\n", i, str[0].c_str());
|
||||
|
||||
if( str[0].find("####") != std::string::npos ) break;
|
||||
if( str[0].find("#===") != std::string::npos ) {
|
||||
detFlag ++;
|
||||
detLine = 0;
|
||||
continue;;
|
||||
}
|
||||
|
||||
if( detFlag == 0 ){
|
||||
if ( i == 0 ) {
|
||||
Bfield = atof(str[0].c_str());
|
||||
BfieldSign = Bfield > 0 ? 1: -1;
|
||||
}
|
||||
if ( i == 1 ) BfieldTheta = atof(str[0].c_str());
|
||||
if ( i == 2 ) bore = atof(str[0].c_str());
|
||||
if ( i == 3 ) recoilPos = atof(str[0].c_str());
|
||||
if ( i == 4 ) recoilInnerRadius = atof(str[0].c_str());
|
||||
if ( i == 5 ) recoilOuterRadius = atof(str[0].c_str());
|
||||
if ( i == 6 ) isCoincidentWithRecoil = str[0] == "false" ? false: true;
|
||||
if ( i == 7 ) recoilPos1 = atof(str[0].c_str());
|
||||
if ( i == 8 ) recoilPos2 = atof(str[0].c_str());
|
||||
if ( i == 9 ) elumPos1 = atof(str[0].c_str());
|
||||
if ( i == 10 ) elumPos2 = atof(str[0].c_str());
|
||||
}
|
||||
|
||||
if( detFlag == 1){
|
||||
if ( detLine == 0 ) array1.detPerpDist = atof(str[0].c_str());
|
||||
if ( detLine == 1 ) array1.detWidth = atof(str[0].c_str());
|
||||
if ( detLine == 2 ) array1.detLength = atof(str[0].c_str());
|
||||
if ( detLine == 3 ) array1.blocker = atof(str[0].c_str());
|
||||
if ( detLine == 4 ) array1.firstPos = atof(str[0].c_str());
|
||||
if ( detLine == 5 ) array1.eSigma = atof(str[0].c_str());
|
||||
if ( detLine == 6 ) array1.zSigma = atof(str[0].c_str());
|
||||
if ( detLine == 7 ) array1.detFaceOut = str[0] == "Out" ? true : false;
|
||||
if ( detLine == 8 ) array1.mDet = atoi(str[0].c_str());
|
||||
if ( detLine >= 9 ) array1.pos.push_back(atof(str[0].c_str()));
|
||||
detLine ++;
|
||||
}
|
||||
|
||||
if( detFlag == 2){
|
||||
if ( detLine == 0 ) use2ndArray = str[0] == "true" ? true : false;
|
||||
if ( detLine == 1 ) array2.detPerpDist = atof(str[0].c_str());
|
||||
if ( detLine == 2 ) array2.detWidth = atof(str[0].c_str());
|
||||
if ( detLine == 3 ) array2.detLength = atof(str[0].c_str());
|
||||
if ( detLine == 4 ) array2.blocker = atof(str[0].c_str());
|
||||
if ( detLine == 5 ) array2.firstPos = atof(str[0].c_str());
|
||||
if ( detLine == 6 ) array2.eSigma = atof(str[0].c_str());
|
||||
if ( detLine == 7 ) array2.zSigma = atof(str[0].c_str());
|
||||
if ( detLine == 8 ) array2.detFaceOut = str[0] == "Out" ? true : false;
|
||||
if ( detLine == 9 ) array2.mDet = atoi(str[0].c_str());
|
||||
if ( detLine >= 10 ) array2.pos.push_back(atof(str[0].c_str()));
|
||||
detLine ++;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
array1.DeduceAbsolutePos();
|
||||
|
||||
zMin = array1.zMin;
|
||||
zMax = array1.zMax;
|
||||
|
||||
if( use2ndArray) {
|
||||
array2.DeduceAbsolutePos();
|
||||
|
||||
zMax = TMath::Min(array1.zMax, array2.zMax);
|
||||
zMin = TMath::Min(array1.zMin, array2.zMin);
|
||||
}
|
||||
|
||||
PrintDetGeo(false);
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
inline void DetGeo::PrintDetGeo(bool printAll) const{
|
||||
|
||||
printf("=====================================================\n");
|
||||
printf(" B-field: %8.2f T, Theta : %6.2f deg \n", Bfield, BfieldTheta);
|
||||
if( BfieldTheta != 0.0 ) {
|
||||
printf(" +---- field angle != 0 is not supported!!! \n");
|
||||
}
|
||||
printf(" Recoil detector pos: %8.2f mm, radius: %6.2f - %6.2f mm \n", recoilPos, recoilInnerRadius, recoilOuterRadius);
|
||||
if( printAll ){
|
||||
printf("------------------------------------- Detector Position \n");
|
||||
array1.PrintArray();
|
||||
|
||||
if( use2ndArray){
|
||||
printf("--------------------------------- 2nd Detector Position \n");
|
||||
array2.PrintArray();
|
||||
}
|
||||
}else{
|
||||
if( use2ndArray){
|
||||
printf("--------------------------------- 2nd Detector Position \n");
|
||||
array2.PrintArray();
|
||||
}else{
|
||||
printf("------------------------------------- Detector Position \n");
|
||||
array1.PrintArray();
|
||||
}
|
||||
}
|
||||
|
||||
if( elumPos1 != 0 || elumPos2 != 0 || recoilPos1 != 0 || recoilPos2 != 0){
|
||||
printf("=================================== Auxillary/Imaginary 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( recoilPos1 != 0 ) printf(" Recoil 1 pos.: %f mm \n", recoilPos1);
|
||||
if( recoilPos2 != 0 ) printf(" Recoil 2 pos.: %f mm \n", recoilPos2);
|
||||
printf("=====================================================\n");
|
||||
|
||||
}
|
||||
|
||||
#endif
|
190
Armory/ClassReactionConfig.h
Normal file
190
Armory/ClassReactionConfig.h
Normal file
|
@ -0,0 +1,190 @@
|
|||
#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"
|
||||
|
||||
class ReactionConfig {
|
||||
|
||||
public:
|
||||
ReactionConfig(){}
|
||||
~ReactionConfig(){}
|
||||
|
||||
int beamA, beamZ;
|
||||
int targetA, targetZ;
|
||||
int recoilLightA, recoilLightZ;
|
||||
int recoilHeavyA, recoilHeavyZ;
|
||||
|
||||
float beamEnergy; ///MeV/u
|
||||
float beamEnergySigma; ///beam-energy_sigma_in_MeV/u
|
||||
float beamAngle; ///beam-angle_in_mrad
|
||||
float beamAngleSigma; ///beam-emittance_in_mrad
|
||||
float beamX; ///x_offset_of_Beam_in_mm
|
||||
float beamY; ///y_offset_of_Beam_in_mm
|
||||
|
||||
int numEvents; ///number_of_Event_being_generated
|
||||
bool isTargetScattering; ///isTargetScattering
|
||||
float targetDensity; ///target_density_in_g/cm3
|
||||
float targetThickness; ///targetThickness_in_cm
|
||||
std::string beamStoppingPowerFile; ///stopping_power_for_beam
|
||||
std::string recoilLightStoppingPowerFile; ///stopping_power_for_light_recoil
|
||||
std::string recoilHeavyStoppingPowerFile; ///stopping_power_for_heavy_recoil
|
||||
bool isDecay; ///isDacay
|
||||
int heavyDecayA; ///decayNucleus_A
|
||||
int heavyDecayZ; ///decayNucleus_Z
|
||||
bool isRedo; ///isReDo
|
||||
std::vector<float> beamEx; ///excitation_energy_of_A[MeV]
|
||||
|
||||
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 PrintReactionConfig() 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->recoilLightA = recoilA;
|
||||
this->recoilLightZ = recoilZ;
|
||||
recoilHeavyA = this->beamA + this->targetA - recoilLightA;
|
||||
recoilHeavyZ = this->beamZ + this->targetZ - recoilLightZ;
|
||||
|
||||
beamEnergy = beamEnergy_AMeV;
|
||||
beamEnergySigma = 0;
|
||||
beamAngle = 0;
|
||||
beamAngleSigma = 0;
|
||||
beamX = 0;
|
||||
beamY = 0;
|
||||
|
||||
}
|
||||
|
||||
inline bool ReactionConfig::LoadReactionConfig(TString fileName){
|
||||
TMacro * haha = new TMacro();
|
||||
if( haha->ReadFile(fileName) > 0 ) {
|
||||
if( LoadReactionConfig(haha) ){
|
||||
return true;
|
||||
}else{
|
||||
return false;
|
||||
}
|
||||
}else{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
inline bool ReactionConfig::LoadReactionConfig(TMacro * macro){
|
||||
|
||||
if( macro == NULL ) return false;
|
||||
|
||||
int numLine = macro->GetListOfLines()->GetSize();
|
||||
|
||||
for( int i = 0; i < numLine; i ++){
|
||||
|
||||
std::vector<std::string> str =AnalysisLib::SplitStr(macro->GetListOfLines()->At(i)->GetName(), " ");
|
||||
|
||||
///printf("%d | %s\n", i, str[0].c_str());
|
||||
|
||||
if( str[0].find_first_of("#") == 0 ) break;
|
||||
|
||||
if( i == 0 ) beamA = atoi(str[0].c_str());
|
||||
if( i == 1 ) beamZ = atoi(str[0].c_str());
|
||||
if( i == 2 ) targetA = atoi(str[0].c_str());
|
||||
if( i == 3 ) targetZ = atoi(str[0].c_str());
|
||||
if( i == 4 ) recoilLightA = atoi(str[0].c_str());
|
||||
if( i == 5 ) recoilLightZ = atoi(str[0].c_str());
|
||||
if( i == 6 ) beamEnergy = atof(str[0].c_str());
|
||||
if( i == 7 ) beamEnergySigma = atof(str[0].c_str());
|
||||
if( i == 8 ) beamAngle = atof(str[0].c_str());
|
||||
if( i == 9 ) beamAngleSigma = atof(str[0].c_str());
|
||||
if( i == 10 ) beamX = atof(str[0].c_str());
|
||||
if( i == 11 ) beamY = atof(str[0].c_str());
|
||||
if( i == 12 ) numEvents = atoi(str[0].c_str());
|
||||
if( i == 13 ) {
|
||||
if( str[0].compare("false") == 0 ) isTargetScattering = false;
|
||||
if( str[0].compare("true") == 0 ) isTargetScattering = true;
|
||||
}
|
||||
if( i == 14 ) targetDensity = atof(str[0].c_str());
|
||||
if( i == 15 ) targetThickness = atof(str[0].c_str());
|
||||
if( i == 16 ) beamStoppingPowerFile = str[0];
|
||||
if( i == 17 ) recoilLightStoppingPowerFile = str[0];
|
||||
if( i == 18 ) recoilHeavyStoppingPowerFile = str[0];
|
||||
if( i == 19 ) {
|
||||
if( str[0].compare("false") == 0 ) isDecay = false;
|
||||
if( str[0].compare("true") == 0 ) isDecay = true;
|
||||
}
|
||||
if( i == 20 ) heavyDecayA = atoi(str[0].c_str());
|
||||
if( i == 21 ) heavyDecayZ = atoi(str[0].c_str());
|
||||
if( i == 22 ) {
|
||||
if( str[0].compare("false") == 0 ) isRedo = false;
|
||||
if( str[0].compare("true" ) == 0 ) isRedo = true;
|
||||
}
|
||||
|
||||
if( i >= 23) {
|
||||
beamEx.push_back( atof(str[0].c_str()) );
|
||||
}
|
||||
}
|
||||
|
||||
recoilHeavyA = beamA + targetA - recoilLightA;
|
||||
recoilHeavyZ = beamZ + targetZ - recoilLightZ;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
inline void ReactionConfig::PrintReactionConfig() const{
|
||||
|
||||
printf("=====================================================\n");
|
||||
printf(" beam : A = %3d, Z = %2d \n", beamA, beamZ);
|
||||
printf(" target : A = %3d, Z = %2d \n", targetA, targetZ);
|
||||
printf(" light : A = %3d, Z = %2d \n", recoilLightA, recoilLightZ);
|
||||
|
||||
printf(" beam Energy : %.2f +- %.2f MeV/u, dE/E = %5.2f %%\n", beamEnergy, beamEnergySigma, beamEnergySigma/beamEnergy);
|
||||
printf(" Angle : %.2f +- %.2f mrad\n", beamAngle, beamAngleSigma);
|
||||
printf(" offset : (x,y) = (%.2f, %.2f) mmm \n", beamX, beamY);
|
||||
|
||||
printf("##### number of Simulation Events : %d \n", numEvents);
|
||||
|
||||
printf(" is target 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(" recoil light stopping file : %s \n", recoilLightStoppingPowerFile.c_str());
|
||||
printf(" recoil heavy stopping file : %s \n", recoilHeavyStoppingPowerFile.c_str());
|
||||
}
|
||||
|
||||
printf(" is simulate decay : %s \n", isDecay ? "Yes" : "No");
|
||||
if( isDecay ){
|
||||
printf(" heavy decay : A = %d, Z = %d \n", heavyDecayA, heavyDecayZ);
|
||||
}
|
||||
printf(" is Redo until hit array : %s \n", isRedo ? "Yes" : "No");
|
||||
|
||||
printf(" beam Ex : %.2f MeV \n", beamEx[0]);
|
||||
for( int i = 1; i < (int) beamEx.size(); i++){
|
||||
printf(" %.2f MeV \n", beamEx[i]);
|
||||
}
|
||||
|
||||
printf("=====================================================\n");
|
||||
}
|
||||
|
||||
#endif
|
351
Armory/EventBuilder.cpp
Normal file
351
Armory/EventBuilder.cpp
Normal file
|
@ -0,0 +1,351 @@
|
|||
#include "SolReader.h"
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
|
||||
#include "TFile.h"
|
||||
#include "TTree.h"
|
||||
#include "TMath.h"
|
||||
#include "TString.h"
|
||||
#include "TMacro.h"
|
||||
//#include "TClonesArray.h" // plan to save trace as TVector with TClonesArray
|
||||
//#include "TVector.h"
|
||||
|
||||
#define MAX_MULTI 64
|
||||
#define MAX_TRACE_LEN 2500
|
||||
|
||||
#define tick2ns 8 // 1 tick = 8 ns
|
||||
|
||||
SolReader ** reader;
|
||||
Hit ** hit;
|
||||
|
||||
std::vector<std::vector<int>> idList;
|
||||
|
||||
unsigned long totFileSize = 0;
|
||||
unsigned long processedFileSize = 0;
|
||||
|
||||
std::vector<int> activeFileID;
|
||||
std::vector<int> groupIndex;
|
||||
std::vector<std::vector<int>> group; // group[i][j], i = group ID, j = group member)
|
||||
|
||||
void findEarliestTime(int &fileID, int &groupID){
|
||||
|
||||
unsigned long firstTime = 0;
|
||||
for( int i = 0; i < (int) activeFileID.size(); i++){
|
||||
int id = activeFileID[i];
|
||||
if( i == 0 ) {
|
||||
firstTime = hit[id]->timestamp;
|
||||
fileID = id;
|
||||
groupID = i;
|
||||
//printf("%d | %d %lu %d | %d \n", id, reader[id]->GetBlockID(), hit[id]->timestamp, hit[id]->channel, (int) activeFileID.size());
|
||||
continue;
|
||||
}
|
||||
if( hit[id]->timestamp <= firstTime) {
|
||||
firstTime = hit[id]->timestamp;
|
||||
fileID = id;
|
||||
groupID = i;
|
||||
//printf("%d | %d %lu %d | %d \n", id, reader[id]->GetBlockID(), hit[id]->timestamp, hit[id]->channel, (int) activeFileID.size());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
unsigned long long evID = 0;
|
||||
unsigned int multi = 0;
|
||||
unsigned short bd[MAX_MULTI] = {0};
|
||||
unsigned short sn[MAX_MULTI] = {0};
|
||||
unsigned short ch[MAX_MULTI] = {0};
|
||||
unsigned short e[MAX_MULTI] = {0};
|
||||
unsigned short e2[MAX_MULTI] = {0}; //for PSD energy short
|
||||
unsigned long long e_t[MAX_MULTI] = {0};
|
||||
unsigned short e_f[MAX_MULTI] = {0};
|
||||
unsigned short lowFlag[MAX_MULTI] = {0};
|
||||
unsigned short highFlag[MAX_MULTI] = {0};
|
||||
int traceLen[MAX_MULTI] = {0};
|
||||
int trace[MAX_MULTI][MAX_TRACE_LEN] = {0};
|
||||
|
||||
void fillData(int &fileID, const bool &saveTrace){
|
||||
bd[multi] = idList[fileID][1];
|
||||
sn[multi] = idList[fileID][3];
|
||||
ch[multi] = hit[fileID]->channel;
|
||||
e[multi] = hit[fileID]->energy;
|
||||
e2[multi] = hit[fileID]->energy_short;
|
||||
e_t[multi] = hit[fileID]->timestamp;
|
||||
e_f[multi] = hit[fileID]->fine_timestamp;
|
||||
lowFlag[multi] = hit[fileID]->flags_low_priority;
|
||||
highFlag[multi] = hit[fileID]->flags_high_priority;
|
||||
|
||||
if( saveTrace ){
|
||||
traceLen[multi] = hit[fileID]->traceLenght;
|
||||
for( int i = 0; i < TMath::Min(traceLen[multi], MAX_TRACE_LEN); i++){
|
||||
trace[multi][i] = hit[fileID]->analog_probes[0][i];
|
||||
}
|
||||
}
|
||||
|
||||
multi++;
|
||||
reader[fileID]->ReadNextBlock();
|
||||
}
|
||||
|
||||
void printEvent(){
|
||||
printf("==================== evID : %llu\n", evID);
|
||||
for( int i = 0; i < multi; i++){
|
||||
printf(" %2d | %d %d | %llu %d \n", i, bd[i], ch[i], e_t[i], e[i] );
|
||||
}
|
||||
printf("==========================================\n");
|
||||
}
|
||||
|
||||
//^##################################################################################
|
||||
int main(int argc, char ** argv){
|
||||
|
||||
printf("=======================================================\n");
|
||||
printf("=== SOLARIS Event Builder sol --> root ===\n");
|
||||
printf("=======================================================\n");
|
||||
|
||||
if( argc <= 3){
|
||||
printf("%s [outfile] [timeWindow] [saveTrace] [sol-1] [sol-2] ... \n", argv[0]);
|
||||
printf(" outfile : output root file name\n");
|
||||
printf(" timeWindow : number of tick, 1 tick = %d ns.\n", tick2ns);
|
||||
printf(" saveTrace : 1 = save trace, 0 = no trace\n");
|
||||
printf(" sol-X : the sol file(s)\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
// for( int i = 0; i < argc; i++){
|
||||
// printf("%d | %s\n", i, argv[i]);
|
||||
// }
|
||||
|
||||
TString outFileName = argv[1];
|
||||
int timeWindow = abs(atoi(argv[2]));
|
||||
const bool saveTrace = atoi(argv[3]);
|
||||
|
||||
const int nFile = argc - 4;
|
||||
TString inFileName[nFile];
|
||||
for( int i = 0 ; i < nFile ; i++){
|
||||
inFileName[i] = argv[i+4];
|
||||
}
|
||||
|
||||
//*======================================== setup reader
|
||||
reader = new SolReader*[nFile];
|
||||
hit = new Hit *[nFile];
|
||||
|
||||
for( int i = 0 ; i < nFile ; i++){
|
||||
reader[i] = new SolReader(inFileName[i].Data());
|
||||
hit[i] = reader[i]->hit; //TODO check is file open propertly
|
||||
reader[i]->ReadNextBlock(); // read the first block
|
||||
}
|
||||
|
||||
//*======================================== group files
|
||||
idList.clear();
|
||||
for( int i = 0; i < nFile; i++){
|
||||
TString fn = inFileName[i];
|
||||
|
||||
int pos = fn.Last('/'); // path
|
||||
fn.Remove(0, pos+1);
|
||||
|
||||
pos = fn.First('_'); // expName;
|
||||
fn.Remove(0, pos+1);
|
||||
|
||||
pos = fn.First('_'); // runNum;
|
||||
fn.Remove(0, pos+1);
|
||||
|
||||
pos = fn.First('_'); // digiID
|
||||
TString f1 = fn;
|
||||
int digiID = f1.Remove(pos).Atoi();
|
||||
fn.Remove(0, pos+1);
|
||||
|
||||
pos = fn.Last('_'); // digi serial num
|
||||
f1 = fn;
|
||||
int digisn = f1.Remove(pos).Atoi();
|
||||
fn.Remove(0, pos+1);
|
||||
|
||||
pos = fn.First('.'); // get the file id;
|
||||
int indexID = fn.Remove(pos).Atoi();
|
||||
|
||||
int fileID = i;
|
||||
std::vector<int> haha = {fileID, digiID, indexID, digisn};
|
||||
idList.push_back(haha);
|
||||
}
|
||||
|
||||
// sort by digiID
|
||||
std::sort(idList.begin(), idList.end(), [](const std::vector<int>& a, const std::vector<int>& b){
|
||||
if (a[1] == b[1]) {
|
||||
return a[2] < b[2];
|
||||
}
|
||||
return a[1] < b[1];
|
||||
});
|
||||
|
||||
group.clear(); // group[i][j], i is the group Index = digiID
|
||||
int last_id = 0;
|
||||
std::vector<int> kaka;
|
||||
for( int i = 0; i < (int) idList.size() ; i++){
|
||||
if( i == 0 ) {
|
||||
kaka.clear();
|
||||
last_id = idList[i][1];
|
||||
kaka.push_back(idList[i][0]);
|
||||
continue;
|
||||
}
|
||||
|
||||
if( idList[i][1] != last_id ) {
|
||||
last_id = idList[i][1];
|
||||
group.push_back(kaka);
|
||||
kaka.clear();
|
||||
kaka.push_back(idList[i][0]);
|
||||
}else{
|
||||
kaka.push_back(idList[i][0]);
|
||||
}
|
||||
}
|
||||
group.push_back(kaka);
|
||||
|
||||
printf(" out file : \033[1;33m%s\033[m\n", outFileName.Data());
|
||||
printf(" Event building time window : %d tics = %d nsec \n", timeWindow, timeWindow*tick2ns);
|
||||
printf(" Save Trace ? %s \n", saveTrace ? "Yes" : "No");
|
||||
printf(" Number of input file : %d \n", nFile);
|
||||
for( int i = 0; i < nFile; i++){
|
||||
printf(" %2d| %5.1f MB| %s \n", i, reader[i]->GetFileSize()/1024./1024., inFileName[i].Data());
|
||||
totFileSize += reader[i]->GetFileSize();
|
||||
}
|
||||
printf("------------------------------------\n");
|
||||
for( int i = 0; i < (int) group.size(); i++){
|
||||
printf("Group %d :", i);
|
||||
for( int j = 0; j < (int) group[i].size(); j ++){
|
||||
printf("%d, ", group[i][j]);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
printf("------------------------------------\n");
|
||||
|
||||
//*======================================== setup tree
|
||||
TFile * outRootFile = new TFile(outFileName, "recreate");
|
||||
outRootFile->cd();
|
||||
|
||||
TTree * tree = new TTree("tree", outFileName);
|
||||
|
||||
tree->Branch("evID", &evID, "event_ID/l");
|
||||
tree->Branch("multi", &multi, "multi/i");
|
||||
tree->Branch("bd", bd, "board[multi]/s");
|
||||
tree->Branch("sn", sn, "sn[multi]/s");
|
||||
tree->Branch("ch", ch, "channel[multi]/s");
|
||||
tree->Branch("e", e, "energy[multi]/s");
|
||||
tree->Branch("e2", e2, "energy_short[multi]/s");
|
||||
tree->Branch("e_t", e_t, "timestamp[multi]/l");
|
||||
tree->Branch("e_f", e_f, "fine_timestamp[multi]/s");
|
||||
tree->Branch("lowFlag", lowFlag, "lowFlag[multi]/s");
|
||||
tree->Branch("highFlag", highFlag, "highFlag[multi]/s");
|
||||
|
||||
if( saveTrace){
|
||||
tree->Branch("tl", traceLen, "traceLen[multi]/I");
|
||||
tree->Branch("trace", trace, Form("trace[multi][%d]/I", MAX_TRACE_LEN));
|
||||
}
|
||||
|
||||
//*=========================================== build event
|
||||
|
||||
//@---- using file from group[i][0] first
|
||||
|
||||
//--- find earlist time among the files
|
||||
activeFileID.clear();
|
||||
groupIndex.clear(); //the index of each group
|
||||
|
||||
for(int i = 0; i < (int) group.size(); i++) {
|
||||
groupIndex.push_back(0);
|
||||
activeFileID.push_back(group[i][0]);
|
||||
}
|
||||
|
||||
int fileID = 0;
|
||||
int groupID = 0;
|
||||
findEarliestTime(fileID, groupID);
|
||||
fillData(fileID, saveTrace);
|
||||
|
||||
unsigned long firstTimeStamp = hit[fileID]->timestamp;
|
||||
unsigned long lastTimeStamp = 0;
|
||||
|
||||
int last_precentage = 0;
|
||||
while((activeFileID.size() > 0)){
|
||||
|
||||
findEarliestTime(fileID, groupID);
|
||||
if( reader[fileID]->IsEndOfFile() ){
|
||||
groupIndex[groupID] ++;
|
||||
if( groupIndex[groupID] < (int) group[groupID].size() ){
|
||||
activeFileID[groupID] = group[groupID][groupIndex[groupID]];
|
||||
fileID = activeFileID[groupID];
|
||||
}else{
|
||||
activeFileID.erase(activeFileID.begin() + groupID);
|
||||
}
|
||||
}
|
||||
|
||||
if( hit[fileID]->timestamp - e_t[0] < timeWindow ){
|
||||
fillData(fileID, saveTrace);
|
||||
}else{
|
||||
outRootFile->cd();
|
||||
tree->Fill();
|
||||
evID ++;
|
||||
|
||||
multi = 0;
|
||||
fillData(fileID, saveTrace);
|
||||
}
|
||||
|
||||
///========= calculate progress
|
||||
processedFileSize = 0;
|
||||
for( int p = 0; p < (int) group.size(); p ++){
|
||||
for( int q = 0; q <= groupIndex[p]; q++){
|
||||
if( groupIndex[p] < (int) group[p].size() ){
|
||||
int id = group[p][q];
|
||||
processedFileSize += reader[id]->GetFilePos();
|
||||
}
|
||||
}
|
||||
}
|
||||
double percentage = processedFileSize * 100/ totFileSize;
|
||||
if( percentage >= last_precentage ) {
|
||||
printf("Processed : %llu, %.0f%% | %lu/%lu | ", evID, percentage, processedFileSize, totFileSize);
|
||||
for( int i = 0; i < (int) activeFileID.size(); i++) printf("%d, ", activeFileID[i]);
|
||||
printf(" \n\033[A\r");
|
||||
last_precentage = percentage + 1.0;
|
||||
}
|
||||
}; ///====== end of event building loop
|
||||
|
||||
processedFileSize = 0;
|
||||
for( int p = 0; p < (int) group.size(); p ++){
|
||||
for( int q = 0; q < (int) group[p].size(); q++){
|
||||
int id = group[p][q];
|
||||
processedFileSize += reader[id]->GetFilePos();
|
||||
}
|
||||
}
|
||||
double percentage = processedFileSize * 100/ totFileSize;
|
||||
printf("Processed : %llu, %.0f%% | %lu/%lu \n", evID, percentage, processedFileSize, totFileSize);
|
||||
|
||||
lastTimeStamp = hit[fileID]->timestamp;
|
||||
//*=========================================== save file
|
||||
outRootFile->cd();
|
||||
tree->Fill();
|
||||
evID ++;
|
||||
tree->Write();
|
||||
|
||||
//*=========================================== Save timestamp as TMacro
|
||||
TMacro timeStamp;
|
||||
TString str;
|
||||
str.Form("%lu", firstTimeStamp); timeStamp.AddLine( str.Data() );
|
||||
str.Form("%lu", lastTimeStamp); timeStamp.AddLine( str.Data() );
|
||||
timeStamp.Write("timeStamp");
|
||||
|
||||
unsigned int numBlock = 0;
|
||||
for( int i = 0; i < nFile; i++){
|
||||
//printf("%d | %8ld | %10u/%10u\n", i, reader[i]->GetBlockID() + 1, reader[i]->GetFilePos(), reader[i]->GetFileSize());
|
||||
numBlock += reader[i]->GetBlockID() + 1;
|
||||
}
|
||||
|
||||
printf("===================================== done. \n");
|
||||
printf("Number of Block Scanned : %u\n", numBlock);
|
||||
printf(" Number of Event Built : %lld\n", evID);
|
||||
printf(" Output Root File Size : %.2f MB\n", outRootFile->GetSize()/1024./1024.);
|
||||
printf(" first timestamp : %lu \n", firstTimeStamp);
|
||||
printf(" last timestamp : %lu \n", lastTimeStamp);
|
||||
unsigned long duration = lastTimeStamp - firstTimeStamp;
|
||||
printf(" total duration : %lu = %.2f sec \n", duration, duration * tick2ns * 1.0 / 1e9 );
|
||||
printf("===================================== end of summary. \n");
|
||||
|
||||
|
||||
//^############## delete new
|
||||
for( int i = 0; i < nFile; i++) delete reader[i];
|
||||
delete [] reader;
|
||||
outRootFile->Close();
|
||||
|
||||
return 0;
|
||||
}
|
20
Armory/EventBuilder.dSYM/Contents/Info.plist
Normal file
20
Armory/EventBuilder.dSYM/Contents/Info.plist
Normal file
|
@ -0,0 +1,20 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>English</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>com.apple.xcode.dsym.EventBuilder</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>dSYM</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.0</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1</string>
|
||||
</dict>
|
||||
</plist>
|
205
Armory/GeneralSort.C
Normal file
205
Armory/GeneralSort.C
Normal file
|
@ -0,0 +1,205 @@
|
|||
#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++){
|
||||
for( int j = 0; j < mapping::detNum[i]; j++){
|
||||
eE[i][j] = TMath::QuietNaN();
|
||||
eT[i][j] = 0;
|
||||
|
||||
if( isTraceExist && traceMethod > 0){
|
||||
teE[i][j] = TMath::QuietNaN();
|
||||
teT[i][j] = TMath::QuietNaN();
|
||||
teR[i][j] = TMath::QuietNaN();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
multi = 0;
|
||||
b_event_ID->GetEntry(entry);
|
||||
b_multi->GetEntry(entry);
|
||||
b_bd->GetEntry(entry);
|
||||
b_ch->GetEntry(entry);
|
||||
b_e->GetEntry(entry);
|
||||
b_e_t->GetEntry(entry);
|
||||
|
||||
for( int i = 0 ; i < multi; i++){
|
||||
int detID = mapping::map[bd[i]][ch[i]];
|
||||
int detType = mapping::FindDetTypeIndex(detID);
|
||||
int low = (i == 0 ? 0 : mapping::detMaxID[detType-1]);
|
||||
int reducedDetID = detID - low;
|
||||
|
||||
eE[detType][reducedDetID] = e[i] * mapping::detParity[detType];
|
||||
eT[detType][reducedDetID] = e_t[i];
|
||||
|
||||
}
|
||||
|
||||
//@===================================== Trace
|
||||
if( isTraceExist && traceMethod >= 0 ){
|
||||
|
||||
b_tl->GetEntry(entry);
|
||||
b_trace->GetEntry(entry);
|
||||
|
||||
int countTrace = 0;
|
||||
|
||||
arr->Clear("C");
|
||||
|
||||
for( int i = 0; i < multi; i++){
|
||||
int detID = mapping::map[bd[i]][ch[i]];
|
||||
|
||||
|
||||
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 == 1){
|
||||
|
||||
int detType = mapping::FindDetTypeIndex(detID);
|
||||
//TODO use a blackList
|
||||
//if( mapping::detTypeName[detType] != "rdt") continue;
|
||||
|
||||
//TODO try custom build fiting algorithm. May be faster?
|
||||
gFit = new TF1("gFit", fitFunc, 0, traceLength, numPara);
|
||||
gFit->SetLineColor(6);
|
||||
gFit->SetRange(0, traceLength);
|
||||
|
||||
gFit->SetParameter(0, e[i]);
|
||||
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 low = (i == 0 ? 0 : mapping::detMaxID[detType-1]);
|
||||
int reducedDetID = detID - low;
|
||||
|
||||
teE[detType][reducedDetID] = gFit->GetParameter(0);
|
||||
teT[detType][reducedDetID] = gFit->GetParameter(1);
|
||||
teR[detType][reducedDetID] = gFit->GetParameter(2);
|
||||
|
||||
delete gFit;
|
||||
gFit = nullptr;
|
||||
}
|
||||
|
||||
//***=================== Trapezoid filter
|
||||
if( traceMethod == 2){
|
||||
//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__);
|
||||
|
||||
DecodeOption();
|
||||
|
||||
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(){
|
||||
if( isParallel){
|
||||
printf("%s::SaveTree\n", __func__);
|
||||
saveFile->cd();
|
||||
newSaveTree->Write();
|
||||
fOutput->Add(proofFile);
|
||||
saveFile->Close();
|
||||
}
|
||||
|
||||
}
|
362
Armory/GeneralSort.h
Normal file
362
Armory/GeneralSort.h
Normal file
|
@ -0,0 +1,362 @@
|
|||
#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]);
|
||||
}
|
||||
|
||||
//^######################################### TRAPEZOID
|
||||
TGraph * TrapezoidFilter(TGraph * trace){
|
||||
///Trapezoid filter https://doi.org/10.1016/0168-9002(94)91652-7
|
||||
|
||||
//TODO how to not hard code?
|
||||
int baseLineEnd = 80;
|
||||
int riseTime = 10; //ch
|
||||
int flatTop = 20;
|
||||
float decayTime = 2000;
|
||||
|
||||
TGraph * trapezoid = new TGraph();
|
||||
trapezoid->Clear();
|
||||
|
||||
///find baseline;
|
||||
double baseline = 0;
|
||||
for( int i = 0; i < baseLineEnd; i++){
|
||||
baseline += trace->Eval(i);
|
||||
}
|
||||
baseline = baseline*1./baseLineEnd;
|
||||
|
||||
int length = trace->GetN();
|
||||
|
||||
double pn = 0.;
|
||||
double sn = 0.;
|
||||
for( int i = 0; i < length ; i++){
|
||||
|
||||
double dlk = trace->Eval(i) - baseline;
|
||||
if( i - riseTime >= 0 ) dlk -= trace->Eval(i - riseTime) - baseline;
|
||||
if( i - flatTop - riseTime >= 0 ) dlk -= trace->Eval(i - flatTop - riseTime) - baseline;
|
||||
if( i - flatTop - 2*riseTime >= 0) dlk += trace->Eval(i - flatTop - 2*riseTime) - baseline;
|
||||
|
||||
if( i == 0 ){
|
||||
pn = dlk;
|
||||
sn = pn + dlk*decayTime;
|
||||
}else{
|
||||
pn = pn + dlk;
|
||||
sn = sn + pn + dlk*decayTime;
|
||||
}
|
||||
trapezoid->SetPoint(i, i, sn / decayTime / riseTime);
|
||||
}
|
||||
return trapezoid;
|
||||
}
|
||||
|
||||
TStopwatch stpWatch;
|
||||
|
||||
//^######################################### Class definition
|
||||
// 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;
|
||||
Int_t multi;
|
||||
Int_t bd[100]; //[multi]
|
||||
Int_t ch[100]; //[multi]
|
||||
Int_t e[100]; //[multi]
|
||||
ULong64_t e_t[100]; //[multi]
|
||||
UShort_t lowFlag[100]; //[multi]
|
||||
UShort_t highFlag[100]; //[multi]
|
||||
Int_t tl[100]; //[multi]
|
||||
Int_t trace[100][2500]; //[multi]
|
||||
|
||||
// List of branches
|
||||
TBranch *b_event_ID; //!
|
||||
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; // -1 = ignore trace, 0 = no trace fit, 1 = fit, 2 = 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 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, "EventID/l"); // simply copy
|
||||
|
||||
eE = new Float_t * [mapping::nDetType];
|
||||
eT = new ULong64_t * [mapping::nDetType];
|
||||
|
||||
for( int i = 0 ; i < mapping::nDetType; i++){
|
||||
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_Timestamp[%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();
|
||||
|
||||
if( traceMethod > 0 ){
|
||||
|
||||
teE = new Float_t * [mapping::nDetType];
|
||||
teT = new Float_t * [mapping::nDetType];
|
||||
teR = new Float_t * [mapping::nDetType];
|
||||
|
||||
for( int i = 0 ; i < mapping::nDetType; i++){
|
||||
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]/l", mapping::detTypeName[i].c_str(), mapping::detNum[i]));
|
||||
newSaveTree->Branch( ("w" + mapping::detTypeName[i]+"R").c_str(), teR[i], Form("trace_%s_rise[%d]/l", mapping::detTypeName[i].c_str(), mapping::detNum[i]));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
newSaveTree->Print("toponly"); //very important, otherwise the mac will blow up.
|
||||
}
|
||||
|
||||
//^##############################################################
|
||||
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;
|
||||
}
|
||||
|
||||
printf("|%s| %d %s %d \n", option.Data(), traceMethod, saveFileName.Data(), isParallel);
|
||||
|
||||
}
|
||||
|
||||
//^##############################################################
|
||||
void GeneralSort::Init(TTree *tree){
|
||||
|
||||
// Set branch addresses and branch pointers
|
||||
if (!tree) return;
|
||||
fChain = tree;
|
||||
fChain->SetMakeClass(1);
|
||||
|
||||
fChain->SetBranchAddress("evID", &evID, &b_event_ID);
|
||||
fChain->SetBranchAddress("multi", &multi, &b_multi);
|
||||
fChain->SetBranchAddress("bd", bd, &b_bd);
|
||||
fChain->SetBranchAddress("ch", ch, &b_ch);
|
||||
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("tl");
|
||||
if( br == NULL ){
|
||||
printf(" ++++++++ no Trace.\n");
|
||||
isTraceExist = false;
|
||||
}else{
|
||||
printf(" ++++++++ Found Trace.\n");
|
||||
isTraceExist = true;
|
||||
fChain->SetBranchAddress("tl", tl, &b_tl);
|
||||
fChain->SetBranchAddress("trace", trace, &b_trace);
|
||||
}
|
||||
|
||||
NumEntries = fChain->GetEntries();
|
||||
printf( " ========== total Entry : %ld\n", NumEntries);
|
||||
|
||||
//########################### Get Option
|
||||
DecodeOption();
|
||||
|
||||
if( isTraceExist ){
|
||||
PrintTraceMethod();
|
||||
}else{
|
||||
printf("++++++++ no Trace found\n");
|
||||
}
|
||||
|
||||
SetUpTree();
|
||||
|
||||
printf("---- end of Init %s\n ", __func__);
|
||||
|
||||
}
|
||||
|
||||
Bool_t GeneralSort::Notify(){
|
||||
return kTRUE;
|
||||
}
|
||||
|
||||
void GeneralSort::PrintTraceMethod(){
|
||||
const char* traceMethodStr;
|
||||
switch(traceMethod) {
|
||||
case -1 : traceMethodStr = "Ignore Trace"; break;
|
||||
case 0 : traceMethodStr = "Copy"; break;
|
||||
case 1 : traceMethodStr = "Fit"; break;
|
||||
case 2 : traceMethodStr = "Trapezoid"; break;
|
||||
default: traceMethodStr = "Unknown"; break;
|
||||
}
|
||||
printf("\033[1;33m ===== Trace method ? %s \033[m\n", traceMethodStr);
|
||||
}
|
||||
|
||||
#endif // #ifdef GeneralSort_cxx
|
56
Armory/GeneralSortAgent.C
Normal file
56
Armory/GeneralSortAgent.C
Normal file
|
@ -0,0 +1,56 @@
|
|||
|
||||
#include "TTree.h"
|
||||
#include "TProof.h"
|
||||
#include "TChain.h"
|
||||
#include "TMacro.h"
|
||||
#include "TFile.h"
|
||||
|
||||
void GeneralSortAgent(Int_t runNum, int nWorker = 1, int traceMethod = -1){
|
||||
|
||||
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;
|
||||
|
||||
}
|
287
Armory/Hit.h
Normal file
287
Armory/Hit.h
Normal file
|
@ -0,0 +1,287 @@
|
|||
#ifndef HIT_H
|
||||
#define HIT_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <cstdlib>
|
||||
#include <stdint.h>
|
||||
#include <string>
|
||||
|
||||
#define MaxTraceLenght 8100
|
||||
|
||||
enum DataFormat{
|
||||
|
||||
ALL = 0x00,
|
||||
OneTrace = 0x01,
|
||||
NoTrace = 0x02,
|
||||
Minimum = 0x03,
|
||||
MiniWithFineTime = 0x04,
|
||||
Raw = 0x0A,
|
||||
|
||||
};
|
||||
|
||||
namespace DPPType{
|
||||
|
||||
const std::string PHA = "DPP_PHA";
|
||||
const std::string PSD = "DPP_PSD";
|
||||
|
||||
};
|
||||
|
||||
class Hit {
|
||||
public:
|
||||
|
||||
unsigned short dataType;
|
||||
std::string DPPType;
|
||||
|
||||
///============= for dpp-pha
|
||||
uint8_t channel; // 6 bit
|
||||
uint16_t energy; // 16 bit
|
||||
uint16_t energy_short; // 16 bit, only for PSD
|
||||
uint64_t timestamp; // 48 bit
|
||||
uint16_t fine_timestamp; // 10 bit
|
||||
uint16_t flags_low_priority; // 12 bit
|
||||
uint16_t flags_high_priority; // 8 bit
|
||||
size_t traceLenght; // 64 bit
|
||||
uint8_t downSampling; // 8 bit
|
||||
bool board_fail;
|
||||
bool flush;
|
||||
uint8_t analog_probes_type[2]; // 3 bit for PHA, 4 bit for PSD
|
||||
uint8_t digital_probes_type[4]; // 4 bit for PHA, 5 bit for PSD
|
||||
int32_t * analog_probes[2]; // 18 bit
|
||||
uint8_t * digital_probes[4]; // 1 bit
|
||||
uint16_t trigger_threashold; // 16 bit
|
||||
size_t event_size; // 64 bit
|
||||
uint32_t aggCounter; // 32 bit
|
||||
|
||||
///============= for raw
|
||||
uint8_t * data;
|
||||
size_t dataSize; /// number of byte of the data, size/8 = word [64 bits]
|
||||
uint32_t n_events;
|
||||
|
||||
bool isTraceAllZero;
|
||||
|
||||
Hit(){
|
||||
Init();
|
||||
}
|
||||
|
||||
~Hit(){
|
||||
ClearMemory();
|
||||
}
|
||||
|
||||
void Init(){
|
||||
DPPType = DPPType::PHA;
|
||||
dataType = DataFormat::ALL;
|
||||
|
||||
channel = 0;
|
||||
energy = 0;
|
||||
energy_short = 0;
|
||||
timestamp = 0;
|
||||
fine_timestamp = 0;
|
||||
downSampling = 0;
|
||||
board_fail = false;
|
||||
flush = false;
|
||||
flags_low_priority = 0;
|
||||
flags_high_priority = 0;
|
||||
trigger_threashold = 0;
|
||||
event_size = 0;
|
||||
aggCounter = 0;
|
||||
analog_probes[0] = NULL;
|
||||
analog_probes[1] = NULL;
|
||||
digital_probes[0] = NULL;
|
||||
digital_probes[1] = NULL;
|
||||
digital_probes[2] = NULL;
|
||||
digital_probes[3] = NULL;
|
||||
|
||||
analog_probes_type[0] = 0xFF;
|
||||
analog_probes_type[1] = 0xFF;
|
||||
digital_probes_type[0] = 0xFF;
|
||||
digital_probes_type[1] = 0xFF;
|
||||
digital_probes_type[2] = 0xFF;
|
||||
digital_probes_type[3] = 0xFF;
|
||||
data = NULL;
|
||||
|
||||
isTraceAllZero = true; // indicate trace are all zero
|
||||
}
|
||||
|
||||
void ClearMemory(){
|
||||
if( data != NULL ) delete data;
|
||||
|
||||
if( analog_probes[0] != NULL) delete analog_probes[0];
|
||||
if( analog_probes[1] != NULL) delete analog_probes[1];
|
||||
|
||||
if( digital_probes[0] != NULL) delete digital_probes[0];
|
||||
if( digital_probes[1] != NULL) delete digital_probes[1];
|
||||
if( digital_probes[2] != NULL) delete digital_probes[2];
|
||||
if( digital_probes[3] != NULL) delete digital_probes[3];
|
||||
|
||||
isTraceAllZero = true;
|
||||
}
|
||||
|
||||
void SetDataType(unsigned int type, std::string dppType){
|
||||
dataType = type;
|
||||
DPPType = dppType;
|
||||
ClearMemory();
|
||||
|
||||
if( dataType == DataFormat::Raw){
|
||||
data = new uint8_t[20*1024*1024];
|
||||
}else{
|
||||
analog_probes[0] = new int32_t[MaxTraceLenght];
|
||||
analog_probes[1] = new int32_t[MaxTraceLenght];
|
||||
|
||||
digital_probes[0] = new uint8_t[MaxTraceLenght];
|
||||
digital_probes[1] = new uint8_t[MaxTraceLenght];
|
||||
digital_probes[2] = new uint8_t[MaxTraceLenght];
|
||||
digital_probes[3] = new uint8_t[MaxTraceLenght];
|
||||
|
||||
isTraceAllZero = true;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void ClearTrace(){
|
||||
if( isTraceAllZero ) return; // no need to clear again
|
||||
|
||||
for( int i = 0; i < MaxTraceLenght; i++){
|
||||
analog_probes[0][i] = 0;
|
||||
analog_probes[1][i] = 0;
|
||||
|
||||
digital_probes[0][i] = 0;
|
||||
digital_probes[1][i] = 0;
|
||||
digital_probes[2][i] = 0;
|
||||
digital_probes[3][i] = 0;
|
||||
}
|
||||
isTraceAllZero = true;
|
||||
}
|
||||
|
||||
void PrintEnergyTimeStamp(){
|
||||
printf("ch: %2d, energy: %u, timestamp: %lu ch, traceLenght: %lu\n", channel, energy, timestamp, traceLenght);
|
||||
}
|
||||
|
||||
std::string AnaProbeType(uint8_t probeType){
|
||||
|
||||
if( DPPType == DPPType::PHA){
|
||||
switch(probeType){
|
||||
case 0: return "ADC";
|
||||
case 1: return "Time filter";
|
||||
case 2: return "Energy filter";
|
||||
default : return "none";
|
||||
}
|
||||
}else if (DPPType == DPPType::PSD){
|
||||
switch(probeType){
|
||||
case 0: return "ADC";
|
||||
case 9: return "Baseline";
|
||||
case 10: return "CFD";
|
||||
default : return "none";
|
||||
}
|
||||
}else{
|
||||
return "none";
|
||||
}
|
||||
}
|
||||
|
||||
std::string DigiProbeType(uint8_t probeType){
|
||||
|
||||
if( DPPType == DPPType::PHA){
|
||||
switch(probeType){
|
||||
case 0: return "Trigger";
|
||||
case 1: return "Time filter armed";
|
||||
case 2: return "Re-trigger guard";
|
||||
case 3: return "Energy filter baseline freeze";
|
||||
case 4: return "Energy filter peaking";
|
||||
case 5: return "Energy filter peaking ready";
|
||||
case 6: return "Energy filter pile-up guard";
|
||||
case 7: return "Event pile-up";
|
||||
case 8: return "ADC saturation";
|
||||
case 9: return "ADC saturation protection";
|
||||
case 10: return "Post-saturation event";
|
||||
case 11: return "Energy filter saturation";
|
||||
case 12: return "Signal inhibit";
|
||||
default : return "none";
|
||||
}
|
||||
}else if (DPPType == DPPType::PSD){
|
||||
switch(probeType){
|
||||
case 0: return "Trigger";
|
||||
case 1: return "CFD Filter Armed";
|
||||
case 2: return "Re-trigger guard";
|
||||
case 3: return "ADC Input Baseline freeze";
|
||||
case 20: return "ADC Input OverThreshold";
|
||||
case 21: return "Charge Ready";
|
||||
case 22: return "Long Gate";
|
||||
case 7: return "Pile-Up Trig.";
|
||||
case 24: return "Short Gate";
|
||||
case 25: return "Energy Saturation";
|
||||
case 26: return "Charge over-range";
|
||||
case 27: return "ADC Input Neg. OverThreshold";
|
||||
default : return "none";
|
||||
}
|
||||
|
||||
}else{
|
||||
return "none";
|
||||
}
|
||||
}
|
||||
|
||||
std::string HighPriority(uint16_t prio){
|
||||
std::string output;
|
||||
|
||||
bool pileup = prio & 0x1;
|
||||
//bool pileupGuard = (prio >> 1) & 0x1;
|
||||
//bool eventSaturated = (prio >> 2) & 0x1;
|
||||
//bool postSatEvent = (prio >> 3) & 0x1;
|
||||
//bool trapSatEvent = (prio >> 4) & 0x1;
|
||||
//bool SCA_Event = (prio >> 5) & 0x1;
|
||||
|
||||
output = std::string("Pile-up: ") + (pileup ? "Yes" : "No");
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
//TODO LowPriority
|
||||
|
||||
void PrintAll(){
|
||||
|
||||
switch(dataType){
|
||||
case DataFormat::ALL : printf("============= Type : ALL\n"); break;
|
||||
case DataFormat::OneTrace : printf("============= Type : OneTrace\n"); break;
|
||||
case DataFormat::NoTrace : printf("============= Type : NoTrace\n"); break;
|
||||
case DataFormat::MiniWithFineTime : printf("============= Type : Min with FineTimestamp\n"); break;
|
||||
case DataFormat::Minimum : printf("============= Type : Minimum\n"); break;
|
||||
case DataFormat::Raw : printf("============= Type : Raw\n"); return; break;
|
||||
default : return;
|
||||
}
|
||||
|
||||
printf("ch : %2d (0x%02X), fail: %d, flush: %d\n", channel, channel, board_fail, flush);
|
||||
if( DPPType == DPPType::PHA ) printf("energy: %u, timestamp: %lu, fine_timestamp: %u \n", energy, timestamp, fine_timestamp);
|
||||
if( DPPType == DPPType::PSD ) printf("energy: %u, energy_S : %u, timestamp: %lu, fine_timestamp: %u \n", energy, energy_short, timestamp, fine_timestamp);
|
||||
printf("flag (high): 0x%02X, (low): 0x%03X, traceLength: %lu\n", flags_high_priority, flags_low_priority, traceLenght);
|
||||
printf("Agg counter : %u, trigger Thr.: %u, downSampling: %u \n", aggCounter, trigger_threashold, downSampling);
|
||||
printf("AnaProbe Type: %s(%u), %s(%u)\n", AnaProbeType(analog_probes_type[0]).c_str(), analog_probes_type[0],
|
||||
AnaProbeType(analog_probes_type[1]).c_str(), analog_probes_type[1]);
|
||||
printf("DigProbe Type: %s(%u), %s(%u), %s(%u), %s(%u)\n", DigiProbeType(digital_probes_type[0]).c_str(), digital_probes_type[0],
|
||||
DigiProbeType(digital_probes_type[1]).c_str(), digital_probes_type[1],
|
||||
DigiProbeType(digital_probes_type[2]).c_str(), digital_probes_type[2],
|
||||
DigiProbeType(digital_probes_type[3]).c_str(), digital_probes_type[3]);
|
||||
}
|
||||
|
||||
void PrintTrace(unsigned short ID){
|
||||
for(unsigned short i = 0; i < (unsigned short)traceLenght; i++){
|
||||
if( ID == 0 ) printf("%4d| %6d\n", i, analog_probes[0][i]);
|
||||
if( ID == 1 ) printf("%4d| %6d\n", i, analog_probes[1][i]);
|
||||
if( ID == 2 ) printf("%4d| %u\n", i, digital_probes[0][i]);
|
||||
if( ID == 3 ) printf("%4d| %u\n", i, digital_probes[1][i]);
|
||||
if( ID == 4 ) printf("%4d| %u\n", i, digital_probes[2][i]);
|
||||
if( ID == 5 ) printf("%4d| %u\n", i, digital_probes[3][i]);
|
||||
}
|
||||
}
|
||||
|
||||
void PrintAllTrace(){
|
||||
for(unsigned short i = 0; i < (unsigned short)traceLenght; i++){
|
||||
printf("%4d| %6d %6d %1d %1d %1d %1d\n", i, analog_probes[0][i],
|
||||
analog_probes[1][i],
|
||||
digital_probes[0][i],
|
||||
digital_probes[1][i],
|
||||
digital_probes[2][i],
|
||||
digital_probes[3][i]);
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
#endif
|
12
Armory/Makefile
Normal file
12
Armory/Makefile
Normal file
|
@ -0,0 +1,12 @@
|
|||
CC=g++
|
||||
CFLAG= -g
|
||||
ROOTFLAG=`root-config --cflags --glibs`
|
||||
|
||||
all: EventBuilder
|
||||
|
||||
EventBuilder: EventBuilder.cpp SolReader.h Hit.h
|
||||
$(CC) $(CFLAG) EventBuilder.cpp -o EventBuilder ${ROOTFLAG}
|
||||
|
||||
|
||||
clean:
|
||||
-rm EventBuilder
|
359
Armory/Monitor_Util.C
Normal file
359
Armory/Monitor_Util.C
Normal file
|
@ -0,0 +1,359 @@
|
|||
#ifndef Utilities
|
||||
#define Utilities
|
||||
|
||||
#include <TMath.h>
|
||||
#include <TCanvas.h>
|
||||
|
||||
//This file runs after on Monitor.C
|
||||
//This file is parasite on Monitor.C
|
||||
|
||||
int canvasSize[2] = {2000, 1200};
|
||||
|
||||
void listDraws(void) {
|
||||
printf("------------------- List of Plots -------------------\n");
|
||||
printf(" newCanvas() - Create a new Canvas\n");
|
||||
printf("-----------------------------------------------------\n");
|
||||
printf(" rawID() - Raw \033[0;31me\033[0m, \033[0;31mring\033[0m, \033[0;31mxf\033[0m, \033[0;31mxn\033[0m vs detID\n");
|
||||
printf(" rawe() - Raw \033[0;31me\033[0m for all %d detectors\n", numDet);
|
||||
printf(" rawxf() - Raw \033[0;31mxf\033[0m for all %d detectors\n", numDet);
|
||||
printf(" rawxn() - Raw \033[0;31mxn\033[0m for all %d detectors\n", numDet);
|
||||
printf(" rawxfVxn() - Raw \033[0;31mxf\033[0m vs. \033[0;31mxn\033[0m for all %d detectors\n", numDet);
|
||||
printf(" raweVxs() - Raw \033[0;31me\033[0m vs. Raw \033[0;31mxs = xf + xn\033[0m for all %d detectors\n", numDet);
|
||||
printf(" raweVx() - Raw \033[0;31me\033[0m vs. RAW \033[0;31mx\033[0m for all %d detectors\n", numDet);
|
||||
printf("-----------------------------------------------------\n");
|
||||
printf(" eVxsCal() - Raw \033[0;31me\033[0m vs. Corrected \033[0;31mxs\033[0m for all %d detectors\n", numDet);
|
||||
printf(" ecal() - Calibrated \033[0;31me\033[0m for all %d detectors\n", numDet);
|
||||
printf("xfCalVxnCal() - Calibrated \033[0;31mxf\033[0m vs. \033[0;31mxn\033[0m for all %d detectors\n", numDet);
|
||||
printf(" eCalVxCal() - Cal \033[0;31me\033[0m vs. \033[0;31mx\033[0m for all %d detectors\n", numDet);
|
||||
printf("-----------------------------------------------------\n");
|
||||
printf(" recoils() - Raw DE vs. E Recoil spectra\n");
|
||||
//printf(" elum() - Luminosity Energy Spectra\n");
|
||||
//printf(" ic() - Ionization Chamber Spectra\n");
|
||||
printf("-----------------------------------------------------\n");
|
||||
printf(" eCalVz() - Energy vs. Z\n");
|
||||
printf(" eCalVzRow() - Energy vs. Z for each row\n");
|
||||
printf(" excite() - Excitation Energy\n");
|
||||
printf(" ExThetaCM() - Ex vs ThetaCM\n");
|
||||
printf(" ExVxCal() - Ex vs X for all %d detectors\n", numDet);
|
||||
printf("-----------------------------------------------------\n");
|
||||
printf(" ShowFitMethod() - Shows various fitting methods \n");
|
||||
printf(" RDTCutCreator() - Create RDT Cuts [May need to edit]\n");
|
||||
printf(" Check_rdtGate() - Check RDT Cuts. \n");
|
||||
printf(" readTrace() - read trace from gen_runXXX.root \n");
|
||||
printf(" readRawTrace() - read trace from runXXX.root \n");
|
||||
printf(" Check1D() - Count Integral within a range\n");
|
||||
printf("-----------------------------------------------------\n");
|
||||
printf(" %s\n", canvasTitle.Data());
|
||||
printf("-----------------------------------------------------\n");
|
||||
}
|
||||
|
||||
int xD, yD;
|
||||
void FindBesCanvasDivision(int nPad){
|
||||
for( int i = TMath::Sqrt(nPad); i >= 2 ; i--){
|
||||
if( nPad % i == 0 ) {
|
||||
yD = i;
|
||||
xD = nPad/i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int nCanvas=0;
|
||||
void newCanvas(int sizeX = 800, int sizeY = 600, int posX = 0, int posY = 0){
|
||||
TString name; name.Form("cNewCanvas%d | %s", nCanvas, canvasTitle.Data());
|
||||
TCanvas * cNewCanvas = new TCanvas(name, name, posX, posY, sizeX, sizeY);
|
||||
nCanvas++;
|
||||
cNewCanvas->cd();
|
||||
}
|
||||
|
||||
void rawID(){
|
||||
TCanvas * cRawID = (TCanvas *) gROOT->FindObjectAny("cRawID");
|
||||
if( cRawID == NULL ) cRawID = new TCanvas("cRawID", Form("Raw e, Ring, xf, xn vs ID | %s", canvasTitle.Data()), canvasSize[0], canvasSize[1]);
|
||||
cRawID->Clear();cRawID->Divide(2,2);
|
||||
cRawID->cd(1); cRawID->cd(1)->SetGrid(); heVID->Draw("colz");
|
||||
cRawID->cd(2); cRawID->cd(2)->SetGrid(); hMultiHit->Draw();
|
||||
cRawID->cd(3); cRawID->cd(3)->SetGrid(); hxfVID->Draw("colz");
|
||||
cRawID->cd(4); cRawID->cd(4)->SetGrid(); hxnVID->Draw("colz");
|
||||
}
|
||||
|
||||
void rawe(Bool_t isLogy = false) {
|
||||
TCanvas *cRawE = (TCanvas *) gROOT->FindObjectAny("cRawE");
|
||||
if( cRawE == NULL ) cRawE = new TCanvas("cRawE",Form("E raw | %s", canvasTitle.Data()),canvasSize[0], canvasSize[1]);
|
||||
cRawE->Clear();cRawE->Divide(numCol,numRow);
|
||||
for (Int_t i=0; i < numDet; i++) {
|
||||
cRawE->cd(i+1);
|
||||
cRawE->cd(i+1)->SetGrid();
|
||||
if( isLogy ) cRawE->cd(i+1)->SetLogy();
|
||||
he[i]->Draw("");
|
||||
}
|
||||
}
|
||||
|
||||
void rawxf(Bool_t isLogy = false) {
|
||||
TCanvas *cRawXf = (TCanvas *) gROOT->FindObjectAny("cRawXf");
|
||||
if( cRawXf == NULL ) cRawXf = new TCanvas("cRawXf",Form("Xf raw | %s", canvasTitle.Data()),canvasSize[0], canvasSize[1]);
|
||||
cRawXf->Clear();cRawXf->Divide(numCol,numRow);
|
||||
for (Int_t i=0; i<numDet; i++) {
|
||||
cRawXf->cd(i+1);
|
||||
cRawXf->cd(i+1)->SetGrid();
|
||||
if( isLogy ) cRawXf->cd(i+1)->SetLogy();
|
||||
hxf[i]->Draw("");
|
||||
}
|
||||
}
|
||||
|
||||
void rawxn(Bool_t isLogy = false) {
|
||||
TCanvas *cRawXn = (TCanvas *) gROOT->FindObjectAny("cRawXn");
|
||||
if( cRawXn == NULL ) cRawXn = new TCanvas("cRawXn",Form("Xn raw | %s", canvasTitle.Data()),canvasSize[0], canvasSize[1]);
|
||||
cRawXn->Clear();cRawXn->Divide(numCol,numRow);
|
||||
for (Int_t i=0; i<numDet; i++) {
|
||||
cRawXn->cd(i+1);
|
||||
cRawXn->cd(i+1)->SetGrid();
|
||||
if( isLogy ) cRawXn->cd(i+1)->SetLogy();
|
||||
hxn[i]->Draw("");
|
||||
}
|
||||
}
|
||||
|
||||
void rawxfVxn(void) {
|
||||
TCanvas *cxfxn = (TCanvas *) gROOT->FindObjectAny("cxfxn");
|
||||
if( cxfxn == NULL ) cxfxn = new TCanvas("cxfxn",Form("XF vs. XN | %s", canvasTitle.Data()),canvasSize[0], canvasSize[1]);
|
||||
cxfxn->Clear(); cxfxn->Divide(numCol,numRow);
|
||||
for (Int_t i=0;i<numDet;i++) {
|
||||
cxfxn->cd(i+1);
|
||||
cxfxn->cd(i+1)->SetGrid();
|
||||
hxfVxn[i]->Draw("col");
|
||||
}
|
||||
}
|
||||
|
||||
void raweVxs(void) {
|
||||
TCanvas *cxfxne = (TCanvas *) gROOT->FindObjectAny("cxfxne");
|
||||
if( cxfxne == NULL ) cxfxne = new TCanvas("cxfxne",Form("E - XF+XN | %s", canvasTitle.Data()),canvasSize[0], canvasSize[1]);
|
||||
cxfxne->Clear(); cxfxne->Divide(numCol,numRow);
|
||||
TLine line(0,0, 4000, 4000); line.SetLineColor(2);
|
||||
for (Int_t i=0;i<numDet;i++) {
|
||||
cxfxne->cd(i+1);
|
||||
cxfxne->cd(i+1)->SetGrid();
|
||||
heVxs[i]->Draw("col");
|
||||
line.Draw("same");
|
||||
}
|
||||
}
|
||||
|
||||
void raweVx(void) {
|
||||
TCanvas *ceVx = (TCanvas *) gROOT->FindObjectAny("ceVx");
|
||||
if(ceVx == NULL) ceVx = new TCanvas("ceVx",Form("E vs. X = (xf-xn)/e | %s", canvasTitle.Data()),canvasSize[0], canvasSize[1]);
|
||||
ceVx->Clear(); ceVx->Divide(numCol,numRow);
|
||||
for (Int_t i=0;i<numDet;i++) {
|
||||
ceVx->cd(i+1); heVx[i]->Draw("col");
|
||||
}
|
||||
}
|
||||
|
||||
void eVxsCal(void) {
|
||||
TCanvas *cxfxneC = (TCanvas *) gROOT->FindObjectAny("cxfxneC");
|
||||
if(cxfxneC == NULL)cxfxneC = new TCanvas("cxfxneC",Form("Raw E - Corrected XF+XN | %s", canvasTitle.Data()),canvasSize[0], canvasSize[1]);
|
||||
cxfxneC->Clear(); cxfxneC->Divide(numCol,numRow);
|
||||
TLine line(0,0, 4000, 4000); line.SetLineColor(2);
|
||||
for (Int_t i=0;i<numDet;i++) {
|
||||
cxfxneC->cd(i+1);
|
||||
cxfxneC->cd(i+1)->SetGrid();
|
||||
heVxsCal[i]->Draw("col");
|
||||
line.Draw("same");
|
||||
}
|
||||
}
|
||||
|
||||
void ecal(void) {
|
||||
TCanvas *cEC = (TCanvas *) gROOT->FindObjectAny("cEC");
|
||||
if(cEC == NULL) cEC = new TCanvas("cEC",Form("E corrected | %s", canvasTitle.Data()),canvasSize[0], canvasSize[1]);
|
||||
cEC->Clear();cEC->Divide(numCol,numRow);
|
||||
for (Int_t i=0; i<numDet; i++) {
|
||||
cEC->cd(i+1);
|
||||
cEC->cd(i+1)->SetGrid();
|
||||
heCal[i]->Draw("");
|
||||
}
|
||||
|
||||
TCanvas *cEC2 = (TCanvas *) gROOT->FindObjectAny("cEC2");
|
||||
if(cEC2 == NULL) cEC2 = new TCanvas("cEC2",Form("E corrected | %s", canvasTitle.Data()),canvasSize[0], canvasSize[1]);
|
||||
cEC2->Clear();
|
||||
heCalID->Draw("colz");
|
||||
}
|
||||
|
||||
void xfCalVxnCal(void) {
|
||||
TCanvas *cxfxnC = (TCanvas *) gROOT->FindObjectAny("cxfxnC");
|
||||
if(cxfxnC == NULL) cxfxnC = new TCanvas("cxfxnC",Form("XF vs XN corrected | %s", canvasTitle.Data()),canvasSize[0], canvasSize[1]);
|
||||
cxfxnC->Clear(); cxfxnC->Divide(numCol,numRow);
|
||||
for (Int_t i=0;i<numDet;i++) {
|
||||
cxfxnC->cd(i+1);
|
||||
cxfxnC->cd(i+1)->SetGrid();
|
||||
hxfCalVxnCal[i]->Draw("col");
|
||||
}
|
||||
}
|
||||
|
||||
void eCalVxCal(void) {
|
||||
TCanvas *cecalVxcal = (TCanvas *) gROOT->FindObjectAny("cecalVxcal");
|
||||
if( cecalVxcal == NULL ) cecalVxcal = new TCanvas("cecalVxcal",Form("ECALVXCAL | %s",canvasTitle.Data()),canvasSize[0], canvasSize[1]);
|
||||
cecalVxcal->Clear(); cecalVxcal->Divide(numCol,numRow);
|
||||
for (Int_t i=0;i<numDet;i++) {
|
||||
cecalVxcal->cd(i+1);
|
||||
heCalVxCal[i]->SetMarkerStyle(7);
|
||||
heCalVxCal[i]->Draw("");
|
||||
}
|
||||
}
|
||||
|
||||
void recoils(bool isLogz = false) {
|
||||
TCanvas *crdt = (TCanvas *) gROOT->FindObjectAny("crdt");
|
||||
if( crdt == NULL ) crdt = new TCanvas("crdt",Form("raw RDT | %s", canvasTitle.Data()),1700, 0, 1000,1000);
|
||||
crdt->Clear();crdt->Divide(2,2);
|
||||
|
||||
if( isLogz ) crdt->cd(1)->SetLogz(); crdt->cd(1); hrdt2D[0]->Draw("col");
|
||||
if( isLogz ) crdt->cd(2)->SetLogz(); crdt->cd(2); hrdt2D[1]->Draw("col");
|
||||
if( isLogz ) crdt->cd(3)->SetLogz(); crdt->cd(3); hrdt2D[3]->Draw("col");
|
||||
if( isLogz ) crdt->cd(4)->SetLogz(); crdt->cd(4); hrdt2D[2]->Draw("col");
|
||||
|
||||
TCanvas *crdtID = (TCanvas *) gROOT->FindObjectAny("crdtID");
|
||||
if( crdtID == NULL ) crdtID = new TCanvas("crdtID",Form("raw RDT ID | %s", canvasTitle.Data()),0,0, 500, 500);
|
||||
crdtID->Clear();
|
||||
if( isLogz ) crdtID->SetLogz();
|
||||
hrdtID->Draw("colz");
|
||||
|
||||
TCanvas *crdtS = (TCanvas *) gROOT->FindObjectAny("crdtS");
|
||||
if( crdtS == NULL ) crdtS = new TCanvas("crdtS",Form("raw RDT | %s", canvasTitle.Data()),600, 0, 1000, 1000);
|
||||
crdtS->Clear(); crdtS->Divide(2,4);
|
||||
for( int i = 0; i < 8; i ++){
|
||||
crdtS->cd(i+1);
|
||||
if( isLogz ) crdtS->cd(i+1)->SetLogy();
|
||||
hrdt[i]->Draw("");
|
||||
}
|
||||
}
|
||||
|
||||
// void elum(void) {
|
||||
// TCanvas *celum = (TCanvas *) gROOT->FindObjectAny("celum");
|
||||
// if( celum == NULL ) celum = new TCanvas("celum",Form("ELUM | %s", canvasTitle.Data()),1000,1000);
|
||||
// celum->Clear(); celum->Divide(4,4);
|
||||
// for( int i = 0 ; i < 16 ; i++){
|
||||
// celum->cd(i+1);
|
||||
// helum[i]->Draw("");
|
||||
// }
|
||||
|
||||
// TCanvas *celumID = (TCanvas *) gROOT->FindObjectAny("celumID");
|
||||
// if( celumID == NULL ) celumID = new TCanvas("celumID",Form("ELUM-ID | %s", canvasTitle.Data()),1100, 0, 500,500);
|
||||
// celumID->Clear();
|
||||
// helumID->Draw("colz");
|
||||
|
||||
// }
|
||||
|
||||
|
||||
// void ic(){
|
||||
// TCanvas *cic = (TCanvas *) gROOT->FindObjectAny("cic");
|
||||
// if( cic == NULL ) cic = new TCanvas("cic",Form("Ionization Chamber | %s", canvasTitle.Data() ),1200,800);
|
||||
|
||||
// cic->Clear(); cic->SetGrid(0); cic->Divide(3,2);
|
||||
// gStyle->SetOptStat("neiou");
|
||||
|
||||
// cic->cd(1); hic0->Draw();
|
||||
// cic->cd(2); hic1->Draw();
|
||||
// cic->cd(3); hic2->Draw();
|
||||
// cic->cd(4); hic01->Draw("colz");
|
||||
// cic->cd(5); hic02->Draw("colz");
|
||||
// cic->cd(6); hic12->Draw("colz");
|
||||
// }
|
||||
|
||||
void eCalVz(void) {
|
||||
TCanvas *cecalVz = (TCanvas *) gROOT->FindObjectAny("cecalVz");
|
||||
if( cecalVz == NULL ) cecalVz = new TCanvas("cevalVz",Form("ECALVZ : %s", canvasTitle.Data()),1000,650);
|
||||
cecalVz->Clear(); cecalVz->Divide(2,1);
|
||||
gStyle->SetOptStat("neiou");
|
||||
cecalVz->cd(1);heCalVz->Draw("col");
|
||||
cecalVz->cd(2);heCalVzGC->Draw("col");
|
||||
}
|
||||
|
||||
void eCalVzRow() {
|
||||
TCanvas *cecalVzRow = (TCanvas *) gROOT->FindObjectAny("cecalVzRow");
|
||||
if( cecalVzRow == NULL ) cecalVzRow = new TCanvas("cevalVzRow",Form("eCal - Z : %s", canvasTitle.Data()),canvasSize[0], canvasSize[1]);
|
||||
FindBesCanvasDivision(numRow);
|
||||
cecalVzRow->Clear(); cecalVzRow->Divide(xD,yD);
|
||||
gStyle->SetOptStat("neiou");
|
||||
|
||||
for(int row = 0; row < numRow; row ++){
|
||||
cecalVzRow->cd(row+1);
|
||||
cecalVzRow->cd(row+1)->SetGrid();
|
||||
hecalVzRow[row]->Draw("colz");
|
||||
}
|
||||
}
|
||||
|
||||
void excite(void) {
|
||||
TCanvas *cex = (TCanvas *) gROOT->FindObjectAny("cex");
|
||||
if( cex == NULL ) cex = new TCanvas("cex",Form("EX : %s", canvasTitle.Data()),0, 0, 1000,650);
|
||||
cex->Clear();
|
||||
gStyle->SetOptStat("neiou");
|
||||
hEx->Draw("");
|
||||
|
||||
|
||||
TCanvas *cexI = (TCanvas *) gROOT->FindObjectAny("cexI");
|
||||
if( cexI == NULL ) cexI = new TCanvas("cexI",Form("EX : %s", canvasTitle.Data()),500, 0, 1600,1000);
|
||||
cexI->Clear();cexI->Divide(numCol,numRow);
|
||||
gStyle->SetOptStat("neiou");
|
||||
for( int i = 0; i < numDet; i++){
|
||||
cexI->cd(i+1);
|
||||
hExi[i]->Draw("");
|
||||
}
|
||||
}
|
||||
|
||||
void ExThetaCM(void) {
|
||||
TCanvas *cExThetaCM = (TCanvas *) gROOT->FindObjectAny("cExThetaCM");
|
||||
if( cExThetaCM == NULL ) cExThetaCM = new TCanvas("cExThetaCM",Form("EX - ThetaCM | %s", canvasTitle.Data()),650,650);
|
||||
cExThetaCM->Clear();
|
||||
gStyle->SetOptStat("neiou");
|
||||
hExThetaCM->Draw("colz");
|
||||
}
|
||||
|
||||
void ExVxCal(TString drawOpt = "") {
|
||||
TCanvas *cExVxCal = (TCanvas *) gROOT->FindObjectAny("cExVxCal");
|
||||
if( cExVxCal == NULL ) cExVxCal = new TCanvas("cExVxCal",Form("EX | %s", canvasTitle.Data()),1600,1000);
|
||||
cExVxCal->Clear();
|
||||
gStyle->SetOptStat("neiou");
|
||||
|
||||
cExVxCal->Divide(numCol,numRow);
|
||||
for( int i = 0; i < numDet; i++){
|
||||
cExVxCal->cd(i+1);
|
||||
if( drawOpt == "" )hExVxCal[i]->SetMarkerStyle(7);
|
||||
hExVxCal[i]->Draw(drawOpt);
|
||||
}
|
||||
}
|
||||
|
||||
void Count1DH(TString name, TH1F * hist, TCanvas * canvas, int padID, double x1, double x2, Color_t color){
|
||||
|
||||
int k1 = hist->FindBin(x1);
|
||||
int k2 = hist->FindBin(x2);
|
||||
|
||||
int hight = 0 ;
|
||||
for( int i = k1; i < k2 ; i ++){
|
||||
int temp = hist->GetBinContent(i);
|
||||
if( temp > hight ) hight = temp;
|
||||
}
|
||||
hight = hight * 1.2;
|
||||
int max = hist->GetMaximum();
|
||||
|
||||
canvas->cd(padID);
|
||||
|
||||
if( color != 0 ){
|
||||
TBox box;
|
||||
box.SetFillColorAlpha(color, 0.1);
|
||||
box.DrawBox(x1, 0, x2, hight);
|
||||
}
|
||||
|
||||
int count = hist->Integral(k1, k2);
|
||||
|
||||
TLatex text;
|
||||
text.SetTextFont(82);
|
||||
text.SetTextSize(0.06);
|
||||
if( color != 0 ){
|
||||
text.SetTextColor(color);
|
||||
text.DrawLatex(x1, hight, Form("%d", count));
|
||||
}else{
|
||||
text.DrawLatex((x1+x2)/2., max, Form("%d", count));
|
||||
}
|
||||
|
||||
printf(" %s : %d \n", name.Data(), count);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif
|
306
Armory/Parameters.h
Normal file
306
Armory/Parameters.h
Normal file
|
@ -0,0 +1,306 @@
|
|||
#ifndef Parameters_H
|
||||
#define Parameters_H
|
||||
|
||||
#include "ClassDetGeo.h"
|
||||
#include "ClassReactionConfig.h"
|
||||
|
||||
struct ReactionParas{
|
||||
|
||||
double Et; // total energy in CM frame
|
||||
double beta; // Lorentz beta from Lab to CM
|
||||
double gamma; // Lorentz gamma from Lab to CM
|
||||
double alpha; // E-Z slope / beta
|
||||
double G; //The G-coefficient....
|
||||
double massB; // heavy mass
|
||||
double q; // charge of light particle
|
||||
double mass; //light mass
|
||||
bool hasReactionPara;
|
||||
|
||||
double detPrepDist;
|
||||
|
||||
};
|
||||
|
||||
ReactionParas reactParas1;
|
||||
ReactionParas reactParas2;
|
||||
|
||||
//~========================================= reaction parameters
|
||||
void LoadReactionParas(int arrayID, bool verbose = false){
|
||||
|
||||
//check is the transfer.root is using the latest reactionConfig.txt
|
||||
//sicne reaction.dat is generated as a by-product of transfer.root
|
||||
//TFile * transfer = new TFile("transfer.root");
|
||||
//TString aaa1 = "";
|
||||
//TString aaa2 = "";
|
||||
//if( transfer->IsOpen() ){
|
||||
// TMacro * reactionConfig = (TMacro *) transfer->FindObjectAny("reactionConfig");
|
||||
// TMacro presentReactionConfig ("reactionConfig.txt");
|
||||
// aaa1 = ((TMD5*) reactionConfig->Checksum())->AsString();
|
||||
// aaa2 = ((TMD5*) presentReactionConfig.Checksum())->AsString();
|
||||
//}
|
||||
//printf("%s\n", aaa1.Data());
|
||||
//printf("%s\n", aaa2.Data());
|
||||
|
||||
//if( aaa1 != aaa2 ) {
|
||||
// printf("########################## recalculate transfer.root \n");
|
||||
// system("../Cleopatra/Transfer");
|
||||
// printf("########################## transfer.root updated\n");
|
||||
//}
|
||||
|
||||
ReactionParas * reactParas = nullptr;
|
||||
|
||||
std::string fileName;
|
||||
|
||||
if( arrayID == 1){
|
||||
reactParas = &AnalysisLib::reactParas1;
|
||||
fileName = "reaction.dat";
|
||||
}else if( arrayID == 2){
|
||||
reactParas = &AnalysisLib::reactParas2;
|
||||
fileName = "reaction2.dat";
|
||||
}else{
|
||||
printf("arrayID must be either 1 or 2. Abort.\n");
|
||||
return;
|
||||
}
|
||||
reactParas->detPrepDist = AnalysisLib::detGeo.array1.detPerpDist;
|
||||
|
||||
printf(" loading reaction parameters");
|
||||
std::ifstream file;
|
||||
file.open(fileName.c_str());
|
||||
reactParas->hasReactionPara = false;
|
||||
if( file.is_open() ){
|
||||
std::string x;
|
||||
int i = 0;
|
||||
while( file >> x ){
|
||||
if( x.substr(0,2) == "//" ) continue;
|
||||
if( i == 0 ) reactParas->mass = atof(x.c_str());
|
||||
if( i == 1 ) reactParas->q = atof(x.c_str());
|
||||
if( i == 2 ) reactParas->beta = atof(x.c_str());
|
||||
if( i == 3 ) reactParas->Et = atof(x.c_str());
|
||||
if( i == 4 ) reactParas->massB = atof(x.c_str());
|
||||
i = i + 1;
|
||||
}
|
||||
printf("........ done.\n");
|
||||
|
||||
reactParas->hasReactionPara = true;
|
||||
reactParas->alpha = 299.792458 * abs(detGeo.Bfield) * reactParas->q / TMath::TwoPi()/1000.; //MeV/mm
|
||||
reactParas->gamma = 1./TMath::Sqrt(1-reactParas->beta * reactParas->beta);
|
||||
reactParas->G = reactParas->alpha * reactParas->gamma * reactParas->beta * reactParas->detPrepDist ;
|
||||
|
||||
if( verbose ){
|
||||
printf("\tmass-b : %f MeV/c2 \n", reactParas->mass);
|
||||
printf("\tcharge-b : %f \n", reactParas->q);
|
||||
printf("\tE-total : %f MeV \n", reactParas->Et);
|
||||
printf("\tmass-B : %f MeV/c2 \n", reactParas->massB);
|
||||
printf("\tbeta : %f \n", reactParas->beta);
|
||||
printf("\tB-field : %f T \n", detGeo.Bfield);
|
||||
printf("\tslope : %f MeV/mm \n", reactParas->alpha * reactParas->beta);
|
||||
printf("\tdet radius: %f mm \n", reactParas->detPrepDist);
|
||||
printf("\tG-coeff : %f MeV \n", reactParas->G);
|
||||
printf("=====================================================\n");
|
||||
}
|
||||
|
||||
}else{
|
||||
printf("........ fail.\n");
|
||||
}
|
||||
file.close();
|
||||
|
||||
}
|
||||
|
||||
std::vector<double> CalExTheta(double e, double z){
|
||||
|
||||
ReactionParas * reactParas = nullptr;
|
||||
|
||||
if( detGeo.array1.zMin <= z && z <= detGeo.array1.zMax ){
|
||||
reactParas = &reactParas1;
|
||||
if( !reactParas->hasReactionPara) return {TMath::QuietNaN(), TMath::QuietNaN()};
|
||||
}
|
||||
|
||||
if( detGeo.array2.zMin <= z && z <= detGeo.array2.zMax ){
|
||||
reactParas = &reactParas2;
|
||||
if( !reactParas->hasReactionPara) return {TMath::QuietNaN(), TMath::QuietNaN()};
|
||||
}
|
||||
|
||||
double Ex = TMath::QuietNaN();
|
||||
double thetaCM = TMath::QuietNaN();
|
||||
|
||||
double y = e + reactParas->mass; // to give the KE + mass of proton;
|
||||
double Z = reactParas->alpha * reactParas->gamma * reactParas->beta * z;
|
||||
double H = TMath::Sqrt(TMath::Power(reactParas->gamma * reactParas->beta,2) * (y*y - reactParas->mass * reactParas->mass) ) ;
|
||||
|
||||
if( TMath::Abs(Z) < H ) {
|
||||
///using Newton's method to solve 0 == H * sin(phi) - G * tan(phi) - Z = f(phi)
|
||||
double tolerrence = 0.001;
|
||||
double phi = 0; ///initial phi = 0 -> ensure the solution has f'(phi) > 0
|
||||
double nPhi = 0; /// new phi
|
||||
|
||||
int iter = 0;
|
||||
do{
|
||||
phi = nPhi;
|
||||
nPhi = phi - (H * TMath::Sin(phi) - reactParas->G * TMath::Tan(phi) - Z) / (H * TMath::Cos(phi) - reactParas->G /TMath::Power( TMath::Cos(phi), 2));
|
||||
iter ++;
|
||||
if( iter > 10 || TMath::Abs(nPhi) > TMath::PiOver2()) break;
|
||||
}while( TMath::Abs(phi - nPhi ) > tolerrence);
|
||||
phi = nPhi;
|
||||
|
||||
/// check f'(phi) > 0
|
||||
double Df = H * TMath::Cos(phi) - reactParas->G / TMath::Power( TMath::Cos(phi),2);
|
||||
if( Df > 0 && TMath::Abs(phi) < TMath::PiOver2() ){
|
||||
double K = H * TMath::Sin(phi);
|
||||
double x = TMath::ACos( reactParas->mass / ( y * reactParas->gamma - K));
|
||||
double momt = reactParas->mass * TMath::Tan(x); /// momentum of particel b or B in CM frame
|
||||
double EB = TMath::Sqrt(reactParas->mass * reactParas->mass + reactParas->Et * reactParas->Et - 2 * reactParas->Et * TMath::Sqrt(momt*momt + reactParas->mass * reactParas->mass));
|
||||
Ex = EB - reactParas->massB;
|
||||
|
||||
double hahaha1 = reactParas->gamma * TMath::Sqrt(reactParas->mass * reactParas->mass + momt * momt) - y;
|
||||
double hahaha2 = reactParas->gamma * reactParas->beta * momt;
|
||||
thetaCM = TMath::ACos(hahaha1/hahaha2) * TMath::RadToDeg();
|
||||
|
||||
}
|
||||
}
|
||||
return {Ex, thetaCM};
|
||||
|
||||
}
|
||||
|
||||
|
||||
DetGeo detGeo;
|
||||
ReactionConfig reactionConfig1;
|
||||
ReactionConfig reactionConfig2;
|
||||
|
||||
void LoadDetGeoAndReactionConfigFile(std::string detGeoFileName = "detectorGeo.txt",
|
||||
std::string reactionConfigFileName1 = "reactionConfig1.txt",
|
||||
std::string reactionConfigFileName2 = "reactionConfig2.txt"){
|
||||
printf("=====================================================\n");
|
||||
printf(" loading detector geometery : %s.", detGeoFileName.c_str());
|
||||
TMacro * haha = new TMacro();
|
||||
if( haha->ReadFile(detGeoFileName.c_str()) > 0 ) {
|
||||
detGeo = AnalysisLib::LoadDetectorGeo(haha);
|
||||
printf("... done.\n");
|
||||
AnalysisLib::PrintDetGeo(detGeo);
|
||||
}else{
|
||||
printf("... fail\n");
|
||||
}
|
||||
delete haha;
|
||||
|
||||
printf("=====================================================\n");
|
||||
printf(" loading reaction1 config : %s.", reactionConfigFileName1.c_str());
|
||||
TMacro * kaka = new TMacro();
|
||||
if( kaka->ReadFile(reactionConfigFileName1.c_str()) > 0 ) {
|
||||
reactionConfig1 = AnalysisLib::LoadReactionConfig(kaka);
|
||||
printf("..... done.\n");
|
||||
AnalysisLib::PrintReactionConfig(reactionConfig1);
|
||||
}else{
|
||||
printf("..... fail\n");
|
||||
}
|
||||
delete kaka;
|
||||
|
||||
if( detGeo.use2ndArray){
|
||||
printf("=====================================================\n");
|
||||
printf(" loading reaction2 config : %s.", reactionConfigFileName2.c_str());
|
||||
TMacro * jaja = new TMacro();
|
||||
if( jaja->ReadFile(reactionConfigFileName2.c_str()) > 0 ) {
|
||||
reactionConfig2 = AnalysisLib::LoadReactionConfig(kaka);
|
||||
printf("..... done.\n");
|
||||
AnalysisLib::PrintReactionConfig(reactionConfig2);
|
||||
}else{
|
||||
printf("..... fail\n");
|
||||
}
|
||||
delete jaja;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//************************************** Correction parameters;
|
||||
|
||||
std::vector<float> xnCorr; //correction of xn to match xf
|
||||
std::vector<float> xScale; // correction of x to be (0,1)
|
||||
std::vector<std::vector<float>> xfxneCorr; //correction of xn and xf to match e
|
||||
std::vector<std::vector<float>> eCorr; // correction to e, ch -> MeV
|
||||
std::vector<std::vector<float>> rdtCorr; // correction of rdt, ch -> MeV
|
||||
|
||||
//~========================================= xf = xn correction
|
||||
void LoadXNCorr(bool verbose = false, const char * fileName = "correction_xf_xn.dat"){
|
||||
printf(" loading xf-xn correction.");
|
||||
xnCorr.clear();
|
||||
std::ifstream file;
|
||||
file.open(fileName);
|
||||
if( file.is_open() ){
|
||||
float a;
|
||||
while( file >> a ) xnCorr.push_back(a);
|
||||
printf(".......... done.\n");
|
||||
}else{
|
||||
printf(".......... fail.\n");
|
||||
}
|
||||
file.close();
|
||||
if( verbose ) for(int i = 0; i < (int) xnCorr.size(); i++) printf("%2d | %10.3f\n", i, xnCorr[i]);
|
||||
}
|
||||
|
||||
|
||||
//~========================================= X-Scale correction
|
||||
void LoadXScaleCorr(bool verbose = false, const char * fileName = "correction_scaleX.dat"){
|
||||
printf(" loading x-Scale correction.");
|
||||
xScale.clear();
|
||||
std::ifstream file;
|
||||
file.open(fileName);
|
||||
if( file.is_open() ){
|
||||
float a, b;
|
||||
while( file >> a ) xScale.push_back(a);
|
||||
printf("........ done.\n");
|
||||
}else{
|
||||
printf("........ fail.\n");
|
||||
}
|
||||
file.close();
|
||||
if( verbose ) for(int i = 0; i < (int) xScale.size(); i++) printf("%2d | %10.3f\n", i, xnCorr[i]);
|
||||
}
|
||||
|
||||
//~========================================= e = xf + xn correction
|
||||
void LoadXFXN2ECorr(bool verbose = false, const char * fileName = "correction_xfxn_e.dat"){
|
||||
printf(" loading xf/xn-e correction.");
|
||||
xfxneCorr.clear();
|
||||
std::ifstream file;
|
||||
file.open(fileName);
|
||||
if( file.is_open() ){
|
||||
float a, b;
|
||||
while( file >> a >> b) xfxneCorr.push_back({a, b});
|
||||
printf("........ done.\n");
|
||||
}else{
|
||||
printf("........ fail.\n");
|
||||
}
|
||||
file.close();
|
||||
if( verbose ) for(int i = 0; i < (int) xfxneCorr.size(); i++) printf("%2d | %10.3f, %10.3f\n", i, xfxneCorr[i][0], xfxneCorr[i][1]);
|
||||
}
|
||||
|
||||
//~========================================= e correction
|
||||
void LoadECorr(bool verbose = false, const char * fileName = "correction_e.dat"){
|
||||
printf(" loading e correction.");
|
||||
eCorr.clear();
|
||||
std::ifstream file;
|
||||
file.open(fileName);
|
||||
if( file.is_open() ){
|
||||
float a, b;
|
||||
while( file >> a >> b) eCorr.push_back( {a, b} ); // 1/a1, a0 , e' = e * a1 + a0
|
||||
printf(".............. done.\n");
|
||||
}else{
|
||||
printf(".............. fail.\n");
|
||||
}
|
||||
file.close();
|
||||
if( verbose ) for(int i = 0; i < (int) eCorr.size(); i++) printf("%2d | %10.3f, %10.3f\n", i, eCorr[i][0], eCorr[i][1]);
|
||||
}
|
||||
|
||||
//~========================================= rdt correction
|
||||
void LoadRDTCorr(bool verbose = false, const char * fileName = "correction_rdt.dat"){
|
||||
printf(" loading rdt correction.");
|
||||
rdtCorr.clear();
|
||||
std::ifstream file;
|
||||
file.open(fileName);
|
||||
if( file.is_open() ){
|
||||
float a, b;
|
||||
while( file >> a >> b) rdtCorr.push_back({a, b});
|
||||
printf("............ done.\n");
|
||||
}else{
|
||||
printf("............ fail.\n");
|
||||
}
|
||||
file.close();
|
||||
if( verbose ) for(int i = 0; i < (int) rdtCorr.size(); i++) printf("%2d | %10.3f, %10.3f\n", i, rdtCorr[i][0], rdtCorr[i][1]);
|
||||
}
|
||||
|
||||
|
||||
#endif
|
73
Armory/Process_BasicConfig
Normal file
73
Armory/Process_BasicConfig
Normal file
|
@ -0,0 +1,73 @@
|
|||
#!/bin/bash -l
|
||||
|
||||
##############################################
|
||||
#
|
||||
# This script define color, PCID, and dataPath
|
||||
#
|
||||
##############################################
|
||||
|
||||
if [ ! -z $RED ]; then
|
||||
echo "Process_BasicConfig already loaded."
|
||||
return
|
||||
fi
|
||||
|
||||
RED='\033[1;31m'
|
||||
YELLOW='\033[1;33m'
|
||||
ORANGE='\033[0;33m'
|
||||
GREEN='\033[1;32m'
|
||||
BLUE='\033[0;34m'
|
||||
CYAN='\033[0;36m'
|
||||
NC='\033[0m' #no color
|
||||
LRED='\033[1;91m'
|
||||
|
||||
############## need to distingish mac and daq
|
||||
Arch="$(uname -s)"
|
||||
PCName="$(hostname)"
|
||||
PCID=-1 #if PCID == 1 (DAQ), 2 (MAC), -1(OTHER)
|
||||
|
||||
#------ Set up data folder, check disk space
|
||||
echo -e "${YELLOW} ##################### Check computer name and arch. ${NC}"
|
||||
echo "PC name : ${PCName}"
|
||||
echo "Archetech: ${Arch}"
|
||||
|
||||
if [ ${Arch} == "Linux" ] && [ ${PCName} == "solaris-daq" ]; then
|
||||
|
||||
PCID=1
|
||||
|
||||
pathsSetting=${HOME}/SOLARIS_QT6_DAQ/programSettings.txt
|
||||
if [ -e ${pathsSetting} ]; then
|
||||
#echo "Found DAQ programSettings.txt for paths settings"
|
||||
|
||||
analysisPath=$(cat ${pathsSetting} | head -n 2 | tail -n 1)
|
||||
|
||||
if [ ! "${analysisPath}" = "$SOLARISANADIR" ]; then
|
||||
echo "The analysisPath from ${analysisPath} is different from present folder $SOLARISANADIR. Abort."
|
||||
exit
|
||||
fi
|
||||
|
||||
rawDataPathParent=$(cat ${pathsSetting} | head -n 3 | tail -n 1)
|
||||
rootDataPathParent=$(cat ${pathsSetting} | head -n 4 | tail -n 1)
|
||||
|
||||
databaseIP=$(cat ${pathsSetting} | head -n 6 | tail -n 1)
|
||||
databaseName=$(cat ${pathsSetting} | head -n 7 | tail -n 1)
|
||||
|
||||
#echo ${rawDataPathParent}
|
||||
#echo ${rootDataPathParent}
|
||||
#echo ${databaseIP}
|
||||
#echo ${databaseName}
|
||||
|
||||
else
|
||||
|
||||
echo "${RED} Cannot found DAQ programSettings.txt for path settings ${NC}"
|
||||
echo "Seek Ryan for help"
|
||||
exit
|
||||
|
||||
fi
|
||||
|
||||
fi
|
||||
|
||||
if [ ${Arch} == "Darwin" ] && [ ${PCName} == "SOLARISs-Mac-Studio.local" ]; then
|
||||
PCID=2
|
||||
rawDataPathParent=${HOME}/experimentalData/
|
||||
rootDataPathParent=${HOME}/experimentalData/
|
||||
fi
|
105
Armory/Process_Download
Executable file
105
Armory/Process_Download
Executable file
|
@ -0,0 +1,105 @@
|
|||
#!/bin/bash
|
||||
|
||||
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
|
||||
source $SOLARISANADIR/working/expName.sh
|
||||
|
||||
MacRawDataPath=$rawDataPathParent/$expName/
|
||||
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/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 "${RED}######################### 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 "$RED############### Only in SOLARIS MAC can donwload data. skip.$NC"
|
||||
fi
|
||||
|
||||
echo -e "$YELLOW=============================================$NC"
|
||||
tail -10 $MacRawDataPath/data/RunTimeStamp.dat
|
||||
echo -e "$YELLOW=============================================$NC"
|
||||
|
||||
count=`ls -1 $SOLARISANADIR/data_raw/${expName}_${RUN}_*.sol 2>/dev/null | wc -l`
|
||||
echo -e "========== Number of Files : ${count}${NC}"
|
||||
if [ ${count} -eq 0 ]; then
|
||||
echo "============================================"
|
||||
echo "==== RAW Files of RUN-${RUN} not found! "
|
||||
echo "============================================"
|
||||
|
||||
isRunDataExist=false
|
||||
exit 1
|
||||
else
|
||||
echo -e "${YELLOW}"
|
||||
du -hc $SOLARISANADIR/data_raw/${expName}_${RUN}_*.sol
|
||||
echo -e "$NC============================================="
|
||||
isRunDataExist=true
|
||||
fi
|
108
Armory/Process_EventBuilder
Executable file
108
Armory/Process_EventBuilder
Executable file
|
@ -0,0 +1,108 @@
|
|||
#!/bin/bash
|
||||
|
||||
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 [ $# -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
|
||||
source ${SOLARISANADIR}/working/expName.sh
|
||||
|
||||
runNum=${RUN#0} #remove zero
|
||||
RUN=$(printf '%03d' $runNum) ##add back the zero
|
||||
|
||||
rawDataPath=$SOLARISANADIR/data_raw
|
||||
rootDataPath=$SOLARISANADIR/root_data
|
||||
|
||||
rawDataPattern="$rawDataPath/${expName}_${RUN}_*.sol"
|
||||
rootDataName="$rootDataPath/run$RUN.root"
|
||||
|
||||
dir=$(pwd)
|
||||
cd ${SOLARISANADIR}/armory
|
||||
make
|
||||
cd ${dir}
|
||||
|
||||
#==== check raw data exist
|
||||
isRawDataExist=`ls -1 ${rawDataPattern}* 2>/dev/null | wc -l`
|
||||
|
||||
if [ ! $isRawDataExist -gt 0 ]; then
|
||||
echo -e "${LRED}################# Run Data $rawDataPattern not exist. Abort. ${NC}"
|
||||
exit
|
||||
fi
|
||||
|
||||
echo -e "${CYAN} ============== list of files ${NC}"
|
||||
\du -h ${rawDataPattern}*
|
||||
|
||||
totSize=$(\du -hc ${rawDataPattern}* | tail -n 1 | awk '{print $1}')
|
||||
echo -e "${CYAN} ============== 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
96
Armory/Process_MultiRuns
Executable 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
|
93
Armory/Process_Run
Executable file
93
Armory/Process_Run
Executable file
|
@ -0,0 +1,93 @@
|
|||
#!/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 [ $# -eq 0 ] || [ $1 == "-help" ]; then
|
||||
echo "$ Process_Run [RunNum] [EventBuild] [GeneralSort] [TraceMethod] [Monitor]"
|
||||
echo " RunNum = run number / \"lastRun\" "
|
||||
echo " EventBld = 2/1/0/-1/-2 || 2 = with Trace"
|
||||
echo " GeneralSort = n/0/-n || n = number of worker"
|
||||
echo " TraceMethod = -1/0/1/2 || -1 no trace, 0 save trace, 1 fit, 2 trapezoid(not implemented)"
|
||||
echo " Monitor = 2/1/0 || 1 = single run, 2 = using the list in ChainMonitors.C"
|
||||
echo ""
|
||||
echo " * negative option = force (except for TraceMethod and Monitor)."
|
||||
echo " * Defult timeWindow for Event builder is 100 tick = 800 ns."
|
||||
echo ""
|
||||
exit 1
|
||||
fi;
|
||||
|
||||
RUN=$1
|
||||
runNum=$1
|
||||
EventBld=2
|
||||
nWorker=1
|
||||
TraceMethod=-1
|
||||
isMonitor=1
|
||||
|
||||
if [ $# -ge 2 ]; then EventBld=$2; fi
|
||||
if [ $# -ge 3 ]; then nWorker=$3; fi
|
||||
if [ $# -ge 4 ]; then TraceMethod=$4; fi
|
||||
if [ $# -ge 5 ]; then isMonitor=$5; fi
|
||||
|
||||
if [ "$RUN" == "lastRun" ]; then
|
||||
RUN=$runID
|
||||
fi
|
||||
|
||||
RUN=${RUN##*(0)} #remove zero
|
||||
RUN=$(printf '%03d' $RUN) ##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 ${SOLARISANADIR}/working/expName.sh
|
||||
|
||||
if [ "$PWD" != "${SOLARISANADIR}/working" ]; then
|
||||
echo "============= go to the Working directory"
|
||||
cd "${SOLARISANADIR}/working"
|
||||
fi
|
||||
|
||||
|
||||
#################################### CHECK IS RUN DATA EXIST
|
||||
isRunDataExist=true
|
||||
|
||||
#################################### 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($RUN)"
|
||||
elif [ $isMonitor -eq 2 ]; then
|
||||
root -l "ChainMonitors.C"
|
||||
fi
|
||||
|
||||
|
||||
|
||||
|
91
Armory/Process_Sort
Executable file
91
Armory/Process_Sort
Executable file
|
@ -0,0 +1,91 @@
|
|||
#!/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 [ $# -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
|
||||
source $SOLARISANADIR/working/expName.sh
|
||||
|
||||
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
|
258
Armory/SolReader.h
Normal file
258
Armory/SolReader.h
Normal file
|
@ -0,0 +1,258 @@
|
|||
#ifndef SOLREADER_H
|
||||
#define SOLREADER_H
|
||||
|
||||
#include <stdio.h> /// for FILE
|
||||
#include <cstdlib>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <unistd.h>
|
||||
#include <time.h> // time in nano-sec
|
||||
|
||||
#include "Hit.h"
|
||||
|
||||
class SolReader {
|
||||
private:
|
||||
FILE * inFile;
|
||||
unsigned int inFileSize;
|
||||
unsigned int filePos;
|
||||
unsigned int totNumBlock;
|
||||
|
||||
unsigned short blockStartIdentifier;
|
||||
unsigned int numBlock;
|
||||
bool isScanned;
|
||||
|
||||
void init();
|
||||
|
||||
std::vector<unsigned int> blockPos;
|
||||
|
||||
public:
|
||||
SolReader();
|
||||
SolReader(std::string fileName, unsigned short dataType);
|
||||
~SolReader();
|
||||
|
||||
void OpenFile(std::string fileName);
|
||||
int ReadNextBlock(int isSkip = 0); // opt = 0, noraml, 1, fast
|
||||
int ReadBlock(unsigned int index, bool verbose = false);
|
||||
|
||||
void ScanNumBlock();
|
||||
|
||||
bool IsEndOfFile() const {return (filePos >= inFileSize ? true : false);}
|
||||
unsigned int GetBlockID() const {return numBlock - 1;}
|
||||
unsigned int GetNumBlock() const {return numBlock;}
|
||||
unsigned int GetTotalNumBlock() const {return totNumBlock;}
|
||||
unsigned int GetFilePos() const {return filePos;}
|
||||
unsigned int GetFileSize() const {return inFileSize;}
|
||||
|
||||
void RewindFile();
|
||||
|
||||
Hit * hit;
|
||||
|
||||
};
|
||||
|
||||
void SolReader::init(){
|
||||
inFileSize = 0;
|
||||
numBlock = 0;
|
||||
filePos = 0;
|
||||
totNumBlock = 0;
|
||||
hit = new Hit();
|
||||
|
||||
isScanned = false;
|
||||
|
||||
blockPos.clear();
|
||||
|
||||
}
|
||||
|
||||
SolReader::SolReader(){
|
||||
init();
|
||||
}
|
||||
|
||||
SolReader::SolReader(std::string fileName, unsigned short dataType = 0){
|
||||
init();
|
||||
OpenFile(fileName);
|
||||
hit->SetDataType(dataType, DPPType::PHA);
|
||||
}
|
||||
|
||||
SolReader::~SolReader(){
|
||||
if( !inFile ) fclose(inFile);
|
||||
delete hit;
|
||||
}
|
||||
|
||||
inline void SolReader::OpenFile(std::string fileName){
|
||||
inFile = fopen(fileName.c_str(), "r");
|
||||
if( inFile == NULL ){
|
||||
printf("Cannot open file : %s \n", fileName.c_str());
|
||||
}else{
|
||||
fseek(inFile, 0L, SEEK_END);
|
||||
inFileSize = ftell(inFile);
|
||||
rewind(inFile);
|
||||
}
|
||||
}
|
||||
|
||||
inline int SolReader::ReadBlock(unsigned int index, bool verbose){
|
||||
if( isScanned == false) return -1;
|
||||
if( index >= totNumBlock )return -1;
|
||||
fseek(inFile, 0L, SEEK_SET);
|
||||
|
||||
if( verbose ) printf("Block index: %u, File Pos: %u byte\n", index, blockPos[index]);
|
||||
|
||||
fseek(inFile, blockPos[index], SEEK_CUR);
|
||||
|
||||
filePos = blockPos[index];
|
||||
|
||||
numBlock = index;
|
||||
|
||||
return ReadNextBlock();
|
||||
}
|
||||
|
||||
inline int SolReader::ReadNextBlock(int isSkip){
|
||||
if( inFile == NULL ) return -1;
|
||||
if( feof(inFile) ) return -1;
|
||||
if( filePos >= inFileSize) return -1;
|
||||
|
||||
fread(&blockStartIdentifier, 2, 1, inFile);
|
||||
|
||||
if( (blockStartIdentifier & 0xAA00) != 0xAA00 ) {
|
||||
printf("header fail.\n");
|
||||
return -2 ;
|
||||
}
|
||||
|
||||
if( ( blockStartIdentifier & 0xF ) == DataFormat::Raw ){
|
||||
hit->SetDataType(DataFormat::Raw, ((blockStartIdentifier >> 1) & 0xF) == 0 ? DPPType::PHA : DPPType::PSD);
|
||||
}
|
||||
hit->dataType = blockStartIdentifier & 0xF;
|
||||
hit->DPPType = ((blockStartIdentifier >> 4) & 0xF) == 0 ? DPPType::PHA : DPPType::PSD;
|
||||
|
||||
if( hit->dataType == DataFormat::ALL){
|
||||
if( isSkip == 0 ){
|
||||
fread(&hit->channel, 1, 1, inFile);
|
||||
fread(&hit->energy, 2, 1, inFile);
|
||||
if( hit->DPPType == DPPType::PSD ) fread(&hit->energy_short, 2, 1, inFile);
|
||||
fread(&hit->timestamp, 6, 1, inFile);
|
||||
fread(&hit->fine_timestamp, 2, 1, inFile);
|
||||
fread(&hit->flags_high_priority, 1, 1, inFile);
|
||||
fread(&hit->flags_low_priority, 2, 1, inFile);
|
||||
fread(&hit->downSampling, 1, 1, inFile);
|
||||
fread(&hit->board_fail, 1, 1, inFile);
|
||||
fread(&hit->flush, 1, 1, inFile);
|
||||
fread(&hit->trigger_threashold, 2, 1, inFile);
|
||||
fread(&hit->event_size, 8, 1, inFile);
|
||||
fread(&hit->aggCounter, 4, 1, inFile);
|
||||
}else{
|
||||
fseek(inFile, hit->DPPType == DPPType::PHA ? 31 : 33, SEEK_CUR);
|
||||
}
|
||||
fread(&hit->traceLenght, 8, 1, inFile);
|
||||
if( isSkip == 0){
|
||||
fread(hit->analog_probes_type, 2, 1, inFile);
|
||||
fread(hit->digital_probes_type, 4, 1, inFile);
|
||||
fread(hit->analog_probes[0], hit->traceLenght*4, 1, inFile);
|
||||
fread(hit->analog_probes[1], hit->traceLenght*4, 1, inFile);
|
||||
fread(hit->digital_probes[0], hit->traceLenght, 1, inFile);
|
||||
fread(hit->digital_probes[1], hit->traceLenght, 1, inFile);
|
||||
fread(hit->digital_probes[2], hit->traceLenght, 1, inFile);
|
||||
fread(hit->digital_probes[3], hit->traceLenght, 1, inFile);
|
||||
}else{
|
||||
fseek(inFile, 6 + hit->traceLenght*(12), SEEK_CUR);
|
||||
}
|
||||
|
||||
}else if( hit->dataType == DataFormat::OneTrace){
|
||||
if( isSkip == 0 ){
|
||||
fread(&hit->channel, 1, 1, inFile);
|
||||
fread(&hit->energy, 2, 1, inFile);
|
||||
if( hit->DPPType == DPPType::PSD ) fread(&hit->energy_short, 2, 1, inFile);
|
||||
fread(&hit->timestamp, 6, 1, inFile);
|
||||
fread(&hit->fine_timestamp, 2, 1, inFile);
|
||||
fread(&hit->flags_high_priority, 1, 1, inFile);
|
||||
fread(&hit->flags_low_priority, 2, 1, inFile);
|
||||
}else{
|
||||
fseek(inFile, hit->DPPType == DPPType::PHA ? 14 : 16, SEEK_CUR);
|
||||
}
|
||||
fread(&hit->traceLenght, 8, 1, inFile);
|
||||
if( isSkip == 0){
|
||||
fread(&hit->analog_probes_type[0], 1, 1, inFile);
|
||||
fread(hit->analog_probes[0], hit->traceLenght*4, 1, inFile);
|
||||
}else{
|
||||
fseek(inFile, 1 + hit->traceLenght*4, SEEK_CUR);
|
||||
}
|
||||
|
||||
}else if( hit->dataType == DataFormat::NoTrace){
|
||||
if( isSkip == 0 ){
|
||||
fread(&hit->channel, 1, 1, inFile);
|
||||
fread(&hit->energy, 2, 1, inFile);
|
||||
if( hit->DPPType == DPPType::PSD ) fread(&hit->energy_short, 2, 1, inFile);
|
||||
fread(&hit->timestamp, 6, 1, inFile);
|
||||
fread(&hit->fine_timestamp, 2, 1, inFile);
|
||||
fread(&hit->flags_high_priority, 1, 1, inFile);
|
||||
fread(&hit->flags_low_priority, 2, 1, inFile);
|
||||
}else{
|
||||
fseek(inFile, hit->DPPType == DPPType::PHA ? 14 : 16, SEEK_CUR);
|
||||
}
|
||||
|
||||
}else if( hit->dataType == DataFormat::MiniWithFineTime){
|
||||
if( isSkip == 0 ){
|
||||
fread(&hit->channel, 1, 1, inFile);
|
||||
fread(&hit->energy, 2, 1, inFile);
|
||||
if( hit->DPPType == DPPType::PSD ) fread(&hit->energy_short, 2, 1, inFile);
|
||||
fread(&hit->timestamp, 6, 1, inFile);
|
||||
fread(&hit->fine_timestamp, 2, 1, inFile);
|
||||
}else{
|
||||
fseek(inFile, hit->DPPType == DPPType::PHA ? 11 : 13, SEEK_CUR);
|
||||
}
|
||||
|
||||
}else if( hit->dataType == DataFormat::Minimum){
|
||||
if( isSkip == 0 ){
|
||||
fread(&hit->channel, 1, 1, inFile);
|
||||
fread(&hit->energy, 2, 1, inFile);
|
||||
if( hit->DPPType == DPPType::PSD ) fread(&hit->energy_short, 2, 1, inFile);
|
||||
fread(&hit->timestamp, 6, 1, inFile);
|
||||
}else{
|
||||
fseek(inFile, hit->DPPType == DPPType::PHA ? 9 : 11, SEEK_CUR);
|
||||
}
|
||||
|
||||
}else if( hit->dataType == DataFormat::Raw){
|
||||
fread(&hit->dataSize, 8, 1, inFile);
|
||||
if( isSkip == 0){
|
||||
fread(hit->data, hit->dataSize, 1, inFile);
|
||||
}else{
|
||||
fseek(inFile, hit->dataSize, SEEK_CUR);
|
||||
}
|
||||
}
|
||||
|
||||
numBlock ++;
|
||||
filePos = ftell(inFile);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void SolReader::RewindFile(){
|
||||
rewind(inFile);
|
||||
filePos = 0;
|
||||
numBlock = 0;
|
||||
}
|
||||
|
||||
void SolReader::ScanNumBlock(){
|
||||
if( inFile == NULL ) return;
|
||||
if( feof(inFile) ) return;
|
||||
|
||||
numBlock = 0;
|
||||
blockPos.clear();
|
||||
|
||||
blockPos.push_back(0);
|
||||
|
||||
while( ReadNextBlock(1) == 0){
|
||||
blockPos.push_back(filePos);
|
||||
printf("%u, %.2f%% %u/%u\n\033[A\r", numBlock, filePos*100./inFileSize, filePos, inFileSize);
|
||||
}
|
||||
|
||||
totNumBlock = numBlock;
|
||||
numBlock = 0;
|
||||
isScanned = true;
|
||||
printf("\nScan complete: number of data Block : %u\n", totNumBlock);
|
||||
rewind(inFile);
|
||||
filePos = 0;
|
||||
|
||||
//for( int i = 0; i < totNumBlock; i++){
|
||||
// printf("%7d | %u \n", i, blockPos[i]);
|
||||
//}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
144
Armory/readRawTrace.C
Normal file
144
Armory/readRawTrace.C
Normal 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
171
Armory/readTrace.C
Normal 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");
|
||||
|
||||
}
|
|
@ -18,8 +18,10 @@
|
|||
#include <TObjArray.h>
|
||||
#include <fstream>
|
||||
#include <TCutG.h>
|
||||
#include "../armory/AnalysisLib.h"
|
||||
#include "../Cleopatra/Isotope.h"
|
||||
#include "../Armory/AnalysisLib.h"
|
||||
#include "../Armory/ClassDetGeo.h"
|
||||
#include "../Armory/ClassReactionConfig.h"
|
||||
#include "../Cleopatra/ClassIsotope.h"
|
||||
|
||||
double * FindRange(TString branch, TString gate, TTree * tree, double output[2]);
|
||||
double ExtractNumber(int index, TMacro * macro);
|
||||
|
@ -109,7 +111,8 @@ void Check_Simulation(TString filename = "transfer1.root",
|
|||
TMacro * reactionConfigTxt = (TMacro *) file->FindObjectAny("reactionConfig");
|
||||
TString Reaction=reactionConfigTxt->GetName();
|
||||
|
||||
AnalysisLib::ReactionConfig reactionConfig = AnalysisLib::LoadReactionConfig(reactionConfigTxt);
|
||||
ReactionConfig reactionConfig;
|
||||
reactionConfig.LoadReactionConfig(reactionConfigTxt);
|
||||
|
||||
int nEvent = reactionConfig.numEvents;
|
||||
printf("number of events generated : %d \n", nEvent);
|
||||
|
@ -137,9 +140,10 @@ void Check_Simulation(TString filename = "transfer1.root",
|
|||
printf(" loading detector Geometry.\n");
|
||||
TMacro * detGeoTxt = (TMacro *) file->FindObjectAny("detGeo");
|
||||
|
||||
AnalysisLib::DetGeo detGeo = AnalysisLib::LoadDetectorGeo(detGeoTxt);
|
||||
DetGeo detGeo;
|
||||
detGeo.LoadDetectorGeo(detGeoTxt);
|
||||
|
||||
AnalysisLib::Array array;
|
||||
Array array;
|
||||
if( detGeo.use2ndArray){
|
||||
array = detGeo.array2;
|
||||
}else{
|
||||
|
|
147
Cleopatra/ClassDecay.h
Normal file
147
Cleopatra/ClassDecay.h
Normal file
|
@ -0,0 +1,147 @@
|
|||
#ifndef decay_h
|
||||
#define decay_h
|
||||
|
||||
#include "TVector3.h"
|
||||
|
||||
#include "../Cleopatra/ClassIsotope.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(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;
|
||||
|
||||
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 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();
|
||||
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);
|
||||
}
|
||||
|
||||
Decay::~Decay(){
|
||||
delete f1;
|
||||
}
|
||||
|
||||
|
||||
#endif
|
479
Cleopatra/ClassHelios.h
Normal file
479
Cleopatra/ClassHelios.h
Normal file
|
@ -0,0 +1,479 @@
|
|||
#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(trajectory a){
|
||||
printf("=====================\n");
|
||||
printf(" theta : %f deg\n", a.theta*TMath::RadToDeg());
|
||||
printf(" phi : %f deg\n", a.phi*TMath::RadToDeg());
|
||||
printf(" vt : %f mm/ns\n", a.vt);
|
||||
printf(" vp : %f mm/ns\n", a.vp);
|
||||
printf(" rho : %f mm\n", a.rho);
|
||||
printf(" z0 : %f mm\n", a.z0);
|
||||
printf(" t0 : %f ns\n", a.t0);
|
||||
printf("(x, y, z) : (%f, %f. %f) mm\n", a.x, a.y, a.z);
|
||||
printf(" R : %f mm\n", a.R);
|
||||
printf(" t : %f ns\n", a.t);
|
||||
printf(" effLoop : %f cycle\n", a.effLoop);
|
||||
printf(" Loop : %d cycle\n", a.loop);
|
||||
printf(" detRowID : %d \n", a.detRowID);
|
||||
printf(" detID : %d \n", a.detID);
|
||||
|
||||
}
|
||||
|
||||
class HELIOS{
|
||||
public:
|
||||
|
||||
HELIOS();
|
||||
~HELIOS();
|
||||
|
||||
void SetCoincidentWithRecoil(bool TorF){ this->isCoincidentWithRecoil = TorF;}
|
||||
bool GetCoincidentWithRecoil(){return this->isCoincidentWithRecoil;}
|
||||
bool SetDetectorGeometry(std::string filename);
|
||||
void SetBeamPosition(double x, double y) { xOff = x; yOff = y;}
|
||||
|
||||
void OverrideMagneticField(double BField){ this->detGeo.Bfield = BField; this->detGeo.BfieldSign = BField > 0 ? 1: -1;}
|
||||
void OverrideMagneticFieldDirection(double BfieldThetaInDeg){ this->detGeo.BfieldTheta = BfieldThetaInDeg;}
|
||||
void OverrideFirstPos(double firstPos){
|
||||
overrideFirstPos = true;
|
||||
printf("------ Overriding FirstPosition to : %8.2f mm \n", firstPos);
|
||||
this->array.firstPos = firstPos;
|
||||
}
|
||||
void OverrideDetectorDistance(double perpDist){
|
||||
overrideDetDistance = true;
|
||||
printf("------ Overriding Detector Distance to : %8.2f mm \n", perpDist);
|
||||
this->array.detPerpDist = perpDist;
|
||||
}
|
||||
|
||||
void SetDetectorOutside(bool isOutside){
|
||||
this->array.detFaceOut = isOutside;
|
||||
printf(" Detectors are facing %s\n", array.detFaceOut ? "outside": "inside" );
|
||||
}
|
||||
|
||||
int DetAcceptance();
|
||||
int CalArrayHit(TLorentzVector Pb, int Zb);
|
||||
int CalRecoilHit(TLorentzVector PB, int ZB);
|
||||
//int CalHit(TLorentzVector Pb, int Zb, TLorentzVector PB, int ZB, double xOff = 0, double yOff = 0 ); // return 0 for no hit, 1 for hit
|
||||
|
||||
void CalTrajectoryPara(TLorentzVector P, int Z, int id); // id = 0 for Pb, id = 1 for PB.
|
||||
|
||||
int GetNumberOfDetectorsInSamePos(){return array.mDet;}
|
||||
double GetEnergy(){return e;}
|
||||
double GetDetX(){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){
|
||||
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){
|
||||
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){
|
||||
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 XPos( ZPos, orbitb.theta, orbitb.phi, orbitb.rho, detGeo.BfieldSign); }
|
||||
double GetYPos(double ZPos){ return YPos( ZPos, orbitb.theta, orbitb.phi, orbitb.rho, detGeo.BfieldSign); }
|
||||
double GetR(double ZPos) { return RPos( ZPos, orbitb.theta, orbitb.phi, orbitb.rho, detGeo.BfieldSign); }
|
||||
|
||||
double GetRecoilEnergy(){return eB;}
|
||||
double GetRecoilXPos(double ZPos){ return XPos( ZPos, orbitB.theta, orbitB.phi, orbitB.rho, detGeo.BfieldSign); }
|
||||
double GetRecoilYPos(double ZPos){ return YPos( ZPos, orbitB.theta, orbitB.phi, orbitB.rho, detGeo.BfieldSign); }
|
||||
double GetRecoilR(double ZPos) { return RPos( ZPos, orbitB.theta, orbitB.phi, orbitB.rho, detGeo.BfieldSign); }
|
||||
|
||||
double GetBField() {return detGeo.Bfield;}
|
||||
double GetDetRadius() {return array.detPerpDist;}
|
||||
|
||||
trajectory GetTrajectory_b() {return orbitb;}
|
||||
trajectory GetTrajectory_B() {return orbitB;}
|
||||
|
||||
DetGeo GetDetectorGeometry() {return detGeo;}
|
||||
|
||||
private:
|
||||
|
||||
void ClearTrajectory(trajectory t){
|
||||
t.theta = TMath::QuietNaN();
|
||||
t.phi = TMath::QuietNaN();
|
||||
t.vt = TMath::QuietNaN();
|
||||
t.vp = TMath::QuietNaN();
|
||||
t.rho = TMath::QuietNaN();
|
||||
t.z0 = TMath::QuietNaN();
|
||||
t.t0 = TMath::QuietNaN();
|
||||
t.x = TMath::QuietNaN();
|
||||
t.y = TMath::QuietNaN();
|
||||
t.z = TMath::QuietNaN();
|
||||
t.effLoop = TMath::QuietNaN();
|
||||
t.detID = -1;
|
||||
t.detRowID = -1;
|
||||
t.loop = -1;
|
||||
}
|
||||
|
||||
DetGeo detGeo;
|
||||
Array array;
|
||||
|
||||
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;
|
||||
|
||||
double xOff, yOff; // beam position
|
||||
|
||||
|
||||
bool overrideDetDistance;
|
||||
bool overrideFirstPos;
|
||||
bool isCoincidentWithRecoil;
|
||||
|
||||
const double c = 299.792458; //mm/ns
|
||||
};
|
||||
|
||||
HELIOS::HELIOS(){
|
||||
|
||||
ClearTrajectory(orbitb);
|
||||
ClearTrajectory(orbitB);
|
||||
|
||||
e = TMath::QuietNaN();
|
||||
eB = TMath::QuietNaN();
|
||||
detX = TMath::QuietNaN();
|
||||
rhoHit = TMath::QuietNaN();
|
||||
|
||||
xOff = 0.0;
|
||||
yOff = 0.0;
|
||||
|
||||
isDetReady = false;
|
||||
|
||||
overrideDetDistance = false;
|
||||
overrideFirstPos = false;
|
||||
isCoincidentWithRecoil = false;
|
||||
|
||||
}
|
||||
|
||||
HELIOS::~HELIOS(){
|
||||
|
||||
}
|
||||
|
||||
bool HELIOS::SetDetectorGeometry(std::string filename){
|
||||
|
||||
if( detGeo.LoadDetectorGeo(filename)) {
|
||||
|
||||
if( detGeo.use2ndArray ){
|
||||
array = detGeo.array2;
|
||||
}else{
|
||||
array = detGeo.array1;
|
||||
}
|
||||
|
||||
isCoincidentWithRecoil = detGeo.isCoincidentWithRecoil;
|
||||
|
||||
isDetReady = true;
|
||||
}else{
|
||||
printf("cannot read file %s.\n", filename.c_str());
|
||||
isDetReady = false;
|
||||
}
|
||||
|
||||
return isDetReady;
|
||||
}
|
||||
|
||||
int HELIOS::DetAcceptance(){
|
||||
|
||||
//CalArrayHit and CalRecoilHit must be done before.
|
||||
|
||||
if( isDetReady == false ) return 0;
|
||||
|
||||
// -1 ========= when recoil direction is not same side of array
|
||||
if( array.firstPos < 0 && orbitb.z > 0 ) return -1;
|
||||
if( array.firstPos > 0 && orbitb.z < 0 ) return -1;
|
||||
|
||||
// -11 ======== rho is too small
|
||||
if( 2 * orbitb.rho < array.detPerpDist ) return -11;
|
||||
|
||||
// -15 ========= if detRowID == -1, should be (2 * orbitb.rho < perpDist)
|
||||
if( orbitb.detRowID == -1 ) return -15;
|
||||
|
||||
// -10 =========== when rho is too big .
|
||||
if( detGeo.bore < 2 * orbitb.rho) return -10;
|
||||
|
||||
// -14 ========== check particle-B hit radius on recoil dectector
|
||||
if( isCoincidentWithRecoil && orbitB.R > detGeo.recoilOuterRadius ) return -14;
|
||||
//if( isCoincidentWithRecoil && (orbitB.R > rhoRecoilout || orbitB.R < rhoRecoilin) ) return -14;
|
||||
|
||||
// -12 ========= check is particle-b was blocked by recoil detector
|
||||
rhoHit = GetR(detGeo.recoilPos);
|
||||
if( orbitb.z > 0 && detGeo.recoilPos > 0 && orbitb.z > detGeo.recoilPos && rhoHit < detGeo.recoilOuterRadius ) return -12;
|
||||
if( orbitb.z < 0 && detGeo.recoilPos < 0 && orbitb.z < detGeo.recoilPos && rhoHit < detGeo.recoilOuterRadius ) return -12;
|
||||
|
||||
// -13 ========= not more than 3 loops
|
||||
if( orbitb.loop > 3 ) return -13;
|
||||
|
||||
// -2 ========= calculate the "y"-distance from detector center
|
||||
if( sqrt(orbitb.R*orbitb.R - array.detPerpDist * array.detPerpDist)> array.detWidth/2 ) return -2;
|
||||
|
||||
// -3 ==== when zPos further the range of whole array, more loop would not save
|
||||
if( array.firstPos < 0 && orbitb.z < array.detPos[0] - array.detLength ) return -3;
|
||||
if( array.firstPos > 0 && orbitb.z > array.detPos[array.nDet-1] + array.detLength ) return -3;
|
||||
|
||||
// -4 ======== Hit on blacker
|
||||
if( array.blocker != 0 && array.firstPos > 0 && array.detPos[0] - array.blocker < orbitb.z && orbitb.z < array.detPos[0] ) return -4;
|
||||
if( array.blocker != 0 && array.firstPos < 0 && array.detPos[array.nDet-1] < orbitb.z && orbitb.z < array.detPos[array.nDet-1] + array.blocker ) return -4;
|
||||
|
||||
// 2 ====== when zPos less then the nearest position, more loop may hit
|
||||
int increaseLoopFlag = 0;
|
||||
if( array.firstPos < 0 && array.detPos[array.nDet-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;
|
||||
return 2;
|
||||
}
|
||||
|
||||
// 1 ======= check hit array z- position
|
||||
if( array.firstPos < 0 ){
|
||||
for( int i = 0; i < array.nDet; 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
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}else{
|
||||
for( int i = 0; i < array.nDet ; 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
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// -5 ======== check hit array gap
|
||||
if( array.firstPos < 0 ){
|
||||
for( int i = 0; i < array.nDet-1 ; i++){
|
||||
if( array.detPos[i] < orbitb.z && orbitb.z < array.detPos[i+1] - array.detLength ) return -5; //increaseLoopFlag = 3;
|
||||
}
|
||||
}else{
|
||||
for( int i = 0; i < array.nDet-1 ; i++){
|
||||
if( array.detPos[i] + array.detLength < orbitb.z && orbitb.z < array.detPos[i+1] ) return -5; //increaseLoopFlag = 3;
|
||||
}
|
||||
}
|
||||
if (increaseLoopFlag == 3 ) {
|
||||
orbitb.z += orbitb.z0;
|
||||
orbitb.effLoop += 1.0;
|
||||
orbitb.loop += 1;
|
||||
orbitb.t = orbitb.t0 * orbitb.effLoop;
|
||||
return 3;
|
||||
}
|
||||
|
||||
|
||||
return -20; // for unknown reason
|
||||
}
|
||||
|
||||
void HELIOS::CalTrajectoryPara(TLorentzVector P, int Z, int id){
|
||||
|
||||
if( id == 0 ){
|
||||
orbitb.theta = P.Theta();
|
||||
orbitb.phi = P.Phi();
|
||||
orbitb.rho = P.Pt() / abs(detGeo.Bfield) / Z / 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;
|
||||
|
||||
}
|
||||
|
||||
if( id == 1 ){
|
||||
orbitB.theta = P.Theta();
|
||||
orbitB.phi = P.Phi();
|
||||
orbitB.rho = P.Pt() / abs(detGeo.Bfield) / Z / 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, int Zb){
|
||||
|
||||
e = Pb.E() - Pb.M();
|
||||
detX = TMath::QuietNaN();
|
||||
rhoHit = TMath::QuietNaN();
|
||||
|
||||
CalTrajectoryPara(Pb, Zb, 0);
|
||||
|
||||
int targetLoop = 1;
|
||||
int inOut = array.detFaceOut == true ? 1: 0; //1 = from Outside, 0 = from inside
|
||||
|
||||
bool debug = false;
|
||||
|
||||
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("-----------------------------------\n");
|
||||
}
|
||||
|
||||
std::vector<double> zPossible;
|
||||
std::vector<int> dID; //detRowID
|
||||
|
||||
int iStart = ( detGeo.BfieldSign == 1 ? 0 : -array.mDet );
|
||||
int iEnd = ( detGeo.BfieldSign == 1 ? 2 * array.mDet : array.mDet );
|
||||
for( int i = iStart; i < iEnd ; i++){
|
||||
|
||||
double phiD = TMath::TwoPi()/array.mDet * 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.BfieldTheta * 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( zPossible.size() == 0 ){ // will not happen
|
||||
zHit = TMath::QuietNaN();
|
||||
xPos = TMath::QuietNaN();
|
||||
yPos = TMath::QuietNaN();
|
||||
loop = -1;
|
||||
detID = -1;
|
||||
detRowID = -1;
|
||||
return -1 ;
|
||||
}*/
|
||||
|
||||
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.mDet * 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;
|
||||
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;
|
||||
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);
|
||||
|
||||
return 1; // return 1 when OK
|
||||
}
|
||||
|
||||
int HELIOS::CalRecoilHit(TLorentzVector PB, int ZB){
|
||||
|
||||
CalTrajectoryPara(PB, ZB, 1);
|
||||
|
||||
orbitB.z = detGeo.recoilPos;
|
||||
orbitB.x = GetRecoilXPos(detGeo.recoilPos) ;
|
||||
orbitB.y = GetRecoilYPos(detGeo.recoilPos) ;
|
||||
orbitB.R = GetRecoilR(detGeo.recoilPos);
|
||||
orbitB.effLoop = orbitB.z/orbitB.z0;
|
||||
orbitB.t = orbitB.t0 * orbitB.effLoop ;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
#endif
|
301
Cleopatra/ClassKnockout.h
Normal file
301
Cleopatra/ClassKnockout.h
Normal 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
|
202
Cleopatra/ClassTargetScattering.h
Normal file
202
Cleopatra/ClassTargetScattering.h
Normal 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], ¶Straggling[0]);
|
||||
gD = new TGraph(energy.size(), &energy[0], &prepStraggling[0]);
|
||||
|
||||
}
|
||||
|
||||
#endif
|
384
Cleopatra/ClassTransfer.h
Normal file
384
Cleopatra/ClassTransfer.h
Normal file
|
@ -0,0 +1,384 @@
|
|||
#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"
|
||||
|
||||
//=======================================================
|
||||
//#######################################################
|
||||
// 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();
|
||||
~TransferReaction();
|
||||
|
||||
void SetA(int A, int Z, double Ex);
|
||||
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 SetReactionSimple(int beamA, int beamZ,
|
||||
int targetA, int targetZ,
|
||||
int recoilA, int recoilZ, float beamEnergy_AMeV);
|
||||
|
||||
void SetExA(double Ex);
|
||||
void SetExB(double Ex);
|
||||
void SetReactionFromFile(string settingFile);
|
||||
|
||||
TString GetReactionName();
|
||||
TString GetReactionName_Latex();
|
||||
|
||||
ReactionConfig GetRectionConfig() { return reaction;}
|
||||
|
||||
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;}
|
||||
|
||||
int GetCharge_b() const {return reaction.recoilLightZ;}
|
||||
|
||||
double GetCMTotalKE() {return Etot - mA - ma;}
|
||||
double GetQValue() {return mA + ExA + ma - mb - mB - ExB;}
|
||||
double GetMaxExB() {return Etot - mb - mB;}
|
||||
|
||||
TLorentzVector GetPA(){return PA;}
|
||||
TLorentzVector GetPa(){return Pa;}
|
||||
TLorentzVector GetPb(){return Pb;}
|
||||
TLorentzVector GetPB(){return PB;}
|
||||
|
||||
void CalReactionConstant();
|
||||
|
||||
void Event(double thetaCM_rad, double phiCM_rad);
|
||||
|
||||
double GetMomentumbCM() {return p;}
|
||||
double GetReactionBeta() {return beta;}
|
||||
double GetReactionGamma() {return gamma;}
|
||||
double GetCMTotalEnergy() {return Etot;}
|
||||
|
||||
std::pair<double, double> CalExThetaCM(double e, double z, double Bfield, double a);
|
||||
|
||||
private:
|
||||
|
||||
ReactionConfig reaction;
|
||||
|
||||
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
|
||||
|
||||
TLorentzVector PA, Pa, Pb, PB;
|
||||
|
||||
TString format(TString name);
|
||||
|
||||
};
|
||||
|
||||
TransferReaction::TransferReaction(){
|
||||
|
||||
thetaIN = 0.;
|
||||
phiIN = 0.;
|
||||
SetA(12, 6, 0);
|
||||
Seta(2,1);
|
||||
Setb(1,1);
|
||||
SetB(13,6);
|
||||
TA = 6;
|
||||
T = TA * reaction.beamA;
|
||||
|
||||
ExA = 0;
|
||||
ExB = 0;
|
||||
|
||||
CalReactionConstant();
|
||||
|
||||
TLorentzVector temp (0,0,0,0);
|
||||
PA = temp;
|
||||
Pa = temp;
|
||||
Pb = temp;
|
||||
PB = temp;
|
||||
|
||||
}
|
||||
|
||||
TransferReaction::~TransferReaction(){
|
||||
|
||||
}
|
||||
|
||||
void TransferReaction::SetA(int A, int Z, double Ex = 0){
|
||||
Isotope temp (A, Z);
|
||||
mA = temp.Mass;
|
||||
reaction.beamA = A;
|
||||
reaction.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;
|
||||
reaction.targetA = A;
|
||||
reaction.targetZ = Z;
|
||||
namea = temp.Name;
|
||||
isReady = false;
|
||||
isBSet = false;
|
||||
}
|
||||
void TransferReaction::Setb(int A, int Z){
|
||||
Isotope temp (A, Z);
|
||||
mb = temp.Mass;
|
||||
reaction.recoilLightA = A;
|
||||
reaction.recoilLightZ = Z;
|
||||
nameb = temp.Name;
|
||||
isReady = false;
|
||||
isBSet = false;
|
||||
}
|
||||
void TransferReaction::SetB(int A, int Z){
|
||||
Isotope temp (A, Z);
|
||||
mB = temp.Mass;
|
||||
reaction.recoilHeavyA = A;
|
||||
reaction.recoilHeavyZ = Z;
|
||||
nameB = temp.Name;
|
||||
isReady = false;
|
||||
isBSet = true;
|
||||
}
|
||||
|
||||
void TransferReaction::SetIncidentEnergyAngle(double KEA, double theta, double phi){
|
||||
this->TA = KEA;
|
||||
this->T = TA * reaction.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){
|
||||
|
||||
reaction.SetReactionSimple(beamA, beamZ,
|
||||
targetA, targetZ,
|
||||
recoilA, recoilZ, beamEnergy_AMeV);
|
||||
|
||||
SetA(reaction.beamA, reaction.beamZ);
|
||||
Seta(reaction.targetA, reaction.targetZ);
|
||||
Setb(reaction.recoilLightA, reaction.recoilLightZ);
|
||||
SetB(reaction.recoilHeavyA, reaction.recoilHeavyZ);
|
||||
SetIncidentEnergyAngle(reaction.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::SetReactionFromFile(string settingFile){
|
||||
|
||||
if( reaction.LoadReactionConfig(settingFile) ){
|
||||
|
||||
SetA(reaction.beamA, reaction.beamZ);
|
||||
Seta(reaction.targetA, reaction.targetZ);
|
||||
Setb(reaction.recoilLightA, reaction.recoilLightZ);
|
||||
SetB(reaction.recoilHeavyA, reaction.recoilHeavyZ);
|
||||
SetIncidentEnergyAngle(reaction.beamEnergy, 0, 0);
|
||||
|
||||
CalReactionConstant();
|
||||
|
||||
}else{
|
||||
printf("cannot read file %s.\n", settingFile.c_str());
|
||||
isReady = false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
TString TransferReaction::GetReactionName(){
|
||||
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", format(nameA).Data(), format(namea).Data(), format(nameb).Data(), format(nameB).Data());
|
||||
return rName;
|
||||
}
|
||||
|
||||
void TransferReaction::CalReactionConstant(){
|
||||
if( !isBSet){
|
||||
reaction.recoilHeavyA = reaction.beamA + reaction.targetA - reaction.recoilLightA;
|
||||
reaction.recoilHeavyZ = reaction.beamZ + reaction.targetZ - reaction.recoilLightZ;
|
||||
Isotope temp (reaction.recoilHeavyA, reaction.recoilHeavyZ);
|
||||
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);
|
||||
p = TMath::Sqrt( (Etot*Etot - TMath::Power(mb + mB + ExB,2)) * (Etot*Etot - TMath::Power(mb - mB - ExB,2)) ) / 2 / Etot;
|
||||
|
||||
PA.SetXYZM(0, 0, k, mA + ExA);
|
||||
PA.RotateY(thetaIN);
|
||||
PA.RotateZ(phiIN);
|
||||
|
||||
Pa.SetXYZM(0,0,0,ma);
|
||||
|
||||
isReady = true;
|
||||
}
|
||||
|
||||
void TransferReaction::Event(double thetaCM_rad, double phiCM_rad){
|
||||
|
||||
if( isReady == false ){
|
||||
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 * reaction.recoilLightZ * 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);
|
||||
}
|
||||
|
||||
|
||||
#endif
|
|
@ -1,205 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
|
||||
########################################################################
|
||||
#
|
||||
# This is Cleopatra.sh, a scripted version for Cleopatra
|
||||
#
|
||||
# Using bash script provide flexibility that user can add difference
|
||||
# compoenents during the calculation
|
||||
#
|
||||
# A full package includes fellowing:
|
||||
# 1) create a in-file for ptolemy
|
||||
# 2) run ptolemy from that in-file and output an out-file
|
||||
# 3) extract cross-section distribution from the out-file
|
||||
# save as txt or root TGraph format
|
||||
# 4) call ROOT to draw the TGraph
|
||||
# 5) load possible experimental Xsec and fit with Ptolemy calulation
|
||||
#
|
||||
# User can easily select/comment-out different component
|
||||
# to suit their needs
|
||||
#-------------------------------------------------------
|
||||
# created by Ryan (Tsz Leung) Tang, Nov-18, 2018
|
||||
# email: goluckyryan@gmail.com
|
||||
########################################################################
|
||||
|
||||
#===== Call thisroot.h
|
||||
ROOTPATH=$(which root)
|
||||
len=${#ROOTPATH}
|
||||
ROOTSOURCE=${ROOTPATH:0:$len-4}"thisroot.sh"
|
||||
echo $ROOTSOURCE
|
||||
source $ROOTSOURCE
|
||||
|
||||
#===== go to Cleopatra and make
|
||||
cd ../Cleopatra
|
||||
make
|
||||
cd ../working
|
||||
|
||||
#================================ User Defualt Control
|
||||
CreateInFile=0 # 0 = false, 1 = true
|
||||
RunPtolemy=0
|
||||
IsExtractXSec=0
|
||||
PlotResult=0
|
||||
SimTransfer=0
|
||||
#============================================ USER don't need to change thing below
|
||||
|
||||
if [ $# -eq 0 ] ; then
|
||||
echo "$./Cleopatra in-file X X X X X angMin angMax angStep"
|
||||
echo " | | | | |"
|
||||
echo " | | | | Simulate Transfer reaction? (1/0)"
|
||||
echo " | | | |"
|
||||
echo " | | | PlotResult? (1/0)"
|
||||
echo " | | Extract cross-section? (2/1/0)"
|
||||
echo " | | if 1 = extract Ratio to Rutherford for (d,d), (p,p)"
|
||||
echo " | | if 2 = extract total Xsec for (d,d), (p,p), (n,n)"
|
||||
echo " | | if 3 = extract Rutherford"
|
||||
echo " | Run Ptolemy? (1/0)"
|
||||
echo " Create infile? (1/0)"
|
||||
echo "default angMin = 0, angMax = 50, angStep = 0.5"
|
||||
exit 1
|
||||
fi;
|
||||
|
||||
loadfile=$1
|
||||
infile=$1".in"
|
||||
outfile=$1".out"
|
||||
rootfile=$1".root"
|
||||
exFile=$1".Ex.txt"
|
||||
|
||||
if [ $# -eq 2 ]; then
|
||||
CreateInFile=$2
|
||||
fi;
|
||||
if [ $# -eq 3 ]; then
|
||||
CreateInFile=$2
|
||||
RunPtolemy=$3
|
||||
fi;
|
||||
if [ $# -eq 4 ]; then
|
||||
CreateInFile=$2
|
||||
RunPtolemy=$3
|
||||
IsExtractXSec=$4
|
||||
fi;
|
||||
if [ $# -eq 5 ]; then
|
||||
CreateInFile=$2
|
||||
RunPtolemy=$3
|
||||
IsExtractXSec=$4
|
||||
PlotResult=$5
|
||||
fi;
|
||||
if [ $# -eq 6 ]; then
|
||||
CreateInFile=$2
|
||||
RunPtolemy=$3
|
||||
IsExtractXSec=$4
|
||||
PlotResult=$5
|
||||
SimTransfer=$6
|
||||
fi;
|
||||
if [ $# -eq 9 ]; then
|
||||
CreateInFile=$2
|
||||
RunPtolemy=$3
|
||||
IsExtractXSec=$4
|
||||
PlotResult=$5
|
||||
SimTransfer=$6
|
||||
angMin=$7
|
||||
angMax=$8
|
||||
angStep=$9
|
||||
fi;
|
||||
|
||||
ExtractXsecMsg=""
|
||||
if [ $IsExtractXSec -eq 1 ]; then
|
||||
ExtractXsecMsg=", for (d,d)(p,p), extract Ratio to Rutherford"
|
||||
elif [ $IsExtractXSec -eq 2 ]; then
|
||||
ExtractXsecMsg=", for (d,d)(p,p), extract Total Xsec"
|
||||
fi;
|
||||
|
||||
if [ $SimTransfer -eq 1 ]; then
|
||||
angMin=0
|
||||
angMax=180
|
||||
angStep=0.5
|
||||
fi
|
||||
|
||||
echo "#################################################################"
|
||||
echo "## @@@@ @@ @@@@ @@@@ @@@@@ @@@@ @@@@@@ @@@@@ @@@@ ##"
|
||||
echo "## @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ ##"
|
||||
echo "## @@ @@ @@@@ @@ @@ @@@@@ @@@@@@ @@ @@@@@ @@@@@@ ##"
|
||||
echo "## @@ @@ @@ @@ @@ @@ @@ @@ @@ @@ @ @@ @@ ##"
|
||||
echo "## @@@@ @@@@@ @@@@ @@@@ @@ @@ @@ @@ @@ @ @@ @@ ##"
|
||||
echo "#################################################################"
|
||||
echo "##### Cleopatra, Ptolemy for p,d,t,3He, a #####"
|
||||
echo "#################################################################"
|
||||
echo "Supported reactions:"
|
||||
echo "elastics/inelastics : (p,p), (d,d)"
|
||||
echo "1-neutron adding : (d,p), (t,d) | (a,3He)?"
|
||||
echo "1-proton adding : (3He,d)"
|
||||
echo "2-neutrons adding : (t,p)"
|
||||
echo "1-neutron removal : (p,d), (d,t) "
|
||||
echo "1-proton removal : (d,3He), (t,a)"
|
||||
echo "================================================================="
|
||||
echo "USER OPTION:"
|
||||
echo " --- Is Create Ptolemy infile ? " ${CreateInFile}
|
||||
echo " --- Is Run Ptolemy ? " ${RunPtolemy}
|
||||
echo " --- Is Extract Cross-Section ? " ${IsExtractXSec} ${ExtractXsecMsg}
|
||||
echo " --- Is Plot Results ? " ${PlotResult}
|
||||
echo " ----Is Simulation Transfer ? " ${SimTransfer}
|
||||
echo "================================================================="
|
||||
|
||||
#if [ ${CreateInFile} -eq 1 ] ; then
|
||||
# echo "infile ----> "${loadfile}
|
||||
#fi;
|
||||
#
|
||||
#if [ ${RunPtolemy} -eq 1 ] ; then
|
||||
# echo "Ptolemy infile ----> "${infile}
|
||||
# echo "Ptolemy outfile ----> "${outfile}
|
||||
#fi;
|
||||
|
||||
if [ ${CreateInFile} -eq 1 ] ; then
|
||||
if [ $# -eq 9 ]; then
|
||||
../Cleopatra/InFileCreator ${loadfile} $angMin $angMax $angStep
|
||||
else
|
||||
../Cleopatra/InFileCreator ${loadfile} 0.0 50.0 0.5
|
||||
fi
|
||||
fi;
|
||||
|
||||
if [ ${RunPtolemy} -eq 1 ] ; then
|
||||
echo "================================================================="
|
||||
echo "===== Ptolemy Calcualtion ==================================="
|
||||
echo "================================================================="
|
||||
|
||||
#check is linux or Mac
|
||||
|
||||
arch=$(uname)
|
||||
|
||||
if [ ${arch} == "Darwin" ] ; then
|
||||
../Cleopatra/ptolemy_mac <${infile}> ${outfile}
|
||||
ptolemyOUTPUT=$?
|
||||
else
|
||||
../Cleopatra/ptolemy <${infile}> ${outfile}
|
||||
ptolemyOUTPUT=$?
|
||||
fi
|
||||
|
||||
echo "ptolmey exit code : " $ptolemyOUTPUT
|
||||
if [ ${ptolemyOUTPUT} -eq 0 ] ; then
|
||||
echo "Ptolmey finished without problem. "
|
||||
else
|
||||
echo "Ptolemy has error, check ${infile} or ${outfile}"
|
||||
exit 1;
|
||||
fi
|
||||
|
||||
fi;
|
||||
|
||||
#===== Extracting XSec and save into *txt and *root
|
||||
if [ ${IsExtractXSec} -ge 1 ] ; then
|
||||
../Cleopatra/ExtractXSec ${outfile} ${IsExtractXSec}
|
||||
fi;
|
||||
|
||||
if [ ${PlotResult} -eq 1 ] ; then
|
||||
#===== Plot the result from the *.root
|
||||
#./PlotTGraphTObjArray ${rootfile}
|
||||
#--- other way within ROOT
|
||||
echo "================================================================="
|
||||
echo "===== Plot Result from ${rootfile}"
|
||||
echo "================================================================="
|
||||
com='../Cleopatra/PlotTGraphTObjArray.h("'${rootfile}'")'
|
||||
echo ${com}
|
||||
root -l ${com}
|
||||
fi;
|
||||
|
||||
if [ ${SimTransfer} -eq 1 ] ; then
|
||||
../Cleopatra/Transfer reactionConfig.txt detectorGeo.txt ${exFile} ${rootfile} transfer.root reaction.dat
|
||||
fi;
|
|
@ -25,7 +25,7 @@
|
|||
#include <TGraph.h>
|
||||
#include <TF1.h>
|
||||
#include <TObjArray.h>
|
||||
#include "../armory/AnalysisLib.h"
|
||||
#include "../Armory/AnalysisLib.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
|
|
|
@ -16,11 +16,12 @@
|
|||
#include "TMacro.h"
|
||||
#include "TObjArray.h"
|
||||
#include "TGraph.h"
|
||||
#include "../Cleopatra/HELIOS_LIB.h"
|
||||
#include "../Cleopatra/ClassHelios.h"
|
||||
#include "../Cleopatra/ClassTransfer.h"
|
||||
|
||||
void FindThetaCM(double Ex, int nDivision=1, double XRATION = 0.95,
|
||||
string basicConfig="reactionConfig.txt",
|
||||
string detGeoFileName = "detectorGeo.txt"){
|
||||
std::string basicConfig="reactionConfig.txt",
|
||||
std::string detGeoFileName = "detectorGeo.txt"){
|
||||
|
||||
//---- reaction
|
||||
int AA, zA; //beam
|
||||
|
@ -34,13 +35,9 @@ void FindThetaCM(double Ex, int nDivision=1, double XRATION = 0.95,
|
|||
double xBeam, yBeam; // mm
|
||||
|
||||
/**///========================================================= load files
|
||||
AnalysisLib::ReactionConfig reactionConfig;
|
||||
AnalysisLib::DetGeo detGeo;
|
||||
TMacro * haha = new TMacro();
|
||||
if( haha->ReadFile(basicConfig.c_str()) > 0 ){
|
||||
reactionConfig = AnalysisLib::LoadReactionConfig(haha);
|
||||
|
||||
AnalysisLib::PrintReactionConfig(reactionConfig);
|
||||
ReactionConfig reactionConfig;
|
||||
DetGeo detGeo;
|
||||
if( reactionConfig.LoadReactionConfig(basicConfig) ){
|
||||
|
||||
KEAmean = reactionConfig.beamEnergy;
|
||||
KEAsigma = reactionConfig.beamEnergySigma;
|
||||
|
@ -62,7 +59,7 @@ void FindThetaCM(double Ex, int nDivision=1, double XRATION = 0.95,
|
|||
return;
|
||||
}
|
||||
|
||||
vector<double> pos;
|
||||
std::vector<double> pos;
|
||||
double a = 11.5;
|
||||
double length = 50.5;
|
||||
double firstPos = 0;
|
||||
|
@ -99,10 +96,7 @@ void FindThetaCM(double Ex, int nDivision=1, double XRATION = 0.95,
|
|||
|
||||
|
||||
printf("----- loading detector geometery : %s.", detGeoFileName.c_str());
|
||||
TMacro * kaka = new TMacro();
|
||||
if( kaka->ReadFile(detGeoFileName.c_str()) > 0 ){
|
||||
detGeo = AnalysisLib::LoadDetectorGeo(kaka);
|
||||
|
||||
if(detGeo.LoadDetectorGeo(detGeoFileName) ){
|
||||
pos = detGeo.array1.detPos;
|
||||
a = detGeo.array1.detPerpDist;
|
||||
length = detGeo.array1.detLength;
|
||||
|
@ -113,8 +107,6 @@ void FindThetaCM(double Ex, int nDivision=1, double XRATION = 0.95,
|
|||
|
||||
printf("... done.\n");
|
||||
|
||||
AnalysisLib::PrintDetGeo(detGeo);
|
||||
|
||||
}else{
|
||||
printf("... fail\n");
|
||||
return;
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -26,9 +26,9 @@
|
|||
|
||||
#include <stdlib.h> /* atof */
|
||||
#include <vector>
|
||||
#include "../Cleopatra/Isotope.h" // for geting Z
|
||||
#include "../Cleopatra/ClassIsotope.h" // for geting Z
|
||||
#include "potentials.h"
|
||||
#include "../armory/AnalysisLib.h"
|
||||
#include "../Armory/AnalysisLib.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
|
||||
#include <fstream>
|
||||
#include <stdlib.h>
|
||||
#include "Isotope.h"
|
||||
#include "ClassIsotope.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
|
||||
#include <fstream>
|
||||
#include <stdlib.h>
|
||||
#include "Isotope.h"
|
||||
#include "ClassIsotope.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
|
|
|
@ -13,7 +13,11 @@
|
|||
#include <fstream>
|
||||
#include <TObjArray.h>
|
||||
|
||||
#include "HELIOS_LIB.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]];
|
||||
|
@ -37,9 +41,9 @@ void Transfer(
|
|||
printf("----- loading reaction setting from %s. \n", basicConfig.c_str());
|
||||
printf("\e[32m#################################### Beam \e[0m\n");
|
||||
|
||||
const AnalysisLib::ReactionConfig reactionConfig = reaction.GetRectionConfig();
|
||||
const ReactionConfig reactionConfig = reaction.GetRectionConfig();
|
||||
|
||||
AnalysisLib::PrintReactionConfig(reactionConfig);
|
||||
reactionConfig.PrintReactionConfig();
|
||||
|
||||
vector<float> ExAList = reactionConfig.beamEx;
|
||||
int nExA = (int) ExAList.size();
|
||||
|
@ -49,7 +53,7 @@ void Transfer(
|
|||
HELIOS helios;
|
||||
helios.SetDetectorGeometry(heliosDetGeoFile);
|
||||
|
||||
const AnalysisLib::DetGeo detGeo = helios.GetDetectorGeometry();
|
||||
const DetGeo detGeo = helios.GetDetectorGeometry();
|
||||
|
||||
printf("==================================== E-Z plot slope\n");
|
||||
double betaRect = reaction.GetReactionBeta() ;
|
||||
|
@ -537,9 +541,9 @@ void Transfer(
|
|||
double phiCM = TMath::TwoPi() * gRandom->Rndm();
|
||||
|
||||
//==== Calculate reaction
|
||||
TLorentzVector * output = reaction.Event(thetaCM, phiCM);
|
||||
TLorentzVector Pb = output[2];
|
||||
TLorentzVector PB = output[3];
|
||||
reaction.Event(thetaCM, phiCM);
|
||||
TLorentzVector Pb = reaction.GetPb();
|
||||
TLorentzVector PB = reaction.GetPB();
|
||||
|
||||
//==== Calculate energy loss of scattered and recoil in target
|
||||
if( isTargetScattering ){
|
||||
|
@ -646,9 +650,9 @@ void Transfer(
|
|||
rhoRecoil2 = helios.GetRecoilR(detGeo.recoilPos2);
|
||||
}
|
||||
|
||||
reaction.CalExThetaCM(e, z, helios.GetBField(), helios.GetDetRadius());
|
||||
ExCal = reaction.GetEx();
|
||||
thetaCMCal = reaction.GetThetaCM();
|
||||
std::pair<double,double> ExThetaCM = reaction.CalExThetaCM(e, z, helios.GetBField(), helios.GetDetRadius());
|
||||
ExCal = ExThetaCM.first;
|
||||
thetaCMCal = ExThetaCM.second;
|
||||
|
||||
//change thetaCM into deg
|
||||
thetaCM = thetaCM * TMath::RadToDeg();
|
||||
|
|
|
@ -4,10 +4,7 @@ ALL = Isotope InFileCreator ExtractXSec ExtractXSecFromText PlotTGraphTObjArray
|
|||
|
||||
all: $(ALL)
|
||||
|
||||
#Cleopatra: Cleopatra.C ../Simulation/Isotope.h ../Simulation/constant.h potentials.h InFileCreator.h ExtractXSec.h PlotTGraphTObjArray.h
|
||||
# $(CC) Cleopatra.C -o Cleopatra `root-config --cflags --glibs`
|
||||
|
||||
InFileCreator: InFileCreator.C InFileCreator.h ../Cleopatra/Isotope.h ../Cleopatra/constant.h potentials.h
|
||||
InFileCreator: InFileCreator.C InFileCreator.h ../Cleopatra/ClassIsotope.h ../Cleopatra/constant.h potentials.h
|
||||
$(CC) InFileCreator.C -o InFileCreator `root-config --cflags --glibs`
|
||||
|
||||
ExtractXSec: ExtractXSec.C ExtractXSec.h
|
||||
|
@ -19,19 +16,19 @@ ExtractXSecFromText: ExtractXSecFromText.C ExtractXSec.h
|
|||
PlotTGraphTObjArray: PlotTGraphTObjArray.C PlotTGraphTObjArray.h
|
||||
$(CC) PlotTGraphTObjArray.C -o PlotTGraphTObjArray `root-config --cflags --glibs`
|
||||
|
||||
FindThetaCM: FindThetaCM.C FindThetaCM.h ../Cleopatra/HELIOS_LIB.h ../Cleopatra/Isotope.h ../Cleopatra/constant.h
|
||||
FindThetaCM: FindThetaCM.C FindThetaCM.h ../Cleopatra/ClassHelios.h ../Cleopatra/ClassIsotope.h ../Cleopatra/constant.h
|
||||
$(CC) FindThetaCM.C -o FindThetaCM `root-config --cflags --glibs`
|
||||
|
||||
Transfer: Transfer.C Transfer.h ../Cleopatra/HELIOS_LIB.h ../Cleopatra/Isotope.h ../Cleopatra/constant.h
|
||||
Transfer: Transfer.C Transfer.h ../Cleopatra/ClassHelios.h ../Cleopatra/ClassIsotope.h ../Cleopatra/constant.h
|
||||
$(CC) Transfer.C -o Transfer `root-config --cflags --glibs`
|
||||
|
||||
PlotSimulation: PlotSimulation.C Check_Simulation.C
|
||||
$(CC) PlotSimulation.C -o PlotSimulation `root-config --cflags --glibs`
|
||||
|
||||
Isotope: ../Cleopatra/Isotope.h ../Cleopatra/Isotope.C
|
||||
Isotope: ../Cleopatra/ClassIsotope.h ../Cleopatra/Isotope.C
|
||||
$(CC) Isotope.C -o Isotope
|
||||
|
||||
IsotopeShort: ../Cleopatra/Isotope.h ../Cleopatra/IsotopeShort.C
|
||||
IsotopeShort: ../Cleopatra/ClassIsotope.h ../Cleopatra/IsotopeShort.C
|
||||
$(CC) IsotopeShort.C -o IsotopeShort
|
||||
|
||||
clean:
|
||||
|
|
|
@ -1,77 +0,0 @@
|
|||
#include "HELIOS_LIB.h"
|
||||
#include "TROOT.h"
|
||||
#include "TBenchmark.h"
|
||||
#include "TLorentzVector.h"
|
||||
#include "TMath.h"
|
||||
#include "TFile.h"
|
||||
#include "TF1.h"
|
||||
#include "TTree.h"
|
||||
#include "TRandom.h"
|
||||
#include "TGraph.h"
|
||||
#include "TMacro.h"
|
||||
#include <stdlib.h>
|
||||
#include <vector>
|
||||
#include <fstream>
|
||||
#include <TObjArray.h>
|
||||
|
||||
void transfer_test(double t, double p, double bField, bool fromOutSide){
|
||||
|
||||
TransferReaction reaction;
|
||||
reaction.SetA(14, 6);
|
||||
reaction.Seta( 2, 1);
|
||||
reaction.Setb( 1, 1);
|
||||
reaction.SetB(15, 6);
|
||||
|
||||
reaction.SetExB(0);
|
||||
|
||||
reaction.SetIncidentEnergyAngle(10, 0, 0);
|
||||
reaction.CalReactionConstant();
|
||||
|
||||
HELIOS helios;
|
||||
helios.SetDetectorGeometry("../working/detectorGeo.txt");
|
||||
helios.OverrideMagneticField(bField);
|
||||
helios.SetDetectorOutside(fromOutSide);
|
||||
|
||||
double beta = reaction.GetReactionBeta() ;
|
||||
|
||||
double slope = 299.792458 * abs(helios.GetBField()) / TMath::TwoPi() * beta / 1000.; // MeV/mm
|
||||
|
||||
double alpha = slope / beta;
|
||||
|
||||
printf("===================================\n");
|
||||
printf("Mass A : %8.2f MeV/c2\n", reaction.GetMass_A());
|
||||
printf("Mass a : %8.2f MeV/c2\n", reaction.GetMass_a());
|
||||
printf("Mass b : %8.2f MeV/c2\n", reaction.GetMass_b());
|
||||
printf("Mass B : %8.2f MeV/c2\n", reaction.GetMass_B());
|
||||
printf("CM Mass : %8.2f MeV\n", reaction.GetCMTotalEnergy());
|
||||
printf("CM beta : %8.6f \n", beta);
|
||||
printf("slope : %8.6f MeV\n", alpha * beta);
|
||||
printf("alpha : %8.6f MeV\n", alpha);
|
||||
|
||||
|
||||
double thetaCM = t * TMath::DegToRad();
|
||||
double phiCM = - p * TMath::DegToRad();
|
||||
|
||||
TLorentzVector * output = reaction.Event(thetaCM, phiCM);
|
||||
TLorentzVector Pb = output[2];
|
||||
TLorentzVector PB = output[3];
|
||||
|
||||
Pb.Print();
|
||||
PB.Print();
|
||||
|
||||
helios.CalArrayHit(Pb, 1);
|
||||
helios.CalRecoilHit(PB, 6);
|
||||
|
||||
printf("+++++++++++++++++++++++++++++++++++++\n");
|
||||
|
||||
int hitID = 2;
|
||||
while( hitID > 1 ){
|
||||
printf("==================== check accp.\n");
|
||||
hitID = helios.DetAcceptance();
|
||||
printf("-------------------- hitID %d\n", hitID);
|
||||
}
|
||||
|
||||
PrintTrajectory(helios.GetTrajectory_b());
|
||||
|
||||
|
||||
}
|
|
@ -49,640 +49,6 @@ std::vector<std::string> SplitStr(std::string tempLine, std::string splitter, in
|
|||
return output;
|
||||
};
|
||||
|
||||
struct Array{
|
||||
|
||||
double detPerpDist; /// distance from axis
|
||||
double detWidth; /// width
|
||||
double detLength; /// length
|
||||
double blocker;
|
||||
double firstPos; /// meter
|
||||
double eSigma; /// intrinsic energy resolution MeV
|
||||
double zSigma; /// intrinsic position resolution mm
|
||||
bool detFaceOut; ///detector_facing_Out_or_In
|
||||
std::vector<double> pos; /// near position in meter
|
||||
int nDet, mDet; /// nDet = number of different pos, mDet, number of same pos
|
||||
std::vector<double> detPos; ///absolute position of detector
|
||||
|
||||
double zMin, zMax;
|
||||
|
||||
void DeduceAbsolutePos(){
|
||||
nDet = pos.size();
|
||||
detPos.clear();
|
||||
|
||||
for(int id = 0; id < nDet; id++){
|
||||
if( firstPos > 0 ) detPos.push_back(firstPos + pos[id]);
|
||||
if( firstPos < 0 ) detPos.push_back(firstPos - pos[nDet - 1 - id]);
|
||||
///printf("%d | %f, %f \n", id, pos[id], detPos[id]);
|
||||
}
|
||||
|
||||
zMin = TMath::Min(detPos.front(), detPos.back()) - (firstPos < 0 ? detLength : 0);
|
||||
zMax = TMath::Max(detPos.front(), detPos.back()) + (firstPos > 0 ? detLength : 0);
|
||||
}
|
||||
|
||||
void PrintArray(){
|
||||
for(int i = 0; i < nDet ; i++){
|
||||
if( firstPos > 0 ){
|
||||
printf("%d, %8.2f mm - %8.2f mm \n", i, detPos[i], detPos[i] + detLength);
|
||||
}else{
|
||||
printf("%d, %8.2f mm - %8.2f mm \n", i, detPos[i] - detLength , detPos[i]);
|
||||
}
|
||||
}
|
||||
|
||||
printf(" Blocker Position: %8.2f mm \n", firstPos > 0 ? firstPos - blocker : firstPos + blocker );
|
||||
printf(" First Position: %8.2f mm \n", firstPos);
|
||||
printf(" number of det : %d x %d \n", mDet, nDet);
|
||||
printf(" detector facing : %s\n", detFaceOut ? "Out" : "In");
|
||||
printf(" energy resol.: %f MeV\n", eSigma);
|
||||
printf(" pos-Z resol.: %f mm \n", zSigma);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
struct DetGeo{
|
||||
|
||||
double Bfield; /// T
|
||||
int BfieldSign ; /// sign of B-field
|
||||
double BfieldTheta; /// rad, 0 = z-axis, pi/2 = y axis, pi = -z axis
|
||||
double bore; /// bore , mm
|
||||
|
||||
double recoilPos; /// recoil, downstream
|
||||
double recoilInnerRadius; /// radius recoil inner
|
||||
double recoilOuterRadius; /// radius recoil outter
|
||||
|
||||
double recoilPos1, recoilPos2; /// imaginary recoils
|
||||
|
||||
double elumPos1, elumPos2; /// imaginary elum, only sensitive to light recoil
|
||||
|
||||
//===================1st array
|
||||
Array array1;
|
||||
|
||||
//==================2nd array
|
||||
bool use2ndArray;
|
||||
Array array2;
|
||||
|
||||
double zMin, zMax; /// range of detectors
|
||||
bool isCoincidentWithRecoil;
|
||||
|
||||
};
|
||||
|
||||
struct ReactionConfig{
|
||||
|
||||
int beamA;
|
||||
int beamZ;
|
||||
int targetA;
|
||||
int targetZ;
|
||||
int recoilLightA;
|
||||
int recoilLightZ;
|
||||
int recoilHeavyA;
|
||||
int recoilHeavyZ;
|
||||
float beamEnergy; ///MeV/u
|
||||
float beamEnergySigma; ///beam-energy_sigma_in_MeV/u
|
||||
float beamAngle; ///beam-angle_in_mrad
|
||||
float beamAngleSigma; ///beam-emittance_in_mrad
|
||||
float beamX; ///x_offset_of_Beam_in_mm
|
||||
float beamY; ///y_offset_of_Beam_in_mm
|
||||
int numEvents; ///number_of_Event_being_generated
|
||||
bool isTargetScattering; ///isTargetScattering
|
||||
float targetDensity; ///target_density_in_g/cm3
|
||||
float targetThickness; ///targetThickness_in_cm
|
||||
std::string beamStoppingPowerFile; ///stopping_power_for_beam
|
||||
std::string recoilLightStoppingPowerFile; ///stopping_power_for_light_recoil
|
||||
std::string recoilHeavyStoppingPowerFile; ///stopping_power_for_heavy_recoil
|
||||
bool isDecay; ///isDacay
|
||||
int heavyDecayA; ///decayNucleus_A
|
||||
int heavyDecayZ; ///decayNucleus_Z
|
||||
bool isRedo; ///isReDo
|
||||
std::vector<float> beamEx; ///excitation_energy_of_A[MeV]
|
||||
|
||||
};
|
||||
|
||||
///Using TMacro to load the detectorGeo frist,
|
||||
///this indrect method is good for loading detectorGeo from TMacro in root file
|
||||
DetGeo LoadDetectorGeo(TMacro * macro){
|
||||
|
||||
DetGeo detGeo;
|
||||
|
||||
if( macro == NULL ) return detGeo;
|
||||
|
||||
TList * haha = macro->GetListOfLines();
|
||||
int numLine = (haha)->GetSize();
|
||||
|
||||
detGeo.array1.pos.clear();
|
||||
detGeo.array2.pos.clear();
|
||||
detGeo.use2ndArray = false;
|
||||
|
||||
int detFlag = 0;
|
||||
int detLine = 0;
|
||||
|
||||
for( int i = 0 ; i < numLine; i++){
|
||||
|
||||
std::vector<std::string> str = SplitStr(macro->GetListOfLines()->At(i)->GetName(), " ");
|
||||
|
||||
//printf("%3d | %s\n", i, str[0].c_str());
|
||||
|
||||
if( str[0].find("####") != std::string::npos ) break;
|
||||
if( str[0].find("#===") != std::string::npos ) {
|
||||
detFlag ++;
|
||||
detLine = 0;
|
||||
continue;;
|
||||
}
|
||||
|
||||
if( detFlag == 0 ){
|
||||
if ( i == 0 ) {
|
||||
detGeo.Bfield = atof(str[0].c_str());
|
||||
detGeo.BfieldSign = detGeo.Bfield > 0 ? 1: -1;
|
||||
}
|
||||
if ( i == 1 ) detGeo.BfieldTheta = atof(str[0].c_str());
|
||||
if ( i == 2 ) detGeo.bore = atof(str[0].c_str());
|
||||
if ( i == 3 ) detGeo.recoilPos = atof(str[0].c_str());
|
||||
if ( i == 4 ) detGeo.recoilInnerRadius = atof(str[0].c_str());
|
||||
if ( i == 5 ) detGeo.recoilOuterRadius = atof(str[0].c_str());
|
||||
if ( i == 6 ) detGeo.isCoincidentWithRecoil = str[0] == "false" ? false: true;
|
||||
if ( i == 7 ) detGeo.recoilPos1 = atof(str[0].c_str());
|
||||
if ( i == 8 ) detGeo.recoilPos2 = atof(str[0].c_str());
|
||||
if ( i == 9 ) detGeo.elumPos1 = atof(str[0].c_str());
|
||||
if ( i == 10 ) detGeo.elumPos2 = atof(str[0].c_str());
|
||||
}
|
||||
|
||||
if( detFlag == 1){
|
||||
if ( detLine == 0 ) detGeo.array1.detPerpDist = atof(str[0].c_str());
|
||||
if ( detLine == 1 ) detGeo.array1.detWidth = atof(str[0].c_str());
|
||||
if ( detLine == 2 ) detGeo.array1.detLength = atof(str[0].c_str());
|
||||
if ( detLine == 3 ) detGeo.array1.blocker = atof(str[0].c_str());
|
||||
if ( detLine == 4 ) detGeo.array1.firstPos = atof(str[0].c_str());
|
||||
if ( detLine == 5 ) detGeo.array1.eSigma = atof(str[0].c_str());
|
||||
if ( detLine == 6 ) detGeo.array1.zSigma = atof(str[0].c_str());
|
||||
if ( detLine == 7 ) detGeo.array1.detFaceOut = str[0] == "Out" ? true : false;
|
||||
if ( detLine == 8 ) detGeo.array1.mDet = atoi(str[0].c_str());
|
||||
if ( detLine >= 9 ) (detGeo.array1.pos).push_back(atof(str[0].c_str()));
|
||||
detLine ++;
|
||||
}
|
||||
|
||||
if( detFlag == 2){
|
||||
if ( detLine == 0 ) detGeo.use2ndArray = str[0] == "true" ? true : false;
|
||||
if ( detLine == 1 ) detGeo.array2.detPerpDist = atof(str[0].c_str());
|
||||
if ( detLine == 2 ) detGeo.array2.detWidth = atof(str[0].c_str());
|
||||
if ( detLine == 3 ) detGeo.array2.detLength = atof(str[0].c_str());
|
||||
if ( detLine == 4 ) detGeo.array2.blocker = atof(str[0].c_str());
|
||||
if ( detLine == 5 ) detGeo.array2.firstPos = atof(str[0].c_str());
|
||||
if ( detLine == 6 ) detGeo.array2.eSigma = atof(str[0].c_str());
|
||||
if ( detLine == 7 ) detGeo.array2.zSigma = atof(str[0].c_str());
|
||||
if ( detLine == 8 ) detGeo.array2.detFaceOut = str[0] == "Out" ? true : false;
|
||||
if ( detLine == 9 ) detGeo.array2.mDet = atoi(str[0].c_str());
|
||||
if ( detLine >= 10 ) (detGeo.array2.pos).push_back(atof(str[0].c_str()));
|
||||
detLine ++;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
detGeo.array1.DeduceAbsolutePos();
|
||||
|
||||
detGeo.zMin = detGeo.array1.zMin;
|
||||
detGeo.zMax = detGeo.array1.zMax;
|
||||
|
||||
if( detGeo.use2ndArray) {
|
||||
detGeo.array2.DeduceAbsolutePos();
|
||||
|
||||
detGeo.zMin = TMath::Min(detGeo.array1.zMin, detGeo.array2.zMin);
|
||||
detGeo.zMax = TMath::Min(detGeo.array1.zMax, detGeo.array2.zMax);
|
||||
}
|
||||
|
||||
return detGeo;
|
||||
}
|
||||
|
||||
void PrintDetGeo(DetGeo detGeo, bool printAll = true){
|
||||
|
||||
printf("=====================================================\n");
|
||||
printf(" B-field: %8.2f T, Theta : %6.2f deg \n", detGeo.Bfield, detGeo.BfieldTheta);
|
||||
if( detGeo.BfieldTheta != 0.0 ) {
|
||||
printf(" +---- field angle != 0 is not supported!!! \n");
|
||||
}
|
||||
printf(" Recoil detector pos: %8.2f mm, radius: %6.2f - %6.2f mm \n", detGeo.recoilPos, detGeo.recoilInnerRadius, detGeo.recoilOuterRadius);
|
||||
if( printAll ){
|
||||
printf("------------------------------------- Detector Position \n");
|
||||
detGeo.array1.PrintArray();
|
||||
|
||||
if( detGeo.use2ndArray){
|
||||
printf("--------------------------------- 2nd Detector Position \n");
|
||||
detGeo.array2.PrintArray();
|
||||
}
|
||||
}else{
|
||||
if( detGeo.use2ndArray){
|
||||
printf("--------------------------------- 2nd Detector Position \n");
|
||||
detGeo.array2.PrintArray();
|
||||
}else{
|
||||
printf("------------------------------------- Detector Position \n");
|
||||
detGeo.array1.PrintArray();
|
||||
}
|
||||
}
|
||||
|
||||
if( detGeo.elumPos1 != 0 || detGeo.elumPos2 != 0 || detGeo.recoilPos1 != 0 || detGeo.recoilPos2 != 0){
|
||||
printf("=================================== Auxillary/Imaginary Detectors\n");
|
||||
}
|
||||
if( detGeo.elumPos1 != 0 ) printf(" Elum 1 pos.: %f mm \n", detGeo.elumPos1);
|
||||
if( detGeo.elumPos2 != 0 ) printf(" Elum 2 pos.: %f mm \n", detGeo.elumPos2);
|
||||
if( detGeo.recoilPos1 != 0 ) printf(" Recoil 1 pos.: %f mm \n", detGeo.recoilPos1);
|
||||
if( detGeo.recoilPos2 != 0 ) printf(" Recoil 2 pos.: %f mm \n", detGeo.recoilPos2);
|
||||
printf("=====================================================\n");
|
||||
|
||||
}
|
||||
|
||||
ReactionConfig LoadReactionConfig(TMacro * macro){
|
||||
|
||||
ReactionConfig reaction;
|
||||
|
||||
if( macro == NULL ) return reaction;
|
||||
|
||||
int numLine = macro->GetListOfLines()->GetSize();
|
||||
|
||||
for( int i = 0; i < numLine; i ++){
|
||||
|
||||
std::vector<std::string> str = SplitStr(macro->GetListOfLines()->At(i)->GetName(), " ");
|
||||
|
||||
///printf("%d | %s\n", i, str[0].c_str());
|
||||
|
||||
if( str[0].find_first_of("#") == 0 ) break;
|
||||
|
||||
if( i == 0 ) reaction.beamA = atoi(str[0].c_str());
|
||||
if( i == 1 ) reaction.beamZ = atoi(str[0].c_str());
|
||||
if( i == 2 ) reaction.targetA = atoi(str[0].c_str());
|
||||
if( i == 3 ) reaction.targetZ = atoi(str[0].c_str());
|
||||
if( i == 4 ) reaction.recoilLightA = atoi(str[0].c_str());
|
||||
if( i == 5 ) reaction.recoilLightZ = atoi(str[0].c_str());
|
||||
if( i == 6 ) reaction.beamEnergy = atof(str[0].c_str());
|
||||
if( i == 7 ) reaction.beamEnergySigma = atof(str[0].c_str());
|
||||
if( i == 8 ) reaction.beamAngle = atof(str[0].c_str());
|
||||
if( i == 9 ) reaction.beamAngleSigma = atof(str[0].c_str());
|
||||
if( i == 10 ) reaction.beamX = atof(str[0].c_str());
|
||||
if( i == 11 ) reaction.beamY = atof(str[0].c_str());
|
||||
if( i == 12 ) reaction.numEvents = atoi(str[0].c_str());
|
||||
if( i == 13 ) {
|
||||
if( str[0].compare("false") == 0 ) reaction.isTargetScattering = false;
|
||||
if( str[0].compare("true") == 0 ) reaction.isTargetScattering = true;
|
||||
}
|
||||
if( i == 14 ) reaction.targetDensity = atof(str[0].c_str());
|
||||
if( i == 15 ) reaction.targetThickness = atof(str[0].c_str());
|
||||
if( i == 16 ) reaction.beamStoppingPowerFile = str[0];
|
||||
if( i == 17 ) reaction.recoilLightStoppingPowerFile = str[0];
|
||||
if( i == 18 ) reaction.recoilHeavyStoppingPowerFile = str[0];
|
||||
if( i == 19 ) {
|
||||
if( str[0].compare("false") == 0 ) reaction.isDecay = false;
|
||||
if( str[0].compare("true") == 0 ) reaction.isDecay = true;
|
||||
}
|
||||
if( i == 20 ) reaction.heavyDecayA = atoi(str[0].c_str());
|
||||
if( i == 21 ) reaction.heavyDecayZ = atoi(str[0].c_str());
|
||||
if( i == 22 ) {
|
||||
if( str[0].compare("false") == 0 ) reaction.isRedo = false;
|
||||
if( str[0].compare("true" ) == 0 ) reaction.isRedo = true;
|
||||
}
|
||||
|
||||
if( i >= 23) {
|
||||
reaction.beamEx.push_back( atof(str[0].c_str()) );
|
||||
}
|
||||
}
|
||||
|
||||
reaction.recoilHeavyA = reaction.beamA + reaction.targetA - reaction.recoilLightA;
|
||||
reaction.recoilHeavyZ = reaction.beamZ + reaction.targetZ - reaction.recoilLightZ;
|
||||
|
||||
return reaction;
|
||||
|
||||
}
|
||||
|
||||
void PrintReactionConfig(ReactionConfig reaction){
|
||||
|
||||
printf("=====================================================\n");
|
||||
printf(" beam : A = %3d, Z = %2d \n", reaction.beamA, reaction.beamZ);
|
||||
printf(" target : A = %3d, Z = %2d \n", reaction.targetA, reaction.targetZ);
|
||||
printf(" light : A = %3d, Z = %2d \n", reaction.recoilLightA, reaction.recoilLightZ);
|
||||
|
||||
printf(" beam Energy : %.2f +- %.2f MeV/u, dE/E = %5.2f %%\n", reaction.beamEnergy, reaction.beamEnergySigma, reaction.beamEnergySigma/reaction.beamEnergy);
|
||||
printf(" Angle : %.2f +- %.2f mrad\n", reaction.beamAngle, reaction.beamAngleSigma);
|
||||
printf(" offset : (x,y) = (%.2f, %.2f) mmm \n", reaction.beamX, reaction.beamY);
|
||||
|
||||
printf("##### number of Simulation Events : %d \n", reaction.numEvents);
|
||||
|
||||
printf(" is target scattering : %s \n", reaction.isTargetScattering ? "Yes" : "No");
|
||||
|
||||
if(reaction.isTargetScattering){
|
||||
printf(" target density : %.f g/cm3\n", reaction.targetDensity);
|
||||
printf(" thickness : %.f cm\n", reaction.targetThickness);
|
||||
printf(" beam stopping file : %s \n", reaction.beamStoppingPowerFile.c_str());
|
||||
printf(" recoil light stopping file : %s \n", reaction.recoilLightStoppingPowerFile.c_str());
|
||||
printf(" recoil heavy stopping file : %s \n", reaction.recoilHeavyStoppingPowerFile.c_str());
|
||||
}
|
||||
|
||||
printf(" is simulate decay : %s \n", reaction.isDecay ? "Yes" : "No");
|
||||
if( reaction.isDecay ){
|
||||
printf(" heavy decay : A = %d, Z = %d \n", reaction.heavyDecayA, reaction.heavyDecayZ);
|
||||
}
|
||||
printf(" is Redo until hit array : %s \n", reaction.isRedo ? "Yes" : "No");
|
||||
|
||||
printf(" beam Ex : %.2f MeV \n", reaction.beamEx[0]);
|
||||
for( int i = 1; i < (int) reaction.beamEx.size(); i++){
|
||||
printf(" %.2f MeV \n", reaction.beamEx[i]);
|
||||
}
|
||||
|
||||
printf("=====================================================\n");
|
||||
|
||||
}
|
||||
|
||||
DetGeo detGeo;
|
||||
ReactionConfig reactionConfig1;
|
||||
ReactionConfig reactionConfig2;
|
||||
|
||||
void LoadDetGeoAndReactionConfigFile(std::string detGeoFileName = "detectorGeo.txt",
|
||||
std::string reactionConfigFileName1 = "reactionConfig1.txt",
|
||||
std::string reactionConfigFileName2 = "reactionConfig2.txt"){
|
||||
printf("=====================================================\n");
|
||||
printf(" loading detector geometery : %s.", detGeoFileName.c_str());
|
||||
TMacro * haha = new TMacro();
|
||||
if( haha->ReadFile(detGeoFileName.c_str()) > 0 ) {
|
||||
detGeo = AnalysisLib::LoadDetectorGeo(haha);
|
||||
printf("... done.\n");
|
||||
AnalysisLib::PrintDetGeo(detGeo);
|
||||
}else{
|
||||
printf("... fail\n");
|
||||
}
|
||||
delete haha;
|
||||
|
||||
printf("=====================================================\n");
|
||||
printf(" loading reaction1 config : %s.", reactionConfigFileName1.c_str());
|
||||
TMacro * kaka = new TMacro();
|
||||
if( kaka->ReadFile(reactionConfigFileName1.c_str()) > 0 ) {
|
||||
reactionConfig1 = AnalysisLib::LoadReactionConfig(kaka);
|
||||
printf("..... done.\n");
|
||||
AnalysisLib::PrintReactionConfig(reactionConfig1);
|
||||
}else{
|
||||
printf("..... fail\n");
|
||||
}
|
||||
delete kaka;
|
||||
|
||||
if( detGeo.use2ndArray){
|
||||
printf("=====================================================\n");
|
||||
printf(" loading reaction2 config : %s.", reactionConfigFileName2.c_str());
|
||||
TMacro * jaja = new TMacro();
|
||||
if( jaja->ReadFile(reactionConfigFileName2.c_str()) > 0 ) {
|
||||
reactionConfig2 = AnalysisLib::LoadReactionConfig(kaka);
|
||||
printf("..... done.\n");
|
||||
AnalysisLib::PrintReactionConfig(reactionConfig2);
|
||||
}else{
|
||||
printf("..... fail\n");
|
||||
}
|
||||
delete jaja;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//************************************** Correction parameters;
|
||||
|
||||
std::vector<float> xnCorr; //correction of xn to match xf
|
||||
std::vector<float> xScale; // correction of x to be (0,1)
|
||||
std::vector<std::vector<float>> xfxneCorr; //correction of xn and xf to match e
|
||||
std::vector<std::vector<float>> eCorr; // correction to e, ch -> MeV
|
||||
std::vector<std::vector<float>> rdtCorr; // correction of rdt, ch -> MeV
|
||||
|
||||
//~========================================= xf = xn correction
|
||||
void LoadXNCorr(bool verbose = false, const char * fileName = "correction_xf_xn.dat"){
|
||||
printf(" loading xf-xn correction.");
|
||||
xnCorr.clear();
|
||||
std::ifstream file;
|
||||
file.open(fileName);
|
||||
if( file.is_open() ){
|
||||
float a;
|
||||
while( file >> a ) xnCorr.push_back(a);
|
||||
printf(".......... done.\n");
|
||||
}else{
|
||||
printf(".......... fail.\n");
|
||||
}
|
||||
file.close();
|
||||
if( verbose ) for(int i = 0; i < (int) xnCorr.size(); i++) printf("%2d | %10.3f\n", i, xnCorr[i]);
|
||||
}
|
||||
|
||||
|
||||
//~========================================= X-Scale correction
|
||||
void LoadXScaleCorr(bool verbose = false, const char * fileName = "correction_scaleX.dat"){
|
||||
printf(" loading x-Scale correction.");
|
||||
xScale.clear();
|
||||
std::ifstream file;
|
||||
file.open(fileName);
|
||||
if( file.is_open() ){
|
||||
float a, b;
|
||||
while( file >> a ) xScale.push_back(a);
|
||||
printf("........ done.\n");
|
||||
}else{
|
||||
printf("........ fail.\n");
|
||||
}
|
||||
file.close();
|
||||
if( verbose ) for(int i = 0; i < (int) xScale.size(); i++) printf("%2d | %10.3f\n", i, xnCorr[i]);
|
||||
}
|
||||
|
||||
//~========================================= e = xf + xn correction
|
||||
void LoadXFXN2ECorr(bool verbose = false, const char * fileName = "correction_xfxn_e.dat"){
|
||||
printf(" loading xf/xn-e correction.");
|
||||
xfxneCorr.clear();
|
||||
std::ifstream file;
|
||||
file.open(fileName);
|
||||
if( file.is_open() ){
|
||||
float a, b;
|
||||
while( file >> a >> b) xfxneCorr.push_back({a, b});
|
||||
printf("........ done.\n");
|
||||
}else{
|
||||
printf("........ fail.\n");
|
||||
}
|
||||
file.close();
|
||||
if( verbose ) for(int i = 0; i < (int) xfxneCorr.size(); i++) printf("%2d | %10.3f, %10.3f\n", i, xfxneCorr[i][0], xfxneCorr[i][1]);
|
||||
}
|
||||
|
||||
//~========================================= e correction
|
||||
void LoadECorr(bool verbose = false, const char * fileName = "correction_e.dat"){
|
||||
printf(" loading e correction.");
|
||||
eCorr.clear();
|
||||
std::ifstream file;
|
||||
file.open(fileName);
|
||||
if( file.is_open() ){
|
||||
float a, b;
|
||||
while( file >> a >> b) eCorr.push_back( {a, b} ); // 1/a1, a0 , e' = e * a1 + a0
|
||||
printf(".............. done.\n");
|
||||
}else{
|
||||
printf(".............. fail.\n");
|
||||
}
|
||||
file.close();
|
||||
if( verbose ) for(int i = 0; i < (int) eCorr.size(); i++) printf("%2d | %10.3f, %10.3f\n", i, eCorr[i][0], eCorr[i][1]);
|
||||
}
|
||||
|
||||
//~========================================= rdt correction
|
||||
void LoadRDTCorr(bool verbose = false, const char * fileName = "correction_rdt.dat"){
|
||||
printf(" loading rdt correction.");
|
||||
rdtCorr.clear();
|
||||
std::ifstream file;
|
||||
file.open(fileName);
|
||||
if( file.is_open() ){
|
||||
float a, b;
|
||||
while( file >> a >> b) rdtCorr.push_back({a, b});
|
||||
printf("............ done.\n");
|
||||
}else{
|
||||
printf("............ fail.\n");
|
||||
}
|
||||
file.close();
|
||||
if( verbose ) for(int i = 0; i < (int) rdtCorr.size(); i++) printf("%2d | %10.3f, %10.3f\n", i, rdtCorr[i][0], rdtCorr[i][1]);
|
||||
}
|
||||
|
||||
|
||||
struct ReactionParas{
|
||||
|
||||
double Et; // total energy in CM frame
|
||||
double beta; // Lorentz beta from Lab to CM
|
||||
double gamma; // Lorentz gamma from Lab to CM
|
||||
double alpha; // E-Z slope / beta
|
||||
double G; //The G-coefficient....
|
||||
double massB; // heavy mass
|
||||
double q; // charge of light particle
|
||||
double mass; //light mass
|
||||
bool hasReactionPara;
|
||||
|
||||
double detPrepDist;
|
||||
|
||||
};
|
||||
|
||||
ReactionParas reactParas1;
|
||||
ReactionParas reactParas2;
|
||||
|
||||
//~========================================= reaction parameters
|
||||
void LoadReactionParas(int arrayID, bool verbose = false){
|
||||
|
||||
//check is the transfer.root is using the latest reactionConfig.txt
|
||||
//sicne reaction.dat is generated as a by-product of transfer.root
|
||||
//TFile * transfer = new TFile("transfer.root");
|
||||
//TString aaa1 = "";
|
||||
//TString aaa2 = "";
|
||||
//if( transfer->IsOpen() ){
|
||||
// TMacro * reactionConfig = (TMacro *) transfer->FindObjectAny("reactionConfig");
|
||||
// TMacro presentReactionConfig ("reactionConfig.txt");
|
||||
// aaa1 = ((TMD5*) reactionConfig->Checksum())->AsString();
|
||||
// aaa2 = ((TMD5*) presentReactionConfig.Checksum())->AsString();
|
||||
//}
|
||||
//printf("%s\n", aaa1.Data());
|
||||
//printf("%s\n", aaa2.Data());
|
||||
|
||||
//if( aaa1 != aaa2 ) {
|
||||
// printf("########################## recalculate transfer.root \n");
|
||||
// system("../Cleopatra/Transfer");
|
||||
// printf("########################## transfer.root updated\n");
|
||||
//}
|
||||
|
||||
ReactionParas * reactParas = nullptr;
|
||||
|
||||
std::string fileName;
|
||||
|
||||
if( arrayID == 1){
|
||||
reactParas = &AnalysisLib::reactParas1;
|
||||
fileName = "reaction.dat";
|
||||
}else if( arrayID == 2){
|
||||
reactParas = &AnalysisLib::reactParas2;
|
||||
fileName = "reaction2.dat";
|
||||
}else{
|
||||
printf("arrayID must be either 1 or 2. Abort.\n");
|
||||
return;
|
||||
}
|
||||
reactParas->detPrepDist = AnalysisLib::detGeo.array1.detPerpDist;
|
||||
|
||||
printf(" loading reaction parameters");
|
||||
std::ifstream file;
|
||||
file.open(fileName.c_str());
|
||||
reactParas->hasReactionPara = false;
|
||||
if( file.is_open() ){
|
||||
std::string x;
|
||||
int i = 0;
|
||||
while( file >> x ){
|
||||
if( x.substr(0,2) == "//" ) continue;
|
||||
if( i == 0 ) reactParas->mass = atof(x.c_str());
|
||||
if( i == 1 ) reactParas->q = atof(x.c_str());
|
||||
if( i == 2 ) reactParas->beta = atof(x.c_str());
|
||||
if( i == 3 ) reactParas->Et = atof(x.c_str());
|
||||
if( i == 4 ) reactParas->massB = atof(x.c_str());
|
||||
i = i + 1;
|
||||
}
|
||||
printf("........ done.\n");
|
||||
|
||||
reactParas->hasReactionPara = true;
|
||||
reactParas->alpha = 299.792458 * abs(detGeo.Bfield) * reactParas->q / TMath::TwoPi()/1000.; //MeV/mm
|
||||
reactParas->gamma = 1./TMath::Sqrt(1-reactParas->beta * reactParas->beta);
|
||||
reactParas->G = reactParas->alpha * reactParas->gamma * reactParas->beta * reactParas->detPrepDist ;
|
||||
|
||||
if( verbose ){
|
||||
printf("\tmass-b : %f MeV/c2 \n", reactParas->mass);
|
||||
printf("\tcharge-b : %f \n", reactParas->q);
|
||||
printf("\tE-total : %f MeV \n", reactParas->Et);
|
||||
printf("\tmass-B : %f MeV/c2 \n", reactParas->massB);
|
||||
printf("\tbeta : %f \n", reactParas->beta);
|
||||
printf("\tB-field : %f T \n", detGeo.Bfield);
|
||||
printf("\tslope : %f MeV/mm \n", reactParas->alpha * reactParas->beta);
|
||||
printf("\tdet radius: %f mm \n", reactParas->detPrepDist);
|
||||
printf("\tG-coeff : %f MeV \n", reactParas->G);
|
||||
printf("=====================================================\n");
|
||||
}
|
||||
|
||||
}else{
|
||||
printf("........ fail.\n");
|
||||
}
|
||||
file.close();
|
||||
|
||||
}
|
||||
|
||||
std::vector<double> CalExTheta(double e, double z){
|
||||
|
||||
ReactionParas * reactParas = nullptr;
|
||||
|
||||
if( detGeo.array1.zMin <= z && z <= detGeo.array1.zMax ){
|
||||
reactParas = &reactParas1;
|
||||
if( !reactParas->hasReactionPara) return {TMath::QuietNaN(), TMath::QuietNaN()};
|
||||
}
|
||||
|
||||
if( detGeo.array2.zMin <= z && z <= detGeo.array2.zMax ){
|
||||
reactParas = &reactParas2;
|
||||
if( !reactParas->hasReactionPara) return {TMath::QuietNaN(), TMath::QuietNaN()};
|
||||
}
|
||||
|
||||
double Ex = TMath::QuietNaN();
|
||||
double thetaCM = TMath::QuietNaN();
|
||||
|
||||
double y = e + reactParas->mass; // to give the KE + mass of proton;
|
||||
double Z = reactParas->alpha * reactParas->gamma * reactParas->beta * z;
|
||||
double H = TMath::Sqrt(TMath::Power(reactParas->gamma * reactParas->beta,2) * (y*y - reactParas->mass * reactParas->mass) ) ;
|
||||
|
||||
if( TMath::Abs(Z) < H ) {
|
||||
///using Newton's method to solve 0 == H * sin(phi) - G * tan(phi) - Z = f(phi)
|
||||
double tolerrence = 0.001;
|
||||
double phi = 0; ///initial phi = 0 -> ensure the solution has f'(phi) > 0
|
||||
double nPhi = 0; /// new phi
|
||||
|
||||
int iter = 0;
|
||||
do{
|
||||
phi = nPhi;
|
||||
nPhi = phi - (H * TMath::Sin(phi) - reactParas->G * TMath::Tan(phi) - Z) / (H * TMath::Cos(phi) - reactParas->G /TMath::Power( TMath::Cos(phi), 2));
|
||||
iter ++;
|
||||
if( iter > 10 || TMath::Abs(nPhi) > TMath::PiOver2()) break;
|
||||
}while( TMath::Abs(phi - nPhi ) > tolerrence);
|
||||
phi = nPhi;
|
||||
|
||||
/// check f'(phi) > 0
|
||||
double Df = H * TMath::Cos(phi) - reactParas->G / TMath::Power( TMath::Cos(phi),2);
|
||||
if( Df > 0 && TMath::Abs(phi) < TMath::PiOver2() ){
|
||||
double K = H * TMath::Sin(phi);
|
||||
double x = TMath::ACos( reactParas->mass / ( y * reactParas->gamma - K));
|
||||
double momt = reactParas->mass * TMath::Tan(x); /// momentum of particel b or B in CM frame
|
||||
double EB = TMath::Sqrt(reactParas->mass * reactParas->mass + reactParas->Et * reactParas->Et - 2 * reactParas->Et * TMath::Sqrt(momt*momt + reactParas->mass * reactParas->mass));
|
||||
Ex = EB - reactParas->massB;
|
||||
|
||||
double hahaha1 = reactParas->gamma * TMath::Sqrt(reactParas->mass * reactParas->mass + momt * momt) - y;
|
||||
double hahaha2 = reactParas->gamma * reactParas->beta * momt;
|
||||
thetaCM = TMath::ACos(hahaha1/hahaha2) * TMath::RadToDeg();
|
||||
|
||||
}
|
||||
}
|
||||
return {Ex, thetaCM};
|
||||
|
||||
}
|
||||
|
||||
//************************************** TCutG
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user