// // ******************************************************************** // * License and Disclaimer * // * * // * The Geant4 software is copyright of the Copyright Holders of * // * the Geant4 Collaboration. It is provided under the terms and * // * conditions of the Geant4 Software License, included in the file * // * LICENSE and available at http://cern.ch/geant4/license . These * // * include a list of copyright holders. * // * * // * Neither the authors of this software system, nor their employing * // * institutes,nor the agencies providing financial support for this * // * work make any representation or warranty, express or implied, * // * regarding this software system or assume any liability for its * // * use. Please see the license in the file LICENSE and URL above * // * for the full disclaimer and the limitation of liability. * // * * // * This code implementation is the result of the scientific and * // * technical work of the GEANT4 collaboration. * // * By using, copying, modifying or distributing the software (or * // * any work based on the software) you agree to acknowledge its * // * use in resulting scientific publications, and indicate your * // * acceptance of all terms of the Geant4 Software license. * // ******************************************************************** // // $Id$ // // Author: Mathieu Karamitros (kara (AT) cenbg . in2p3 . fr) // // WARNING : This class is released as a prototype. // It might strongly evolve or even disapear in the next releases. // // History: // ----------- // 10 Oct 2011 M.Karamitros created // // ------------------------------------------------------------------- TEMPLATE G4ITMANAGER * G4ITMANAGER::fInstance(0); TEMPLATE G4ITMANAGER * G4ITMANAGER::Instance() { if(!fInstance) fInstance = new G4ITManager(); return fInstance; } TEMPLATE G4ITMANAGER::G4ITManager() : G4VITManager() { fType = T::ITType(); SetVerboseLevel(G4AllITManager::Instance()->GetVerboseLevel()); G4AllITManager::Instance()->RegisterManager(this); } TEMPLATE G4ITMANAGER::~G4ITManager() { { typename BoxMap::iterator it; for(it = fBox.begin() ; it != fBox.end() ; it++) { if(it->second) delete it->second; } fBox.clear(); } { typename TreeMap::iterator it; for(it = fTree.begin() ; it != fTree.end() ; it++) { if(it->second) delete it->second; } fTree.clear(); for(it = fPrevious_tree.begin() ; it != fPrevious_tree.end() ; it++) { if(it->second) delete it->second; } fPrevious_tree.clear(); } } TEMPLATE void G4ITMANAGER::iUpdatePositionMap() { fInstance->UpdatePositionMap(); } TEMPLATE void G4ITMANAGER::Push(G4Track* track) { G4IT* aIT = GetIT(track) ; aIT->RecordCurrentPositionNTime(); const T& key = dynamic_cast(*aIT); typename BoxMap::iterator it = fBox.find(key); if(it != fBox.end()) { G4ITBox* theBox = it->second; theBox->Push(aIT); } else { G4ITBox * itBox = new G4ITBox(); std::pair ret = fBox.insert(std::make_pair (T(key), itBox)) ; typename BoxMap::iterator box_placement = ret.first; typename BoxMap::iterator previous_placement = ret.first; previous_placement--; typename BoxMap::iterator next_placement = ret.first; next_placement++; typename BoxMap::iterator last_placement = fBox.end(); last_placement--; if(box_placement != fBox.begin()) { G4ITBox* previous_box = previous_placement->second; if(previous_box) { itBox->SetPreviousBox(previous_box); previous_box->SetNextBox(itBox); } } if(box_placement != last_placement) { G4ITBox* next_box = next_placement->second; if(next_box) { itBox->SetNextBox(next_placement->second); next_box->SetPreviousBox(itBox); } } itBox -> Push(aIT); } if(!(aIT->GetNode())) { G4KDNode* node = 0; G4ThreeVector position = aIT->GetTrack()->GetPosition(); typename TreeMap::iterator it_fTree = fTree.find(key); if(it_fTree != fTree.end()) { node=it_fTree->second->Insert(position.x(), position.y(), position.z(), aIT); } else { G4KDTree* aTree = new G4KDTree() ; fTree.insert(std::make_pair(T(key),aTree)); node = aTree->Insert(position.x(), position.y(), position.z(), aIT); } aIT->SetNode(node); } } TEMPLATE void G4ITMANAGER::EraseABox(T* aIT) { // G4cout<<"G4ITMANAGER::EraseABox : " << aIT->GetName()<(*aIT); typename BoxMap::iterator it = fBox.find(key); if(it != fBox.end()) { fBox.erase(it); } } TEMPLATE void G4ITMANAGER::EraseABox(G4ITBox* aStack) { typename BoxMap::iterator it; for ( it=fBox.begin() ; it != fBox.end(); it++) { if(it->second == aStack) { break; } } fBox.erase(it); } TEMPLATE G4int G4ITMANAGER::NbElements(const G4IT* aIT) { const T& key = dynamic_cast(*aIT); typename BoxMap::iterator it = fBox.find(key); if(it != fBox.end()) return it->second->GetNTrack(); return -1; } TEMPLATE G4KDTreeResultHandle G4ITMANAGER::FindNearest(const G4ThreeVector& position, const T* key) { typename TreeMap::iterator it = fTree.find(*key); if(it!= fTree.end()) return it->second->Nearest(position.x(),position.y(),position.z()); else { return 0; } return 0; } TEMPLATE G4KDTreeResultHandle G4ITMANAGER::FindNearest(const T* point0, const T* key) { if(*point0 == *key) { // DEBUG // G4cout << "Equal keys !"<< G4endl; G4KDNode* node0 = point0->GetNode() ; if(node0 == 0) { G4ExceptionDescription exceptionDescription ("Bad request : no node found in the IT you are searching closest neighbourg for"); G4Exception("G4ITManager::FindNearest","ITManager002", FatalErrorInArgument,exceptionDescription); return 0; // coverity } typename TreeMap::iterator it = fTree.find(*key); if(it!= fTree.end()) { G4KDTreeResultHandle output(it->second->Nearest(node0)); if(!output) { // G4cout << "NO OUTPUT " << point0->GetName() << " " << key -> GetName() << G4endl; return 0; } // G4cout << "OUTPUT" << G4endl; return output; } else { // DEBUG // G4cout << "Pas trouve dans la map"<< key->GetName() << G4endl; return 0; } } else { // DEBUG // G4cout << "Not equal keys !"<< G4endl; const G4ThreeVector& position = point0->GetTrack()->GetPosition() ; typename TreeMap::iterator it = fTree.find(*key); if(it!= fTree.end()) { G4KDTreeResultHandle output(it->second->Nearest(position.x(),position.y(),position.z())); if(!output) { // G4cout << "NO OUTPUT" << G4endl; return 0; } // G4cout << "OUTPUT" << G4endl; return output; } else { // DEBUG // G4cout << "Pas trouve dans la map : "<< key->GetName() << G4endl; return 0; } } return 0; } TEMPLATE G4KDTreeResultHandle G4ITMANAGER::FindNearestInRange(const G4ThreeVector& position, const T* key, G4double R) { typename TreeMap::iterator it = fTree.find(*key); if(it!= fTree.end()) return it->second->NearestInRange(position.x(),position.y(),position.z(), R); else { return 0; } return 0; } TEMPLATE G4KDTreeResultHandle G4ITMANAGER::FindNearestInRange(const T* point0, const T* key, G4double R) { if(*point0 == *key) { G4KDNode* node0 = point0->GetNode() ; typename TreeMap::iterator it = fTree.find(*key); if(it!= fTree.end()) return it->second->NearestInRange(node0, R); else { return 0; } } else { const G4ThreeVector& position = point0->GetTrack()->GetPosition() ; typename TreeMap::iterator it = fTree.find(*key); if(it!= fTree.end()) return it->second->NearestInRange(position.x(),position.y(),position.z(), R); else { return 0; } } return 0; } TEMPLATE void G4ITMANAGER::UpdatePositionMap() { allbox_iterator allbox(this) ; if(allbox.GetBox() == 0) return; const G4ITBox* currentBox = 0 ; const G4ITBox* buffBox = 0; G4KDTree* currentTree = 0; G4IT* currentIT = 0 ; typename TreeMap::iterator it_fTree ; if(!(fPrevious_tree.empty())) { for(it_fTree = fPrevious_tree.begin() ; it_fTree != fPrevious_tree.end() ; it_fTree ++) { if(it_fTree->second) delete (it_fTree->second) ; } fPrevious_tree.clear(); } for(allbox.begin() ; !allbox.end() ; allbox++) { buffBox = allbox.GetBox() ; currentIT = (*allbox); if(currentBox != buffBox) { currentTree = 0 ; currentBox = buffBox; const T& key = dynamic_cast(*currentIT); it_fTree = fTree.find(key); if(it_fTree != fTree.end()) { currentTree = it_fTree ->second ; if(currentTree) { fPrevious_tree[key] = currentTree ; // currentTree->Clear(); } } // Re-initialize fTree currentTree = new G4KDTree(); fTree[key] = currentTree ; } const G4ThreeVector& position = currentIT-> GetTrack()->GetPosition(); G4KDNode* node = currentTree->Insert(position.x(), position.y(), position.z(), currentIT); currentIT->SetNode(node); } }