#include "TRandom.h"
#include "ARayShooter.h"
ClassImp(ARayShooter)
ARayShooter::ARayShooter()
{
}
ARayShooter::~ARayShooter()
{
}
ARayArray* ARayShooter::Circle(Double_t lambda, Double_t rmax, Int_t nr,
Int_t nphi, TGeoRotation* rot,
TGeoTranslation* tr, TVector3* v)
{
ARayArray* array = new ARayArray;
if(0 > rmax or nr < 1 or nphi < 1){
return array;
}
Double_t position[3] = {0, 0, 0};
Double_t new_pos[3];
Double_t dir[3] = {0, 0, 1};
if(v){
dir[0] = v->X();
dir[1] = v->Y();
dir[2] = v->Z();
}
Double_t new_dir[3];
if(rot){
rot->LocalToMaster(dir, new_dir);
} else {
memcpy(new_dir, dir, 3*sizeof(Double_t));
}
if(tr) {
tr->LocalToMaster(position, new_pos);
} else {
memcpy(new_pos, position, 3*sizeof(Double_t));
}
array->Add(new ARay(0, lambda, new_pos[0], new_pos[1], new_pos[2], 0,
new_dir[0], new_dir[1], new_dir[2]));
for(Int_t i = 0; i < nr; i++){
Double_t r = rmax*(i + 1)/nr;
for(Int_t j = 0; j < nphi*(i + 1); j++){
Double_t phi = 2*TMath::Pi()/nphi/(i + 1)*j;
Double_t x[3] = {r*TMath::Cos(phi), r*TMath::Sin(phi), 0};
if(rot){
rot->LocalToMaster(x, new_pos);
} else {
memcpy(new_pos, x, 3*sizeof(Double_t));
}
if(tr) {
tr->LocalToMaster(new_pos, x);
} else {
memcpy(x, new_pos, 3*sizeof(Double_t));
}
ARay* ray = new ARay(0, lambda, x[0], x[1], x[2], 0,
new_dir[0], new_dir[1], new_dir[2]);
array->Add(ray);
}
}
return array;
}
ARayArray* ARayShooter::RandomCircle(Double_t lambda, Double_t rmax, Int_t n,
TGeoRotation* rot,
TGeoTranslation* tr, TVector3* v)
{
ARayArray* array = new ARayArray;
if(0 > rmax){
return array;
}
Double_t new_pos[3];
Double_t dir[3] = {0, 0, 1};
if(v){
dir[0] = v->X();
dir[1] = v->Y();
dir[2] = v->Z();
}
Double_t new_dir[3];
if(rot){
rot->LocalToMaster(dir, new_dir);
} else {
memcpy(new_dir, dir, 3*sizeof(Double_t));
}
for(Int_t i = 0; i < n; i++){
Double_t r = rmax*10;
Double_t randx, randy;
while(r > rmax){
randx = gRandom->Uniform(-rmax, rmax);
randy = gRandom->Uniform(-rmax, rmax);
r = TMath::Sqrt(randx*randx + randy*randy);
}
Double_t x[3] = {randx, randy, 0};
if(rot){
rot->LocalToMaster(x, new_pos);
} else {
memcpy(new_pos, x, 3*sizeof(Double_t));
}
if(tr) {
tr->LocalToMaster(new_pos, x);
} else {
memcpy(x, new_pos, 3*sizeof(Double_t));
}
ARay* ray = new ARay(0, lambda, x[0], x[1], x[2], 0,
new_dir[0], new_dir[1], new_dir[2]);
array->Add(ray);
}
return array;
}
ARayArray* ARayShooter::RandomCone(Double_t lambda, Double_t r, Double_t d, Int_t n,
TGeoRotation* rot, TGeoTranslation* tr)
{
ARayArray* array = new ARayArray;
for(Int_t i = 0; i < n; i++){
Double_t x = gRandom->Uniform(-r, r);
Double_t y = gRandom->Uniform(-r, r);
if(x*x + y*y > r*r){
i--;
continue;
}
Double_t goal_pos[3] = {x, y, d};
Double_t tmp_pos[3];
if(rot){
rot->LocalToMaster(goal_pos, tmp_pos);
} else {
memcpy(tmp_pos, goal_pos, 3*sizeof(Double_t));
}
Double_t start_pos[3] = {0, 0, 0};
if(tr) {
tr->LocalToMaster(tmp_pos, goal_pos);
tr->LocalToMaster(start_pos, tmp_pos);
} else {
memcpy(goal_pos, tmp_pos, 3*sizeof(Double_t));
memcpy(tmp_pos, start_pos, 3*sizeof(Double_t));
}
TVector3 start(tmp_pos);
TVector3 goal(goal_pos);
TVector3 dir = goal - start;
ARay* ray = new ARay(0, lambda, start.X(), start.Y(), start.Z(), 0,
dir.X(), dir.Y(), dir.Z());
array->Add(ray);
}
return array;
}
ARayArray* ARayShooter::RandomRectangle(Double_t lambda, Double_t dx, Double_t dy,
Int_t n, TGeoRotation* rot,
TGeoTranslation* tr, TVector3* v)
{
ARayArray* array = new ARayArray;
if(dx < 0 or dy < 0 or n < 1){
return array;
}
Double_t dir[3] = {0, 0, 1};
if(v){
dir[0] = v->X();
dir[1] = v->Y();
dir[2] = v->Z();
}
Double_t new_dir[3];
if(rot){
rot->LocalToMaster(dir, new_dir);
} else {
memcpy(new_dir, dir, 3*sizeof(Double_t));
}
for(Int_t i = 0; i < n; i++){
Double_t new_pos[3];
Double_t x[3] = {gRandom->Uniform(-dx/2., dx/2.), gRandom->Uniform(-dy/2., dy/2.), 0};
if(rot){
rot->LocalToMaster(x, new_pos);
} else {
memcpy(new_pos, x, 3*sizeof(Double_t));
}
if(tr) {
tr->LocalToMaster(new_pos, x);
} else {
memcpy(x, new_pos, 3*sizeof(Double_t));
}
ARay* ray = new ARay(0, lambda, x[0], x[1], x[2], 0,
new_dir[0], new_dir[1], new_dir[2]);
array->Add(ray);
}
return array;
}
ARayArray* ARayShooter::RandomSphere(Double_t lambda, Int_t n, TGeoTranslation* tr)
{
ARayArray* array = new ARayArray;
for(Int_t i = 0; i < n; i++){
Double_t dir[3];
gRandom->Sphere(dir[0], dir[1], dir[2], 1);
Double_t p[3] = {0, 0, 0};
Double_t new_pos[3];
if(tr){
tr->LocalToMaster(p, new_pos);
} else {
memcpy(p, new_pos, 3*sizeof(Double_t));
}
ARay* ray = new ARay(0, lambda, new_pos[0], new_pos[1], new_pos[2], 0,
dir[0], dir[1], dir[2]);
array->Add(ray);
}
return array;
}
ARayArray* ARayShooter::RandomSphericalCone(Double_t lambda, Int_t n, Double_t theta, TGeoRotation* rot, TGeoTranslation* tr)
{
ARayArray* array = new ARayArray;
for(Int_t i = 0; i < n; i++){
Double_t dir[3];
Double_t ran = gRandom->Uniform(TMath::Cos(theta*TMath::DegToRad()), 1);
Double_t theta_ = TMath::ACos(ran);
Double_t phi = gRandom->Uniform(0, TMath::TwoPi());
dir[0] = TMath::Sin(theta_)*TMath::Cos(phi);
dir[1] = TMath::Sin(theta_)*TMath::Sin(phi);
dir[2] = TMath::Cos(theta_);
Double_t new_dir[3];
if(rot){
rot->LocalToMaster(dir, new_dir);
} else {
memcpy(new_dir, dir, 3*sizeof(Double_t));
}
Double_t p[3] = {0, 0, 0};
Double_t new_pos[3] = {0, 0, 0};
if(tr){
tr->LocalToMaster(p, new_pos);
}
ARay* ray = new ARay(0, lambda, new_pos[0], new_pos[1], new_pos[2], 0,
new_dir[0], new_dir[1], new_dir[2]);
array->Add(ray);
}
return array;
}
ARayArray* ARayShooter::RandomSquare(Double_t lambda, Double_t d,
Int_t n, TGeoRotation* rot,
TGeoTranslation* tr, TVector3* v)
{
return RandomRectangle(lambda, d, d, n, rot, tr, v);
}
ARayArray* ARayShooter::Rectangle(Double_t lambda, Double_t dx, Double_t dy,
Int_t nx, Int_t ny, TGeoRotation* rot,
TGeoTranslation* tr, TVector3* v)
{
ARayArray* array = new ARayArray;
if(dx < 0 or dy < 0 or nx < 1 or ny < 1){
return array;
}
Double_t dir[3] = {0, 0, 1};
if(v){
dir[0] = v->X();
dir[1] = v->Y();
dir[2] = v->Z();
}
Double_t new_dir[3];
if(rot){
rot->LocalToMaster(dir, new_dir);
} else {
memcpy(new_dir, dir, 3*sizeof(Double_t));
}
Double_t deltax = nx == 1 ? dx/2 : dx/(nx - 1);
Double_t deltay = ny == 1 ? dy/2 : dy/(ny - 1);
for(Int_t i = 0; i < nx; i++){
for(Int_t j = 0; j < ny; j++){
Double_t new_pos[3];
Double_t x[3] = {i*deltax - dx/2, j*deltay - dy/2, 0};
if(rot){
rot->LocalToMaster(x, new_pos);
} else {
memcpy(new_pos, x, 3*sizeof(Double_t));
}
if(tr) {
tr->LocalToMaster(new_pos, x);
} else {
memcpy(x, new_pos, 3*sizeof(Double_t));
}
ARay* ray = new ARay(0, lambda, x[0], x[1], x[2], 0,
new_dir[0], new_dir[1], new_dir[2]);
array->Add(ray);
}
}
return array;
}
ARayArray* ARayShooter::Square(Double_t lambda, Double_t d, Int_t n,
TGeoRotation* rot, TGeoTranslation* tr,
TVector3* v)
{
return Rectangle(lambda, d, d, n, n, rot, tr, v);
}