#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 #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 "PndDrcPhoton.h" #include "PndDrcOptReflAbs.h" #include "PndDrcSurfAbs.h" #include "PndDrcOptMatAbs.h" #include "PndDrcOptDev.h" #include "PndDrcOptDevSys.h" #include "PndDrcOptDevManager.h" #include "PndDrcUtil.h" 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::m_instance = 0; //---------------------------------------------------------------------- PndDrcOptDevManager::PndDrcOptDevManager() { if(m_instance) { cerr<<" There is only one PndDrcOptDevManager allowed! "<::const_iterator isys; for(isys=m_listDevSys.begin(); isys != m_listDevSys.end(); ++isys) { delete (*isys); } } //---------------------------------------------------------------------- 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 = m_mapDev.find(str); if (idev != m_mapDev.end()) { dev = (*idev).second; } else { cerr<<" *** PndDrcOptDevManager::device: device not in map: " <::const_iterator idev; list::const_iterator isys; list::const_iterator isys_copy; cout<<" size="<listSysOri().size()<::const_iterator isys1 = tmp->listSysOri().begin(); isys1 != tmp->listSysOri().end(); ++isys1) { string str = *isys1; cout<<++ii<<" "<deviceList().begin(), isys = tmp->listSysOri().begin(), isys_copy = tmp->listSysOriCopy().begin(); idev != tmp->deviceList().end(); ++idev, ++isys, ++isys_copy) { cout<<(++ii)<<" "<<(*idev)->name()<name() + "_" + itoa((*idev)->copyNumber(),6); //string str2 = (*isys);// + "_" + itoa((*isys_copy),6); string str = str1;//+str2; pair p(str,(*idev)); pair< map::iterator, bool > idev1 = m_mapDev.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 isys; for(isys=m_listDevSys.begin(); isys != m_listDevSys.end(); ++isys) { (*isys)->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 eps = 1.0e-9; PndDrcPhoton ph; ph.setPosition(pos); ph.setDirection(dir.Unit()); HitMapType hit_map; VolMapType vol_map; SysOriMapType sys_ori_map; HitMapType::iterator hit_map_iter; VolMapType::iterator vol_map_iter; SysOriMapType::iterator sys_ori_map_iter; list::const_iterator isys; list::const_iterator idev; list::const_iterator isurf; list::const_iterator isys_ori; list::const_iterator isys_ori_copy; double path_length; bool hit; pair hit_pair; bool hit1=true; int ihit = 0; while (hit1 && (ph.position()-pos).Mag2()::max(); for (isys=m_listDevSys.begin(); isys != m_listDevSys.end(); ++isys) { PndDrcOptDevSys* sys = (*isys); list list_dev = sys->deviceList(); for (idev=list_dev.begin(), isys_ori=sys->listSysOri().begin(), isys_ori_copy=sys->listSysOriCopy().begin(); idev != list_dev.end(); idev++, isys_ori++, isys_ori_copy++) { PndDrcOptDev* dev = (*idev); list list_surf = dev->surfaceList(); XYZPoint pos_new; PndDrcSurfAbs* surf_closest=0; if (dev->radiator()) { for (isurf=list_surf.begin(); isurf != list_surf.end(); isurf++) { PndDrcSurfAbs* surf = (*isurf); 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) { ph.setPosition(pos_new+ph.direction()*2*eps); // bring it in. ihit++; //cout<<" ihit%2="< vol_pair; vol_pair.first = dev->name(); vol_pair.second = dev->copyNumber(); vol_map.insert( VolValuePair(path_length,vol_pair) ); pair sys_ori_pair; sys_ori_pair.first = (*isys_ori); sys_ori_pair.second = (*isys_ori_copy); sys_ori_map.insert(SysOriValuePair(path_length,sys_ori_pair)); } } } } } } // while hit if (vol_map.size()>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_map_iter=vol_map.begin(), hit_map_iter=hit_map.begin(), sys_ori_map_iter=sys_ori_map.begin(); vol_map_iter != vol_map.end(); ++ vol_map_iter, ++ hit_map_iter, ++ sys_ori_map_iter) { pair r = (*hit_map_iter).second; pair v = (*vol_map_iter).second; pair s = (*sys_ori_map_iter).second; if ((r.first-r.second).Mag2() > 1.0e-18) // no flat devices. { p_in.push_back(r.first); p_out.push_back(r.second); vol_name.push_back(v.first); vol_copy.push_back(v.second); sys_name.push_back(s.first); sys_copy.push_back(s.second); } } return (p_in.size() >0) ? true : false; } return false; } //---------------------------------------------------------------------- bool PndDrcOptDevManager::cerenkov(const XYZPoint& pos, const XYZVector& dir, double beta, int n, double range, double nu1, double nu2) { 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 it_p_in; list::const_iterator it_p_out; list::const_iterator it_vol_name; list::const_iterator it_vol_copy; list::const_iterator it_sys_name; list::const_iterator it_sys_copy; bool result = false; for (it_p_in = p_in_list.begin(), it_p_out = p_out_list.begin(), it_vol_name = vol_name_list.begin(), it_vol_copy = vol_copy_list.begin(), it_sys_name = sys_name_list.begin(), it_sys_copy = sys_copy_list.begin(); it_p_in != p_in_list.end(); ++it_p_in, ++it_p_out, ++it_vol_name, ++it_vol_copy, ++it_sys_name, ++it_sys_copy) { XYZPoint r1 = (*it_p_in); XYZPoint r2 = (*it_p_out); string vol_name = (*it_vol_name); int vol_copy = (*it_vol_copy); string sys_name = (*it_sys_name); int sys_copy = (*it_sys_copy); //cout<<" r1= "<=3) cout<<" PndDrcOptDevManager::cerenkov nu_mean = " <=3) { cout<<" N0 = "<1.001) { cerr<<"* : PndDrcOptDevManager::cerenkov: beta="<optMaterial().refIndex(nu_mean))*beta); 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 + m_ran.Uniform(1.0)*diff; beta_ph = diff.Unit(); // velocity vector with length 1 dphi = m_ran.Uniform(0,2*pi); //cout<& photon_list, string vol_name, string sys_name, int ivol_copy, int isys_copy) { m_listPhoton = photon_list; // find the internal device pointer PndDrcOptDev* dev=device(vol_name,sys_name,ivol_copy,isys_copy); list::iterator iph; for (iph = m_listPhoton.begin(); iph != m_listPhoton.end(); ++iph) { (*iph).setDevice(dev); } } //---------------------------------------------------------------------- void PndDrcOptDevManager::propagate() { list::iterator iph; for (iph = m_listPhoton.begin(); iph != m_listPhoton.end(); ++iph) { PndDrcOptDev* dev = (*iph).device(); dev->propagate((*iph)); } } //---------------------------------------------------------------------- void PndDrcOptDevManager::addTransform(const Transform3D& trans) { list::const_iterator isys; for (isys=m_listDevSys.begin(); isys != m_listDevSys.end(); ++isys) { PndDrcOptDevSys* sys = (*isys); sys->addTransform(trans); } } //---------------------------------------------------------------------- void PndDrcOptDevManager::print() { cout<<"---------------------------- Start PndDrcOptDevManager objects and pointers" <::const_iterator isys; for (isys=m_listDevSys.begin(); isys != m_listDevSys.end(); ++isys) { cout<<"\n\n"<name()<print(); } cout<<"---------------------------- End PndDrcOptDevManager objects and pointers" <