2024-02-13 18:24:56 -05:00
|
|
|
#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{
|
2024-02-15 16:36:45 -05:00
|
|
|
double theta, phi;
|
|
|
|
double vt, vp; // tranvser and perpendicular velocity
|
|
|
|
double rho; // orbit radius
|
|
|
|
double z0, t0; // position cycle
|
|
|
|
double x, y, z; // hit position
|
|
|
|
double t; //actual orbit time;
|
|
|
|
double R; //hit radius = sqrt(x^2+y^2);
|
|
|
|
int detID, detRowID;
|
|
|
|
int loop;
|
|
|
|
double effLoop;
|
|
|
|
|
|
|
|
void PrintTrajectory(){
|
|
|
|
printf("=====================\n");
|
|
|
|
printf(" theta : %f deg\n", theta*TMath::RadToDeg());
|
|
|
|
printf(" phi : %f deg\n", phi*TMath::RadToDeg());
|
|
|
|
printf(" vt : %f mm/ns\n", vt);
|
|
|
|
printf(" vp : %f mm/ns\n", vp);
|
|
|
|
printf(" rho : %f mm\n", rho);
|
|
|
|
printf(" z0 : %f mm\n", z0);
|
|
|
|
printf(" t0 : %f ns\n", t0);
|
|
|
|
printf("(x, y, z) : (%f, %f. %f) mm\n", x, y, z);
|
|
|
|
printf(" R : %f mm\n", R);
|
|
|
|
printf(" t : %f ns\n", t);
|
|
|
|
printf(" effLoop : %f cycle\n", effLoop);
|
|
|
|
printf(" Loop : %d cycle\n", loop);
|
|
|
|
printf(" detRowID : %d \n", detRowID);
|
|
|
|
printf(" detID : %d \n", detID);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
void Clear(){
|
|
|
|
theta = TMath::QuietNaN();
|
|
|
|
phi = TMath::QuietNaN();
|
|
|
|
vt = TMath::QuietNaN();
|
|
|
|
vp = TMath::QuietNaN();
|
|
|
|
rho = TMath::QuietNaN();
|
|
|
|
z0 = TMath::QuietNaN();
|
|
|
|
t0 = TMath::QuietNaN();
|
|
|
|
x = TMath::QuietNaN();
|
|
|
|
y = TMath::QuietNaN();
|
|
|
|
z = TMath::QuietNaN();
|
|
|
|
effLoop = TMath::QuietNaN();
|
|
|
|
detID = -1;
|
|
|
|
detRowID = -1;
|
|
|
|
loop = -1;
|
|
|
|
}
|
2024-02-13 18:24:56 -05:00
|
|
|
};
|
|
|
|
|
|
|
|
class HELIOS{
|
|
|
|
public:
|
|
|
|
|
2024-02-15 16:36:45 -05:00
|
|
|
HELIOS();
|
2024-02-20 16:38:40 -05:00
|
|
|
HELIOS(std::string filename, unsigned short ID);
|
2024-02-15 16:36:45 -05:00
|
|
|
~HELIOS();
|
|
|
|
|
|
|
|
void SetCoincidentWithRecoil(bool TorF){ this->isCoincidentWithRecoil = TorF;}
|
|
|
|
bool GetCoincidentWithRecoil(){return this->isCoincidentWithRecoil;}
|
|
|
|
bool SetDetectorGeometry(std::string filename, unsigned short ID);
|
|
|
|
void SetBeamPosition(double x, double y) { xOff = x; yOff = y;}
|
|
|
|
|
|
|
|
void OverrideMagneticField(double BField);
|
|
|
|
void OverrideMagneticFieldDirection(double BfieldThetaInDeg);
|
|
|
|
void OverrideFirstPos(double firstPos);
|
|
|
|
void OverrideDetectorDistance(double perpDist);
|
|
|
|
void OverrideDetectorFacing(bool isOutside);
|
|
|
|
|
|
|
|
int CheckDetAcceptance();
|
|
|
|
int CalArrayHit(TLorentzVector Pb, bool debug = false);
|
|
|
|
int CalRecoilHit(TLorentzVector PB);
|
|
|
|
void CalTrajectoryPara(TLorentzVector P, bool isLightRecoil);
|
|
|
|
|
|
|
|
int GetNumberOfDetectorsInSamePos(){return array.mDet;}
|
|
|
|
double GetEnergy()const {return e;}
|
|
|
|
double GetDetX() const {return detX;} // position in each detector, range from -1, 1
|
|
|
|
|
|
|
|
/// clockwise rotation for B-field along the z-axis, sign = 1.
|
|
|
|
double XPos(double Zpos, double theta, double phi, double rho, int sign){
|
|
|
|
if( TMath::IsNaN(Zpos) ) return TMath::QuietNaN();
|
|
|
|
return rho * ( TMath::Sin( TMath::Tan(theta) * Zpos / rho - sign * phi ) + sign * TMath::Sin(phi) ) + xOff;
|
|
|
|
}
|
|
|
|
double YPos(double Zpos, double theta, double phi, double rho, int sign){
|
|
|
|
if( TMath::IsNaN(Zpos) ) return TMath::QuietNaN();
|
|
|
|
return rho * sign * (TMath::Cos( TMath::Tan(theta) * Zpos / rho - sign * phi ) - TMath::Cos(phi)) + yOff;
|
|
|
|
}
|
|
|
|
double RPos(double Zpos, double theta, double phi, double rho, int sign){
|
2024-02-14 16:30:13 -05:00
|
|
|
if( TMath::IsNaN(Zpos) ) return TMath::QuietNaN();
|
|
|
|
double x = XPos(Zpos, theta, phi, rho, sign) ;
|
|
|
|
double y = YPos(Zpos, theta, phi, rho, sign) ;
|
|
|
|
return sqrt(x*x+y*y);
|
2024-02-15 16:36:45 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
double GetXPos(double ZPos){ return TMath::IsNaN(ZPos) ? TMath::QuietNaN() : XPos( ZPos, orbitb.theta, orbitb.phi, orbitb.rho, detGeo.BfieldSign); }
|
|
|
|
double GetYPos(double ZPos){ return TMath::IsNaN(ZPos) ? TMath::QuietNaN() : YPos( ZPos, orbitb.theta, orbitb.phi, orbitb.rho, detGeo.BfieldSign); }
|
|
|
|
double GetR(double ZPos) { return TMath::IsNaN(ZPos) ? TMath::QuietNaN() : RPos( ZPos, orbitb.theta, orbitb.phi, orbitb.rho, detGeo.BfieldSign); }
|
|
|
|
|
|
|
|
double GetRecoilEnergy(){return eB;}
|
|
|
|
double GetRecoilXPos(double ZPos){ return TMath::IsNaN(ZPos) ? TMath::QuietNaN() : XPos( ZPos, orbitB.theta, orbitB.phi, orbitB.rho, detGeo.BfieldSign); }
|
|
|
|
double GetRecoilYPos(double ZPos){ return TMath::IsNaN(ZPos) ? TMath::QuietNaN() : YPos( ZPos, orbitB.theta, orbitB.phi, orbitB.rho, detGeo.BfieldSign); }
|
|
|
|
double GetRecoilR(double ZPos) { return TMath::IsNaN(ZPos) ? TMath::QuietNaN() : RPos( ZPos, orbitB.theta, orbitB.phi, orbitB.rho, detGeo.BfieldSign); }
|
|
|
|
|
|
|
|
void PrintGeometry() const;
|
2024-02-13 18:24:56 -05:00
|
|
|
|
2024-02-15 16:36:45 -05:00
|
|
|
double GetBField() const {return detGeo.Bfield;}
|
|
|
|
double GetDetRadius() const {return array.detPerpDist;}
|
2024-02-14 16:30:13 -05:00
|
|
|
|
2024-02-15 16:36:45 -05:00
|
|
|
trajectory GetTrajectory_b() const {return orbitb;}
|
|
|
|
trajectory GetTrajectory_B() const {return orbitB;}
|
|
|
|
|
|
|
|
DetGeo GetDetectorGeometry() const {return detGeo;}
|
2024-02-19 18:31:27 -05:00
|
|
|
Array GetArrayGeometry() const {return array;}
|
2024-02-15 16:36:45 -05:00
|
|
|
|
2024-02-19 18:31:27 -05:00
|
|
|
TString GetHitMessage() {return hitMessage;}
|
|
|
|
TString GetAcceptanceMessage() { AcceptanceCodeToMsg(acceptanceCode); return acceptanceMsg;}
|
2024-02-15 16:36:45 -05:00
|
|
|
|
2024-02-19 18:31:27 -05:00
|
|
|
TString AcceptanceCodeToMsg(short code );
|
|
|
|
|
2024-02-13 18:24:56 -05:00
|
|
|
private:
|
|
|
|
|
2024-02-19 18:31:27 -05:00
|
|
|
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;
|
|
|
|
|
|
|
|
TString hitMessage;
|
|
|
|
TString acceptanceMsg; //acceptance check
|
|
|
|
short acceptanceCode;
|
|
|
|
|
|
|
|
double xOff, yOff; // beam position
|
|
|
|
|
|
|
|
bool overrideDetDistance;
|
|
|
|
bool overrideFirstPos;
|
|
|
|
bool isCoincidentWithRecoil;
|
|
|
|
|
|
|
|
const double c = 299.792458; //mm/ns
|
2024-02-14 16:30:13 -05:00
|
|
|
|
2024-02-20 16:38:40 -05:00
|
|
|
void Clear();
|
2024-02-13 18:24:56 -05:00
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
HELIOS::HELIOS(){
|
2024-02-20 16:38:40 -05:00
|
|
|
Clear();
|
|
|
|
}
|
|
|
|
|
|
|
|
HELIOS::HELIOS(std::string filename, unsigned short ID){
|
|
|
|
Clear();
|
|
|
|
SetDetectorGeometry(filename, ID);
|
|
|
|
}
|
|
|
|
|
|
|
|
HELIOS::~HELIOS(){
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
void HELIOS::Clear(){
|
|
|
|
|
2024-02-15 16:36:45 -05:00
|
|
|
orbitb.Clear();
|
|
|
|
orbitB.Clear();
|
2024-02-13 18:24:56 -05:00
|
|
|
|
2024-02-15 16:36:45 -05:00
|
|
|
e = TMath::QuietNaN();
|
|
|
|
eB = TMath::QuietNaN();
|
|
|
|
detX = TMath::QuietNaN();
|
|
|
|
rhoHit = TMath::QuietNaN();
|
|
|
|
|
|
|
|
xOff = 0.0;
|
|
|
|
yOff = 0.0;
|
|
|
|
|
|
|
|
isDetReady = false;
|
2024-02-13 18:24:56 -05:00
|
|
|
|
2024-02-15 16:36:45 -05:00
|
|
|
hitMessage = "";
|
2024-02-19 18:31:27 -05:00
|
|
|
acceptanceMsg = "";
|
|
|
|
acceptanceCode = 0;
|
2024-02-14 16:30:13 -05:00
|
|
|
|
2024-02-15 16:36:45 -05:00
|
|
|
overrideDetDistance = false;
|
|
|
|
overrideFirstPos = false;
|
|
|
|
isCoincidentWithRecoil = false;
|
2024-02-13 18:24:56 -05:00
|
|
|
}
|
|
|
|
|
2024-02-15 16:36:45 -05:00
|
|
|
void HELIOS::OverrideMagneticField(double BField){
|
|
|
|
this->detGeo.Bfield = BField;
|
|
|
|
this->detGeo.BfieldSign = BField > 0 ? 1: -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
void HELIOS::OverrideMagneticFieldDirection(double BfieldThetaInDeg){
|
|
|
|
this->detGeo.BfieldTheta = BfieldThetaInDeg;
|
|
|
|
}
|
2024-02-13 18:24:56 -05:00
|
|
|
|
2024-02-15 16:36:45 -05:00
|
|
|
void HELIOS::OverrideFirstPos(double firstPos){
|
|
|
|
overrideFirstPos = true;
|
|
|
|
printf("------ Overriding FirstPosition to : %8.2f mm \n", firstPos);
|
|
|
|
this->array.firstPos = firstPos;
|
|
|
|
}
|
2024-02-13 18:24:56 -05:00
|
|
|
|
2024-02-15 16:36:45 -05:00
|
|
|
void HELIOS::OverrideDetectorDistance(double perpDist){
|
|
|
|
overrideDetDistance = true;
|
|
|
|
printf("------ Overriding Detector Distance to : %8.2f mm \n", perpDist);
|
|
|
|
this->array.detPerpDist = perpDist;
|
|
|
|
}
|
2024-02-13 18:24:56 -05:00
|
|
|
|
2024-02-15 16:36:45 -05:00
|
|
|
void HELIOS::OverrideDetectorFacing(bool isOutside){
|
|
|
|
this->array.detFaceOut = isOutside;
|
|
|
|
printf(" Detectors are facing %s\n", array.detFaceOut ? "outside": "inside" );
|
|
|
|
}
|
|
|
|
|
|
|
|
bool HELIOS::SetDetectorGeometry(std::string filename, unsigned short ID){
|
2024-02-13 18:24:56 -05:00
|
|
|
|
2024-02-15 16:36:45 -05:00
|
|
|
if( detGeo.LoadDetectorGeo(filename, false)) {
|
|
|
|
|
|
|
|
array = detGeo.array[ID];
|
|
|
|
isCoincidentWithRecoil = detGeo.isCoincidentWithRecoil;
|
2024-02-13 18:24:56 -05:00
|
|
|
isDetReady = true;
|
2024-02-15 16:36:45 -05:00
|
|
|
|
|
|
|
}else{
|
2024-02-13 18:24:56 -05:00
|
|
|
printf("cannot read file %s.\n", filename.c_str());
|
|
|
|
isDetReady = false;
|
2024-02-15 16:36:45 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
return isDetReady;
|
|
|
|
}
|
|
|
|
|
|
|
|
void HELIOS::PrintGeometry() const{
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
|
|
|
printf("----------------------------------- Detector Position \n");
|
|
|
|
array.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");
|
|
|
|
|
|
|
|
|
2024-02-13 18:24:56 -05:00
|
|
|
}
|
|
|
|
|
2024-02-19 18:31:27 -05:00
|
|
|
TString HELIOS::AcceptanceCodeToMsg(short code ){
|
|
|
|
|
|
|
|
switch(code){
|
|
|
|
case 3 : acceptanceMsg = "try one more loop"; break;
|
|
|
|
case 2 : acceptanceMsg = "hit less than the nearest array. increase loop"; break;
|
|
|
|
case 1 : acceptanceMsg = "GOOD!! hit Array"; break;
|
|
|
|
|
|
|
|
case 0 : acceptanceMsg = "detector geometry incomplete."; break;
|
|
|
|
case -1 : acceptanceMsg = "array at upstream, z is downstream."; break;
|
|
|
|
case -2 : acceptanceMsg = "array at downstream, z is upstream."; break;
|
|
|
|
case -3 : acceptanceMsg = "hit at the XY gap."; break;
|
|
|
|
case -4 : acceptanceMsg = "hit more upstream than the array length"; break;
|
|
|
|
case -5 : acceptanceMsg = "hit more downstream than the array length"; break;
|
|
|
|
case -6 : acceptanceMsg = "hit blocker"; break;
|
|
|
|
case -7 : acceptanceMsg = "hit array Z-gap"; break;
|
|
|
|
|
|
|
|
case -10 : acceptanceMsg = "rho is too big"; break;
|
|
|
|
case -11 : acceptanceMsg = "rho is too small"; break;
|
|
|
|
case -12 : acceptanceMsg = "light recoil blocked by recoil detector"; break;
|
|
|
|
case -13 : acceptanceMsg = "more than 3 loops."; break;
|
|
|
|
case -14 : acceptanceMsg = "heavy recoil does not hit recoil detector"; break;
|
|
|
|
case -15 : acceptanceMsg = "det Row ID == -1"; break;
|
|
|
|
default : acceptanceMsg = "unknown error."; break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return acceptanceMsg;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2024-02-15 16:36:45 -05:00
|
|
|
int HELIOS::CheckDetAcceptance(){
|
2024-02-13 18:24:56 -05:00
|
|
|
|
2024-02-19 18:31:27 -05:00
|
|
|
//CalArrayHit and CalRecoilHit must be done before.
|
|
|
|
|
|
|
|
if( isDetReady == false ) { acceptanceCode = 0; return acceptanceCode; }
|
2024-02-13 18:24:56 -05:00
|
|
|
|
2024-02-19 18:31:27 -05:00
|
|
|
// -1 ========= when recoil direction is not same side of array
|
|
|
|
if( array.firstPos < 0 && orbitb.z > 0 ) {acceptanceCode = -1; return acceptanceCode;}
|
|
|
|
|
|
|
|
// -2 ========= when recoil direction is not same side of array
|
|
|
|
if( array.firstPos > 0 && orbitb.z < 0 ) {acceptanceCode = -2; return acceptanceCode;}
|
2024-02-13 18:24:56 -05:00
|
|
|
|
2024-02-19 18:31:27 -05:00
|
|
|
// -11 ======== rho is too small
|
|
|
|
if( 2 * orbitb.rho < array.detPerpDist ) { acceptanceCode = -11; return acceptanceCode;}
|
|
|
|
|
|
|
|
// -15 ========= if detRowID == -1, should be (2 * orbitb.rho < perpDist)
|
|
|
|
if( orbitb.detRowID == -1 ) {acceptanceCode = -15; return acceptanceCode;}
|
|
|
|
|
|
|
|
// -10 =========== when rho is too big .
|
|
|
|
if( detGeo.bore < 2 * orbitb.rho) { acceptanceCode = -10; return acceptanceCode;}
|
|
|
|
|
|
|
|
// -14 ========== check particle-B hit radius on recoil dectector
|
|
|
|
if( isCoincidentWithRecoil && orbitB.R > detGeo.recoilOuterRadius ) {acceptanceCode = -14; return acceptanceCode;}
|
|
|
|
|
|
|
|
//if( isCoincidentWithRecoil && (orbitB.R > rhoRecoilout || orbitB.R < rhoRecoilin) ) return -14;
|
|
|
|
|
|
|
|
// -12 ========= check is particle-b was blocked by recoil detector
|
|
|
|
rhoHit = GetR(detGeo.recoilPos);
|
|
|
|
if( orbitb.z > 0 && detGeo.recoilPos > 0 && orbitb.z > detGeo.recoilPos && rhoHit < detGeo.recoilOuterRadius ) { acceptanceCode = -12; return acceptanceCode;}
|
|
|
|
if( orbitb.z < 0 && detGeo.recoilPos < 0 && orbitb.z < detGeo.recoilPos && rhoHit < detGeo.recoilOuterRadius ) { acceptanceCode = -12; return acceptanceCode;}
|
|
|
|
|
|
|
|
// -13 ========= not more than 3 loops
|
|
|
|
if( orbitb.loop > 3 ) {acceptanceCode = -13; return acceptanceCode;}
|
|
|
|
|
|
|
|
// -3 ========= calculate the "y"-distance from detector center
|
|
|
|
if( sqrt(orbitb.R*orbitb.R - array.detPerpDist * array.detPerpDist)> array.detWidth/2 ) { acceptanceCode = -3; return acceptanceCode;}
|
|
|
|
|
|
|
|
// -4, -5 ==== when zPos further the range of whole array, more loop would not save
|
|
|
|
if( array.firstPos < 0 && orbitb.z < array.detPos[0] - array.detLength ) { acceptanceCode = -4; return acceptanceCode;}
|
|
|
|
if( array.firstPos > 0 && orbitb.z > array.detPos[array.nDet-1] + array.detLength ) { acceptanceCode = -5; return acceptanceCode;}
|
|
|
|
|
|
|
|
// -6 ======== Hit on blacker
|
|
|
|
if( array.blocker != 0 && array.firstPos > 0 && array.detPos[0] - array.blocker < orbitb.z && orbitb.z < array.detPos[0] ) {acceptanceCode = -6; return acceptanceCode;}
|
|
|
|
if( array.blocker != 0 && array.firstPos < 0 && array.detPos[array.nDet-1] < orbitb.z && orbitb.z < array.detPos[array.nDet-1] + array.blocker ) { acceptanceCode = -6; return acceptanceCode;}
|
|
|
|
|
|
|
|
// 2 ====== when zPos less then the nearest position, more loop may hit
|
|
|
|
int increaseLoopFlag = 0;
|
|
|
|
if( array.firstPos < 0 && array.detPos[array.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;
|
|
|
|
acceptanceCode = 2;
|
|
|
|
return acceptanceCode;
|
|
|
|
}
|
2024-02-13 18:24:56 -05:00
|
|
|
|
2024-02-19 18:31:27 -05:00
|
|
|
// 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
|
|
|
|
acceptanceCode = 1;
|
|
|
|
return acceptanceCode;
|
2024-02-13 18:24:56 -05:00
|
|
|
}
|
2024-02-19 18:31:27 -05:00
|
|
|
}
|
|
|
|
}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
|
|
|
|
acceptanceCode = 1;
|
|
|
|
return acceptanceCode;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2024-02-13 18:24:56 -05:00
|
|
|
|
|
|
|
|
2024-02-19 18:31:27 -05:00
|
|
|
// -7 ======== 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 ) { acceptanceCode = -7; return acceptanceCode; }//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] ) { acceptanceCode = -7; return acceptanceCode; }//increaseLoopFlag = 3;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (increaseLoopFlag == 3 ) {
|
|
|
|
orbitb.z += orbitb.z0;
|
|
|
|
orbitb.effLoop += 1.0;
|
|
|
|
orbitb.loop += 1;
|
|
|
|
orbitb.t = orbitb.t0 * orbitb.effLoop;
|
|
|
|
acceptanceCode = 3;
|
|
|
|
return acceptanceCode;
|
|
|
|
}
|
2024-02-13 18:24:56 -05:00
|
|
|
|
2024-02-19 18:31:27 -05:00
|
|
|
acceptanceCode = -20 ;
|
|
|
|
return acceptanceCode; // for unknown reason
|
2024-02-13 18:24:56 -05:00
|
|
|
}
|
|
|
|
|
2024-02-15 16:36:45 -05:00
|
|
|
void HELIOS::CalTrajectoryPara(TLorentzVector P, bool isLightRecoil){
|
2024-02-13 18:24:56 -05:00
|
|
|
|
2024-02-14 16:30:13 -05:00
|
|
|
if( isLightRecoil ){
|
2024-02-13 18:24:56 -05:00
|
|
|
orbitb.theta = P.Theta();
|
|
|
|
orbitb.phi = P.Phi();
|
2024-02-15 16:36:45 -05:00
|
|
|
orbitb.rho = P.Pt() / abs(detGeo.Bfield) / P.GetUniqueID() / c * 1000; //mm
|
2024-02-13 18:24:56 -05:00
|
|
|
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;
|
2024-02-14 16:30:13 -05:00
|
|
|
|
|
|
|
}else{
|
2024-02-13 18:24:56 -05:00
|
|
|
orbitB.theta = P.Theta();
|
|
|
|
orbitB.phi = P.Phi();
|
2024-02-15 16:36:45 -05:00
|
|
|
orbitB.rho = P.Pt() / abs(detGeo.Bfield) / P.GetUniqueID() / c * 1000; //mm
|
2024-02-13 18:24:56 -05:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-02-15 16:36:45 -05:00
|
|
|
int HELIOS::CalArrayHit(TLorentzVector Pb, bool debug){
|
2024-02-13 18:24:56 -05:00
|
|
|
|
|
|
|
e = Pb.E() - Pb.M();
|
|
|
|
detX = TMath::QuietNaN();
|
|
|
|
rhoHit = TMath::QuietNaN();
|
|
|
|
|
2024-02-15 16:36:45 -05:00
|
|
|
CalTrajectoryPara(Pb, true);
|
2024-02-13 18:24:56 -05:00
|
|
|
|
|
|
|
int targetLoop = 1;
|
|
|
|
int inOut = array.detFaceOut == true ? 1: 0; //1 = from Outside, 0 = from inside
|
|
|
|
|
|
|
|
if( debug ) {
|
|
|
|
printf("===================================\n");
|
|
|
|
printf("theta : %f deg, phi : %f deg \n", orbitb.theta * TMath::RadToDeg(), orbitb.phi * TMath::RadToDeg());
|
|
|
|
printf("z0: %f mm, rho : %f mm \n", orbitb.z0, orbitb.rho);
|
|
|
|
printf(" inOut : %d = %s \n", inOut, inOut == 1 ? "Out" : "in");
|
|
|
|
printf(" z range : %.2f - %.2f \n", detGeo.zMin, detGeo.zMax);
|
2024-02-14 16:30:13 -05:00
|
|
|
printf(" B-field sign : %d\n", detGeo.BfieldSign);
|
2024-02-13 18:24:56 -05:00
|
|
|
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));
|
2024-02-14 16:30:13 -05:00
|
|
|
double hahaha = asin( aEff/ orbitb.rho - detGeo.BfieldSign * sin(dphi));
|
2024-02-13 18:24:56 -05:00
|
|
|
|
|
|
|
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
|
2024-02-14 16:30:13 -05:00
|
|
|
if( !TMath::IsNaN(zP) && 0 < zP/orbitb.z0 && TMath::Max(0, targetLoop-1) < zP/orbitb.z0 && zP/orbitb.z0 < targetLoop ) {
|
2024-02-13 18:24:56 -05:00
|
|
|
zPossible.push_back(zP);
|
|
|
|
dID.push_back(i);
|
|
|
|
}
|
|
|
|
}
|
2024-02-14 16:30:13 -05:00
|
|
|
|
2024-02-13 18:24:56 -05:00
|
|
|
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;
|
2024-02-14 16:30:13 -05:00
|
|
|
hitMessage = "wrong direction.";
|
2024-02-13 18:24:56 -05:00
|
|
|
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;
|
2024-02-14 16:30:13 -05:00
|
|
|
hitMessage = "not on the detector plan.";
|
2024-02-13 18:24:56 -05:00
|
|
|
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);
|
|
|
|
|
2024-02-14 16:30:13 -05:00
|
|
|
hitMessage = "successful hit.";
|
2024-02-13 18:24:56 -05:00
|
|
|
return 1; // return 1 when OK
|
|
|
|
}
|
|
|
|
|
2024-02-15 16:36:45 -05:00
|
|
|
int HELIOS::CalRecoilHit(TLorentzVector PB){
|
2024-02-13 18:24:56 -05:00
|
|
|
|
2024-02-15 16:36:45 -05:00
|
|
|
CalTrajectoryPara(PB, false);
|
2024-02-13 18:24:56 -05:00
|
|
|
|
|
|
|
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
|