diff --git a/Code/Mantid/Framework/Algorithms/src/CopyInstrumentParameters.cpp b/Code/Mantid/Framework/Algorithms/src/CopyInstrumentParameters.cpp index ff4be2b61c60..a5f73a2b50f2 100644 --- a/Code/Mantid/Framework/Algorithms/src/CopyInstrumentParameters.cpp +++ b/Code/Mantid/Framework/Algorithms/src/CopyInstrumentParameters.cpp @@ -83,19 +83,6 @@ void CopyInstrumentParameters::exec() Geometry::ParameterMap targMap; - //// vector of all components contained in the target instrument - //std::vector targComponents; - //// flattens instrument definition tree - //inst2->getChildren(targComponents,true); - //// multimap of existing instrument parameters - //std::multimap existingComponents; - //for(size_t i=0;i(targComponents[i].get())) - // continue; - // existingComponents.insert(std::pair(targComponents[i]->getFullName(),targComponents[i].get())); - //} - auto it = givParams.begin(); for(;it!= givParams.end(); it++) { @@ -130,8 +117,8 @@ void CopyInstrumentParameters::exec() targComp = spTargComp->getBaseComponent(); } // merge maps for existing target component - auto param = it->second.get(); - targMap.add(param->type(),targComp,param->name(),param->asString()); + auto param = it->second; //.get(); + targMap.add(targComp, param); } diff --git a/Code/Mantid/Framework/Geometry/inc/MantidGeometry/Instrument/ParameterMap.h b/Code/Mantid/Framework/Geometry/inc/MantidGeometry/Instrument/ParameterMap.h index 4d5f68c48a92..87c8082c403f 100644 --- a/Code/Mantid/Framework/Geometry/inc/MantidGeometry/Instrument/ParameterMap.h +++ b/Code/Mantid/Framework/Geometry/inc/MantidGeometry/Instrument/ParameterMap.h @@ -59,6 +59,16 @@ namespace Geometry File change history is stored at: . Code Documentation is available at: */ +#ifndef HAS_UNORDERED_MAP_H + /// Parameter map iterator typedef + typedef std::multimap >::iterator component_map_it; + typedef std::multimap >::const_iterator component_map_cit; +#else + /// Parameter map iterator typedef + typedef std::tr1::unordered_multimap >::iterator component_map_it; + typedef std::tr1::unordered_multimap >::const_iterator component_map_cit; +#endif + class MANTID_GEOMETRY_DLL ParameterMap { public: @@ -148,6 +158,8 @@ namespace Geometry } } } + /// Method for adding a parameter providing shared pointer to it. The class stores share pointer and increment ref count to it + void add(const IComponent* comp,const boost::shared_ptr ¶m); /** @name Helper methods for adding and updating parameter types */ /// Create or adjust "pos" parameter for a component void addPositionCoordinate(const IComponent* comp,const std::string& name, const double value); @@ -285,6 +297,11 @@ namespace Geometry /// Retrieve a parameter by either creating a new one of getting an existing one Parameter_sptr retrieveParameter(bool &created, const std::string & type, const IComponent* comp, const std::string & name); + /// internal function to get position of the parameter in the parameter map + component_map_it getMapPlace(const IComponent* comp,const char *name, const char * type); + ///const version of the internal function to get position of the parameter in the parameter map + component_map_cit getMapPlace(const IComponent* comp,const char *name, const char * type)const; + /// internal parameter map instance pmap m_map; diff --git a/Code/Mantid/Framework/Geometry/src/Instrument/ParameterMap.cpp b/Code/Mantid/Framework/Geometry/src/Instrument/ParameterMap.cpp index 7544be861f05..baa2d7fbbbe3 100644 --- a/Code/Mantid/Framework/Geometry/src/Instrument/ParameterMap.cpp +++ b/Code/Mantid/Framework/Geometry/src/Instrument/ParameterMap.cpp @@ -247,6 +247,30 @@ namespace Mantid } } + /** Method for adding a parameter providing shared pointer to it. + * @param comp :: A pointer to the component that this parameter is attached to + * @param par :: a shared pointer to existing parameter. The ParameterMap stores share pointer and increment ref count to it + */ + void ParameterMap::add(const IComponent* comp,const boost::shared_ptr &par) + { + // can not add null pointer + if(!par)return; + + PARALLEL_CRITICAL(parameter_add) + { + auto existing_par = getMapPlace(comp,par->name().c_str(),""); + if (existing_par != m_map.end()) + { + existing_par->second = par; + } + else + { + m_map.insert(std::make_pair(comp->getComponentID(),par)); + } + } + + } + /** Create or adjust "pos" parameter for a component * Assumed that name either equals "x", "y" or "z" otherwise this * method will not add or modify "pos" parameter @@ -571,11 +595,62 @@ namespace Mantid { Parameter_sptr result; if(!comp) return result; - const bool anytype = (strlen(type) == 0); + PARALLEL_CRITICAL(ParameterMap_get) { - if( !m_map.empty() ) - { + auto itr = getMapPlace(comp,name, type); + if (itr != m_map.end()) + result = itr->second; + } + return result; + } + + /**Return an iterator pointing to a named parameter of a given type. + * @param comp :: Component to which parameter is related + * @param name :: Parameter name + * @param type :: An optional type string. If empty, any type is returned + * @returns The iterator parameter of the given type if it exists or a NULL shared pointer if not + */ + component_map_it ParameterMap::getMapPlace(const IComponent* comp,const char *name, const char * type) + { + pmap_it result = m_map.end(); + if(!comp) return result; + const bool anytype = (strlen(type) == 0); + if( !m_map.empty() ) + { + const ComponentID id = comp->getComponentID(); + pmap_it it_found = m_map.find(id); + if (it_found != m_map.end()) + { + pmap_it itr = m_map.lower_bound(id); + pmap_it itr_end = m_map.upper_bound(id); + for( ; itr != itr_end; ++itr ) + { + Parameter_sptr param = itr->second; + if( boost::iequals(param->nameAsCString(), name) && (anytype || param->type() == type) ) + { + result = itr; + break; + } + } + } + } + return result; + } + + /**Return a const iterator pointing to a named parameter of a given type. + * @param comp :: Component to which parameter is related + * @param name :: Parameter name + * @param type :: An optional type string. If empty, any type is returned + * @returns The iterator parameter of the given type if it exists or a NULL shared pointer if not + */ + component_map_cit ParameterMap::getMapPlace(const IComponent* comp,const char *name, const char * type)const + { + pmap_cit result = m_map.end(); + if(!comp) return result; + const bool anytype = (strlen(type) == 0); + if( !m_map.empty() ) + { const ComponentID id = comp->getComponentID(); pmap_cit it_found = m_map.find(id); if (it_found != m_map.end()) @@ -587,16 +662,17 @@ namespace Mantid Parameter_sptr param = itr->second; if( boost::iequals(param->nameAsCString(), name) && (anytype || param->type() == type) ) { - result = param; + result = itr; break; } } } - } - } + } return result; } + + /** Look for a parameter in the given component by the type of the parameter. * @param comp :: Component to which parameter is related * @param type :: Parameter type @@ -784,7 +860,7 @@ namespace Mantid } } - ///Attempts to retreive a location from the location cache + ///Attempts to retrieve a location from the location cache /// @param comp :: The Component to find the location of /// @param location :: If the location is found it's value will be set here /// @returns true if the location is in the map, otherwise false @@ -810,7 +886,7 @@ namespace Mantid } } - ///Attempts to retreive a rotation from the rotation cache + ///Attempts to retrieve a rotation from the rotation cache /// @param comp :: The Component to find the rotation of /// @param rotation :: If the rotation is found it's value will be set here /// @returns true if the rotation is in the map, otherwise false diff --git a/Code/Mantid/Framework/Geometry/test/ParameterMapTest.h b/Code/Mantid/Framework/Geometry/test/ParameterMapTest.h index c77797d8c161..f9e6f49ef599 100644 --- a/Code/Mantid/Framework/Geometry/test/ParameterMapTest.h +++ b/Code/Mantid/Framework/Geometry/test/ParameterMapTest.h @@ -61,6 +61,7 @@ class ParameterMapTest : public CxxTest::TestSuite ParameterMap pmapA; ParameterMap pmapB; + ParameterMap pmapG; // Empty TS_ASSERT_EQUALS(pmapA,pmapB); @@ -69,36 +70,61 @@ class ParameterMapTest : public CxxTest::TestSuite TS_ASSERT_EQUALS(pmapA,pmapA); // Differs from other TS_ASSERT_DIFFERS(pmapA,pmapB); + TS_ASSERT_DIFFERS(pmapA,pmapG); + + auto par= pmapA.getRecursive(m_testInstrument.get(),name); + pmapG.add(m_testInstrument.get(),par); + TS_ASSERT_EQUALS(pmapA,pmapG); // Same name/value/component pmapB.addDouble(m_testInstrument.get(), name, value); // Now equal TS_ASSERT_EQUALS(pmapA,pmapB); + TS_ASSERT_EQUALS(pmapA,pmapG); - ParameterMap pmapC; + //--- C + ParameterMap pmapC,pmapC1; // Same name/value different component IComponent_sptr comp = m_testInstrument->getChild(0); pmapC.addDouble(comp.get(), name, value); + auto par1=pmapC.getRecursive(comp.get(),name); + pmapC1.add(comp.get(), par1); // Differs from other TS_ASSERT_DIFFERS(pmapA,pmapC); + // Equal + TS_ASSERT_EQUALS(pmapC,pmapC1); + + //--- D // Same name/component different value ParameterMap pmapD; pmapD.addDouble(m_testInstrument.get(), name, value + 1.0); // Differs from other TS_ASSERT_DIFFERS(pmapA,pmapD); + // Adding the same replaces the same par + pmapD.add(m_testInstrument.get(), par1); + // Equal + TS_ASSERT_EQUALS(pmapA,pmapD); + + //--- E // Same value/component different name ParameterMap pmapE; pmapE.addDouble(m_testInstrument.get(), name + "_differ", value); // Differs from other TS_ASSERT_DIFFERS(pmapA,pmapE); + //--- F //Different type ParameterMap pmapF; pmapF.addInt(m_testInstrument.get(), name, 5); // Differs from other TS_ASSERT_DIFFERS(pmapA,pmapF); + // Adding the same replaces the same par regardless of type + pmapF.add(m_testInstrument.get(), par1); + // Equal + TS_ASSERT_EQUALS(pmapA,pmapF); + } void testAdding_A_Parameter_That_Is_Not_Present_Puts_The_Parameter_In() @@ -343,24 +369,24 @@ class ParameterMapTest : public CxxTest::TestSuite void test_copy_from_old_pmap_to_new_pmap_with_new_component(){ - IComponent_sptr oldComp = m_testInstrument->getChild(0); - IComponent_sptr newComp = m_testInstrument->getChild(1); + IComponent_sptr oldComp = m_testInstrument->getChild(0); + IComponent_sptr newComp = m_testInstrument->getChild(1); - ParameterMap oldPMap; - oldPMap.addBool(oldComp.get(), "A", false); - oldPMap.addDouble(oldComp.get(), "B", 1.2); + ParameterMap oldPMap; + oldPMap.addBool(oldComp.get(), "A", false); + oldPMap.addDouble(oldComp.get(), "B", 1.2); - ParameterMap newPMap; + ParameterMap newPMap; - TS_ASSERT_DIFFERS(oldPMap,newPMap); + TS_ASSERT_DIFFERS(oldPMap,newPMap); - newPMap.copyFromParameterMap(oldComp.get(),newComp.get(), &oldPMap); + newPMap.copyFromParameterMap(oldComp.get(),newComp.get(), &oldPMap); - TS_ASSERT_EQUALS(newPMap.contains(newComp.get(), "A", ParameterMap::pBool()), true); - TS_ASSERT_EQUALS(newPMap.contains(newComp.get(), "B", ParameterMap::pDouble()), true); + TS_ASSERT_EQUALS(newPMap.contains(newComp.get(), "A", ParameterMap::pBool()), true); + TS_ASSERT_EQUALS(newPMap.contains(newComp.get(), "B", ParameterMap::pDouble()), true); - Parameter_sptr a = newPMap.get(newComp.get(), "A"); - TS_ASSERT_EQUALS( a->value(), false); + Parameter_sptr a = newPMap.get(newComp.get(), "A"); + TS_ASSERT_EQUALS( a->value(), false); }