#include using std::cout; using std::cerr; using std::cin; using std::endl; using std::hex; #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 "DrcPhoton.h" #include "DrcOptReflAbs.h" #include "DrcSurfAbs.h" #include "DrcOptMatAbs.h" #include "DrcOptDev.h" #include "DrcOptDevSys.h" #include "DrcOptDevManager.h" #include "DrcUtil.h" typedef map< double, pair > HitMapType; typedef map< double, pair > VolMapType; typedef HitMapType::value_type HitValuePair; typedef VolMapType::value_type VolValuePair; // pointer to the object made by Construct() DrcOptDevManager* DrcOptDevManager::m_instance = 0; //---------------------------------------------------------------------- DrcOptDevManager::DrcOptDevManager() { if(m_instance) { cerr<<" There is only one DrcOptDevManager allowed! "<::const_iterator isys; for(isys=m_listDevSys.begin(); isys != m_listDevSys.end(); ++isys) { delete (*isys); } } //---------------------------------------------------------------------- DrcOptDev* DrcOptDevManager::device(string s,int icopy) { string str = s + "_" + itoa(icopy,6); DrcOptDev* dev = 0; map::iterator idev = m_mapDev.find(str); if (idev != m_mapDev.end()) { dev = (*idev).second; } else { cerr<<" *** DrcOptDevManager::device: device not in map: " <99999) { cerr<<" *** DrcOptDevManager::addDeviceSystem: sorry, copy limited to" <<" 5 digits."<setCopyNumber(icopy); m_listDevSys.push_back(tmp); // add for fast finding of devices per name the combined name and copy number to // a map; list::iterator idev; for(idev = tmp->deviceList().begin(); idev != tmp->deviceList().end(); ++idev) { string str = (*idev)->name() + "_" + itoa(icopy,6); pair p(str,(*idev)); pair::iterator,bool> idev1 = m_mapDev.insert(p); if (!idev1.second) { cerr<<" *** DrcOptDevManager::addDeviceSystem: device already present \n" <<" name,copy: "<name()<<" "<::const_iterator isys; DrcOptDev* d1=device(dev1,copy1); DrcOptDev* d2=device(dev2,copy2); DrcSurfAbs* s1=0; DrcSurfAbs* 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<<" *** DrcOptDevManager::coupleDevice: surface not found"<::const_iterator isys; for(isys=m_listDevSys.begin(); isys != m_listDevSys.end(); ++isys) { (*isys)->print(stream); } } //---------------------------------------------------------------------- bool DrcOptDevManager::intersect(const XYZPoint& pos, const XYZVector& dir, list& p_in, list& p_out, list& vol_name, list& copy, double range) const { const double eps = 1.0e-9; DrcPhoton ph; ph.setPosition(pos); ph.setDirection(dir.Unit()); HitMapType hit_map; VolMapType vol_map; HitMapType::iterator hit_map_iter; VolMapType::iterator vol_map_iter; list::const_iterator isys; list::const_iterator idev; list::const_iterator isurf; 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) { DrcOptDevSys* sys = (*isys); list list_dev = sys->deviceList(); for (idev=list_dev.begin(); idev != list_dev.end(); idev++) { DrcOptDev* dev = (*idev); list list_surf = dev->surfaceList(); XYZPoint pos_new; DrcSurfAbs* surf_closest=0; if (dev->radiator()) { for (isurf=list_surf.begin(); isurf != list_surf.end(); isurf++) { DrcSurfAbs* 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) { DrcSurfAbs* 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) ); } } } } } } // while hit if (vol_map.size()>0) { // map is already sorted. p_in.clear(); p_out.clear(); vol_name.clear(); copy.clear(); for (vol_map_iter=vol_map.begin(), hit_map_iter=hit_map.begin(); vol_map_iter != vol_map.end(); ++vol_map_iter, ++ hit_map_iter) { pair r = (*hit_map_iter).second; pair v = (*vol_map_iter).second; //double path_length = (*vol_map_iter).first; //cout<<" path_length = "< 1.0e-18) // no flat devices. { p_in.push_back(r.first); p_out.push_back(r.second); vol_name.push_back(v.first); copy.push_back(v.second); } } return (p_in.size() >0) ? true : false; } return false; } //---------------------------------------------------------------------- bool DrcOptDevManager::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 copy_list; if(intersect(pos,dir,p_in_list,p_out_list,vol_name_list,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_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_copy = copy_list.begin(); it_p_in != p_in_list.end(); ++it_p_in, ++it_p_out, ++it_vol_name, ++it_copy) { XYZPoint r1 = (*it_p_in); XYZPoint r2 = (*it_p_out); string vol_name = (*it_vol_name); int copy_number = (*it_copy); //cout<<" r1= "<=3) cout<<" DrcOptDevManager::cerenkov nu_mean = " <=3) { cout<<" N0 = "<1.001) { cerr<<"* : DrcOptDevManager::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, int copy) { m_listPhoton = photon_list; // find the internal device pointer DrcOptDev* dev=device(vol_name,copy); list::iterator iph; for (iph = m_listPhoton.begin(); iph != m_listPhoton.end(); ++iph) { (*iph).setDevice(dev); } } //---------------------------------------------------------------------- void DrcOptDevManager::propagate() { list::iterator iph; for (iph = m_listPhoton.begin(); iph != m_listPhoton.end(); ++iph) { DrcOptDev* dev = (*iph).device(); dev->propagate((*iph)); } } //---------------------------------------------------------------------- void DrcOptDevManager::addTransform(const Transform3D& trans) { list::const_iterator isys; for (isys=m_listDevSys.begin(); isys != m_listDevSys.end(); ++isys) { DrcOptDevSys* sys = (*isys); sys->addTransform(trans); } } //---------------------------------------------------------------------- void DrcOptDevManager::print() { cout<<"---------------------------- Start DrcOptDevManager objects and pointers" <::const_iterator isys; for (isys=m_listDevSys.begin(); isys != m_listDevSys.end(); ++isys) { cout<<"\n\n"<name()<print(); } cout<<"---------------------------- End DrcOptDevManager objects and pointers" <