// ---------------------------------------------------- // This file belongs to the ray tracing framework // for the use with Cherenkov detectors // // created 2007 //----------------------------------------------------- #include "PndDrcOptDevManager.h" //#include "PndDrcPhoton.h" //#include "PndDrcOptReflAbs.h" #include "PndDrcSurfAbs.h" #include "PndDrcOptMatAbs.h" #include "PndDrcOptDev.h" #include "PndDrcOptDevSys.h" #include "PndDrcUtil.h" // //#include "TObject.h" //#include "TVector3.h" //#include "TRandom.h" //#include "Math/Vector3D.h" //using ROOT::Math::XYZVector; // //#include "Math/Point3D.h" //using ROOT::Math::XYZPoint; // //#include "Math/Transform3D.h" //using ROOT::Math::Transform3D; // //#include "Math/RotationX.h" //using ROOT::Math::RotationX; //#include "Math/RotationY.h" //using ROOT::Math::RotationY; //#include "Math/RotationZ.h" //using ROOT::Math::RotationZ; //#include "Math/Rotation3D.h" //using ROOT::Math::Rotation3D; // #include using std::cout; using std::cerr; //using std::cin; using std::endl; // //#include //using std::valarray; // //#include //using std::vector; // //#include //using std::string; // #include //using std::list; // //#include //using std::map; // #include using std::numeric_limits; // //#include //using std::fstream; // //#include using std::pair; //#include //typedef map< double, pair > HitMapType; //typedef map< double, pair > VolMapType; //typedef map< double, pair > SysOriMapType; //typedef HitMapType::value_type HitValuePair; //typedef VolMapType::value_type VolValuePair; //typedef SysOriMapType::value_type SysOriValuePair; // pointer to the object made by Construct() PndDrcOptDevManager* PndDrcOptDevManager::fgInstance = 0; //---------------------------------------------------------------------- PndDrcOptDevManager::PndDrcOptDevManager() { if(fgInstance) { cerr<<" There is only one PndDrcOptDevManager allowed! "<::const_iterator kSys; for(kSys=fListDevSys.begin(); kSys != fListDevSys.end(); ++kSys) { delete (*kSys); } } //---------------------------------------------------------------------- PndDrcOptDev* PndDrcOptDevManager::Device(string s, string sys, int icopy, int isys_copy) { string str = s + "_" + itoa(icopy,6) + sys + "_" + itoa(isys_copy,6); PndDrcOptDev* dev = 0; map::iterator idev = fMapDev.find(str); if (idev != fMapDev.end()) { dev = (*idev).second; } else { cerr<<" *** PndDrcOptDevManager::device: device not in map: " <::const_iterator kDev; list::const_iterator kSys; list::const_iterator kSys_copy; for (kDev = tmp->DeviceList().begin(), kSys = tmp->ListSysOri().begin(), kSys_copy = tmp->ListSysOriCopy().begin(); kDev != tmp->DeviceList().end(); ++kDev, ++kSys, ++kSys_copy) { string str = (*kDev)->Name() + "_" + itoa((*kDev)->CopyNumber(),6) + (*kSys) + "_" + itoa((*kSys_copy),6); pair p(str,(*kDev)); pair< map::iterator, bool > idev1 = fMapDev.insert(p); if (!idev1.second) { cerr<<" *** PndDrcOptDevManager::addDeviceSystem: device already present \n" <<" name,copy: "<Name()<<" "<CopyNumber()<::const_iterator isys; PndDrcOptDev* d1=device(dev1,copy1); PndDrcOptDev* d2=device(dev2,copy2); PndDrcSurfAbs* s1=0; PndDrcSurfAbs* s2=0; if (d1 && d2) { list::const_iterator isurf; for(isurf=(d1->surfaceList()).begin(); isurf != (d1->surfaceList()).end(); ++isurf) { if ((*isurf)->name()== surf1) s1=(*isurf); } for(isurf=d2->surfaceList().begin(); isurf != d2->surfaceList().end(); ++isurf) { if ((*isurf)->name()== surf2) s2=(*isurf); } if (s1 && s2) { s1->setCoupled(d2,s2); s2->setCoupled(d1,s1); } else { cerr<<" *** PndDrcOptDevManager::coupleDevice: surface not found"<::const_iterator kSys; for(kSys=fListDevSys.begin(); kSys != fListDevSys.end(); ++kSys) { if (fVerbosity>=3) cout<<" PndDrcOptDevManager::print: set print flag for " <<(*kSys)->Name()<<" "<<(*kSys)->CopyNumber()<Print(stream); } } //---------------------------------------------------------------------- bool PndDrcOptDevManager::Intersect(const XYZPoint& pos, const XYZVector& dir, list& p_in, list& p_out, list& vol_name, list& sys_name, list& vol_copy, list& sys_copy, double range) const { const double kEps = 1.0e-9; /* typedef map< double, pair > HitMapType; typedef map< double, pair > VolMapType; typedef map< double, pair > SysOriMapType; typedef HitMapType::value_type HitValuePair; typedef VolMapType::value_type VolValuePair; typedef SysOriMapType::value_type SysOriValuePair; */ //HitMapType hit_map; //VolMapType vol_map; //SysOriMapType sys_ori_map; list< pair > hit_list; list< pair > vol_list; list< pair > sys_ori_list; //HitMapType::iterator hit_map_iter; //VolMapType::iterator vol_map_iter; //SysOriMapType::iterator sys_ori_map_iter; list< pair >::iterator hit_list_iter; list< pair >::iterator vol_list_iter; list< pair >::iterator sys_ori_list_iter; list::const_iterator kSys; list::const_iterator kDev; list::const_iterator kSurf; list::const_iterator kSys_ori; list::const_iterator kSys_ori_copy; double path_length; bool hit; pair hit_pair; if (fVerbosity>=3) cout<<" PndDrcOptDevManager::intersect: start loop ------------------"< list_dev = sys->DeviceList(); if (fVerbosity>=3) cout<<" PndDrcOptDevManager::intersect: check system " <Name()<<" "<CopyNumber()<ListSysOri().begin(), kSys_ori_copy=sys->ListSysOriCopy().begin(); kDev != list_dev.end(); kDev++, kSys_ori++, kSys_ori_copy++) { //######################## bool hit1=true; int ihit = 0; PndDrcPhoton ph; ph.SetPosition(pos); ph.SetDirection(dir.Unit()); while (hit1 && (ph.Position()-pos).Mag2()::max(); //######################## PndDrcOptDev* dev = (*kDev); if (fVerbosity>=3) cout<<" PndDrcOptDevManager::intersect: check device " <Name()<<" "<CopyNumber()< list_surf = dev->SurfaceList(); XYZPoint pos_new; PndDrcSurfAbs* surf_closest=0; if (dev->Radiator()) { for (kSurf=list_surf.begin(); kSurf != list_surf.end(); kSurf++) { PndDrcSurfAbs* surf = (*kSurf); hit = surf->SurfaceHit(ph,pos_new,path_length); if (hit) { if (path_length < path_shortest) { path_shortest = path_length; surf_closest = surf; } } } } if (surf_closest) { PndDrcSurfAbs* surf = surf_closest; hit = surf->SurfaceHit(ph,pos_new,path_length); if (hit) hit1=true; if (hit) { if (fVerbosity>=3) cout<<" PndDrcOptDevManager::intersect: hit# "< vol_pair; vol_pair.first = dev->Name(); vol_pair.second = dev->CopyNumber(); //vol_map.insert( VolValuePair(path_length,vol_pair) ); vol_list.push_back(vol_pair); if (fVerbosity>=3) { cout<<" PndDrcOptDevManager::intersect: hit pair" <<" added " < sys_ori_pair; sys_ori_pair.first = (*kSys_ori); sys_ori_pair.second = (*kSys_ori_copy); //sys_ori_map.insert(SysOriValuePair(path_length,sys_ori_pair)); sys_ori_list.push_back(sys_ori_pair); } } } } } } if (fVerbosity>=3) cout<<" PndDrcOptDevManager::intersect: stop loop ------------------"<=3) cout<<" PndDrcOptDevManager::intersect: size of vol_map " <0) { // map is already sorted. p_in.clear(); p_out.clear(); vol_name.clear(); vol_copy.clear(); sys_name.clear(); sys_copy.clear(); for (vol_list_iter=vol_list.begin(), hit_list_iter=hit_list.begin(), sys_ori_list_iter=sys_ori_list.begin(); vol_list_iter != vol_list.end(); ++ vol_list_iter, ++ hit_list_iter, ++ sys_ori_list_iter) { pair r = (*hit_list_iter);//.second; pair v = (*vol_list_iter);//.second; pair s = (*sys_ori_list_iter);//.second; if ((r.first-r.second).Mag2() > 1.0e-18) // no flat devices. { if (fVerbosity>=3) cout<<" PndDrcOptDevManager::intersect: added " <=3) cout<<" PndDrcOptDevManager::intersect: did not add " <0) ? true : false; } return false; } //---------------------------------------------------------------------- bool PndDrcOptDevManager::Cerenkov(const XYZPoint& pos, const XYZVector& dir, double beta, int n, double range, double nu1, double nu2, int refl_limit, int particleIDnumber) { list p_in_list; list p_out_list; list vol_name_list; list vol_copy_list; list sys_name_list; list sys_copy_list; if(Intersect(pos,dir, p_in_list,p_out_list, vol_name_list,sys_name_list, vol_copy_list,sys_copy_list,range)) { list::const_iterator kit_p_in; list::const_iterator kit_p_out; list::const_iterator kit_vol_name; list::const_iterator kit_vol_copy; list::const_iterator kit_sys_name; list::const_iterator kit_sys_copy; bool result = false; for (kit_p_in = p_in_list.begin(), kit_p_out = p_out_list.begin(), kit_vol_name = vol_name_list.begin(), kit_vol_copy = vol_copy_list.begin(), kit_sys_name = sys_name_list.begin(), kit_sys_copy = sys_copy_list.begin(); kit_p_in != p_in_list.end(); ++kit_p_in, ++kit_p_out, ++kit_vol_name, ++kit_vol_copy, ++kit_sys_name, ++kit_sys_copy) { XYZPoint r1 = (*kit_p_in); XYZPoint r2 = (*kit_p_out); string vol_name = (*kit_vol_name); int vol_copy = (*kit_vol_copy); string sys_name = (*kit_sys_name); int sys_copy = (*kit_sys_copy); //cout<<" r1= "<=3) cout<<" PndDrcOptDevManager::cerenkov: vol "<=3) cout<<" PndDrcOptDevManager::cerenkov nu_mean = " <=3) { cout<<" N0 = "<1.001) { cerr<<"* : PndDrcOptDevManager::cerenkov: beta="<Radiator() ) { // get number of photons to sample double ref_index = dev->OptMaterial().RefIndex(nu_mean); double costh = 1.0/(ref_index*beta); if (fVerbosity>=3) cout << " costh= " << costh << endl; if (costh>1) return 0; // particle too slow //cout<<"inum="<OptMaterial().RefIndex(lambda); costh = 1.0L/(beta*n); } while (costh>1); diff = r2 - r1; r = r1 + fRan.Uniform(1.0)*diff; beta_ph = diff.Unit(); // velocity vector with length 1 dphi = fRan.Uniform(0,2*kPi); //cout<DirectionX()); double diry = beta_ph.Dot(dev->DirectionY()); double dirz = beta_ph.Dot(dev->DirectionZ()); ph.SetOriginDirection(XYZVector(dirx,diry,dirz)); ph.SetThetaC(dtheta); ph.SetPhiC(dphi); ph.SetParticleIDnumber(particleIDnumber); ph.SetWavelength(lambda); ph.SetDevice(dev); ph.SetReflectionLimit(refl_limit); fListPhoton.push_back(ph); } } return true; } //---------------------------------------------------------------------- void PndDrcOptDevManager::SetPhotonList(list& photon_list, string vol_name, string sys_name, int ivol_copy, int isys_copy) { fListPhoton = photon_list; PndDrcOptDev* dev = 0; list::iterator iph; for (iph = fListPhoton.begin(); iph != fListPhoton.end(); ++iph) { if( (*iph).Device() == 0 ) { cerr << "*** PndDrcOptDevManager::SetPhotonList: Photon device is not set" << endl; exit(EXIT_FAILURE); } if( vol_name == "@@@") dev = (*iph).Device(); else dev =Device(vol_name,sys_name,ivol_copy,isys_copy); // internal device pointer double x = (*iph).Direction().Dot(dev->DirectionX()); double y = (*iph).Direction().Dot(dev->DirectionY()); double z = (*iph).Direction().Dot(dev->DirectionZ()); (*iph).SetOriginDirection(XYZVector(x,y,z)); } } //---------------------------------------------------------------------- void PndDrcOptDevManager::Propagate() { list::iterator iph; int photonTotal = fListPhoton.size(); int cnt = 0; for (iph = fListPhoton.begin(); iph != fListPhoton.end(); ++iph) { PndDrcOptDev* dev = (*iph).Device(); if (fVerbosity==4) { cnt++; cout << "***** Photon ID: " << cnt << " " << dev->Name() << endl; } dev->Propagate((*iph)); } } //---------------------------------------------------------------------- void PndDrcOptDevManager::AddTransform(const Transform3D& trans) { list::const_iterator kSys; for (kSys=fListDevSys.begin(); kSys != fListDevSys.end(); ++kSys) { PndDrcOptDevSys* sys = (*kSys); sys->AddTransform(trans); } } //---------------------------------------------------------------------- void PndDrcOptDevManager::Print() { cout<<"---------------------------- Start PndDrcOptDevManager objects and pointers" <::const_iterator kSys; for (kSys=fListDevSys.begin(); kSys != fListDevSys.end(); ++kSys) { cout<<"\n\n"<Name()<Print(); } cout<<"---------------------------- End PndDrcOptDevManager objects and pointers" <