Belle II Software  release-05-01-25
relationsobject.cc
1 #include <framework/datastore/StoreArray.h>
2 #include <framework/dataobjects/EventMetaData.h>
3 #include <framework/dataobjects/ProfileInfo.h>
4 #include <framework/datastore/RelationsObject.h>
5 #include <framework/utilities/TestHelpers.h>
6 
7 #include <gtest/gtest.h>
8 
9 using namespace std;
10 using namespace Belle2;
11 
12 namespace {
14  class RelationsObjectTest : public ::testing::Test {
15  protected:
17  void SetUp() override
18  {
19  evtData.registerInDataStore();
20  profileData.registerInDataStore();
21  relObjData.registerInDataStore();
22 
23  for (int i = 0; i < 10; ++i) {
24  evtData.appendNew();
25  profileData.appendNew();
26  relObjData.appendNew();
27  }
28  }
29 
31  void TearDown() override
32  {
33  DataStore::Instance().reset();
34  }
35 
37  StoreArray<ProfileInfo> profileData;
38  StoreArray<RelationsObject> relObjData;
39  };
40 
42  TEST_F(RelationsObjectTest, RelationsObject)
43  {
44  relObjData.registerRelationTo(profileData);
45  DataStore::Instance().setInitializeActive(false);
46 
47  (relObjData)[0]->addRelationTo((profileData)[0], -42.0);
48 
49  //getRelations
50  RelationVector<ProfileInfo> rels = (relObjData)[0]->getRelationsTo<ProfileInfo>();
51  EXPECT_TRUE(rels.size() == 1);
52  EXPECT_TRUE(rels.object(0) == (profileData)[0]);
53  EXPECT_DOUBLE_EQ(rels.weight(0), -42.0);
54  EXPECT_EQ(0u, relObjData[1]->getRelationsTo<ProfileInfo>().size());
55  EXPECT_EQ(0u, relObjData[0]->getRelationsFrom<ProfileInfo>().size());
56  EXPECT_EQ(1u, relObjData[0]->getRelationsWith<ProfileInfo>().size());
57 
58  //getRelated
59  EXPECT_TRUE(profileData[0] == relObjData[0]->getRelatedTo<ProfileInfo>());
60  EXPECT_TRUE(nullptr == relObjData[1]->getRelatedTo<ProfileInfo>());
61  EXPECT_TRUE(nullptr == relObjData[0]->getRelatedFrom<ProfileInfo>());
62  EXPECT_TRUE(profileData[0] == relObjData[0]->getRelated<ProfileInfo>());
63 
64  //getRelatedWithWeight
65  EXPECT_TRUE(std::make_pair(profileData[0], -42.0f) == relObjData[0]->getRelatedToWithWeight<ProfileInfo>());
66  ProfileInfo* profileNullPtr = nullptr;
67  EXPECT_TRUE(std::make_pair(profileNullPtr, 1.0f) == relObjData[1]->getRelatedToWithWeight<ProfileInfo>());
68  EXPECT_TRUE(std::make_pair(profileNullPtr, 1.0f) == relObjData[0]->getRelatedFromWithWeight<ProfileInfo>());
69  EXPECT_TRUE(std::make_pair(profileData[0], -42.0f) == relObjData[0]->getRelatedWithWeight<ProfileInfo>());
70 
71 
72  //adding relations to NULL is safe and doesn't do anything
73  (relObjData)[0]->addRelationTo(static_cast<TObject*>(nullptr));
74  (relObjData)[0]->addRelationTo(static_cast<ProfileInfo*>(nullptr));
75 
76  //if we cannot create a relation to an actual object given, this is obivously wrong
77  ProfileInfo notInArray;
78  EXPECT_B2FATAL((relObjData)[0]->addRelationTo(&notInArray));
79  }
80 
82  TEST_F(RelationsObjectTest, IndexUpdating)
83  {
84  relObjData.registerRelationTo(profileData);
85  DataStore::Instance().setInitializeActive(false);
86 
87  //not yet set
88  EXPECT_FALSE((relObjData)[0]->getRelated<ProfileInfo>() != nullptr);
89 
90  (relObjData)[0]->addRelationTo((profileData)[0], -42.0);
91 
92  //now it should be found (index updated because RelationContainer was just created)
93  EXPECT_TRUE((relObjData)[0]->getRelated<ProfileInfo>() != nullptr);
94 
95  //test again with different object
96  EXPECT_FALSE((relObjData)[1]->getRelated<ProfileInfo>() != nullptr);
97 
98  (relObjData)[1]->addRelationTo((profileData)[0], -42.0);
99 
100  //now it should be found (index updated because addRelation marks RelationContainer as modified)
101  EXPECT_TRUE((relObjData)[1]->getRelated<ProfileInfo>() != nullptr);
102  }
103 
105  TEST_F(RelationsObjectTest, RelationsObjectArrayIndex)
106  {
107  for (int i = 0; i < relObjData.getEntries(); i++) {
108  EXPECT_TRUE((relObjData)[i]->getArrayName() == relObjData.getName());
109  EXPECT_TRUE((relObjData)[i]->getArrayIndex() == i);
110  }
111 
112  RelationsObject bla;
113  EXPECT_TRUE(bla.getArrayName() == "");
114  EXPECT_TRUE(bla.getArrayIndex() == -1);
115  }
116 
118  TEST_F(RelationsObjectTest, DuplicateRelations)
119  {
120  evtData.registerRelationTo(relObjData);
121  relObjData.registerRelationTo(evtData);
122  DataStore::Instance().setInitializeActive(false);
123 
124  //more than a single relation in one direction
125  DataStore::Instance().addRelationFromTo((evtData)[0], (relObjData)[1], 1.0);
126  DataStore::Instance().addRelationFromTo((evtData)[0], (relObjData)[1], 2.0);
127 
128  //since the relation wasn't consolidated, these should still show up as
129  //seperate things
130  RelationVector<EventMetaData> rels1 = (relObjData)[1]->getRelationsFrom<EventMetaData>();
131  EXPECT_EQ(2u, rels1.size());
132 
133 
134  //preserve order
135  EXPECT_FLOAT_EQ(1.0, rels1.weight(0));
136  EXPECT_FLOAT_EQ(2.0, rels1.weight(1));
137  EXPECT_FLOAT_EQ(1.0, relObjData[1]->getRelatedFromWithWeight<EventMetaData>().second);
138 
139 
140  //add another one in opposite direction
141  DataStore::Instance().addRelationFromTo((relObjData)[1], (evtData)[0], 1.0);
142  RelationVector<EventMetaData> rels2 = (relObjData)[1]->getRelationsFrom<EventMetaData>();
143  //wasn't _from_ eventmetadata, so no change
144  EXPECT_EQ(2u, rels2.size());
145 
146  RelationVector<EventMetaData> rels3 = (relObjData)[1]->getRelationsWith<EventMetaData>();
147  EXPECT_EQ(3u, rels3.size());
148  double sum = 0.0;
149  for (int i = 0; i < (int)rels3.size(); i++) {
150  sum += rels3.weight(i);
151  }
152  EXPECT_DOUBLE_EQ(sum, 1.0 + 1.0 + 2.0);
153  }
154 
155  TEST_F(RelationsObjectTest, RelationsToSameArray)
156  {
157  relObjData.registerRelationTo(relObjData);
158  DataStore::Instance().setInitializeActive(false);
159 
160  relObjData[0]->addRelationTo(relObjData[1]);
161  EXPECT_TRUE(relObjData[0] == relObjData[1]->getRelated<RelationsObject>());
162  EXPECT_TRUE(relObjData[0] == relObjData[1]->getRelatedFrom<RelationsObject>());
163  EXPECT_TRUE(relObjData[1] == relObjData[0]->getRelated<RelationsObject>());
164  EXPECT_TRUE(relObjData[1] == relObjData[0]->getRelatedTo<RelationsObject>());
165  EXPECT_TRUE(nullptr == relObjData[2]->getRelated<RelationsObject>());
166  EXPECT_TRUE(nullptr == relObjData[2]->getRelatedFrom<RelationsObject>());
167  EXPECT_TRUE(nullptr == relObjData[2]->getRelatedTo<RelationsObject>());
168  //still in one direction
169  EXPECT_TRUE(nullptr == relObjData[1]->getRelatedTo<RelationsObject>());
170  EXPECT_TRUE(nullptr == relObjData[0]->getRelatedFrom<RelationsObject>());
171 
172  //to same object
173  relObjData[3]->addRelationTo(relObjData[3]);
174  EXPECT_TRUE(relObjData[3] == relObjData[3]->getRelated<RelationsObject>());
175  EXPECT_TRUE(relObjData[3] == relObjData[3]->getRelatedFrom<RelationsObject>());
176  EXPECT_TRUE(relObjData[3] == relObjData[3]->getRelatedTo<RelationsObject>());
177  }
178 
179  TEST_F(RelationsObjectTest, ModifyRelations)
180  {
181  relObjData.registerRelationTo(profileData);
182  DataStore::Instance().setInitializeActive(false);
183 
184  (relObjData)[0]->addRelationTo((profileData)[0], -42.0);
185 
186  //weights
187  RelationVector<ProfileInfo> rels = (relObjData)[0]->getRelationsTo<ProfileInfo>();
188  EXPECT_DOUBLE_EQ(rels.weight(0), -42.0);
189  rels.setWeight(0, -3.0);
190  EXPECT_DOUBLE_EQ(rels.weight(0), -3.0); //updated immediately
191  RelationVector<ProfileInfo> rels2 = (relObjData)[0]->getRelationsTo<ProfileInfo>();
192  EXPECT_DOUBLE_EQ(rels2.weight(0), -3.0); //and in DataStore
193 
194  //removal
195  EXPECT_EQ(1u, relObjData[0]->getRelationsTo<ProfileInfo>().size());
196  EXPECT_EQ(1u, relObjData[0]->getRelationsWith<ProfileInfo>().size());
197  rels2.remove(0);
198  EXPECT_EQ(0u, rels2.size());
199  EXPECT_EQ(0u, relObjData[0]->getRelationsTo<ProfileInfo>().size());
200  EXPECT_EQ(0u, relObjData[0]->getRelationsWith<ProfileInfo>().size());
201  }
202 
204  TEST_F(RelationsObjectTest, NamedRelationsWithInvalidName)
205  {
206  const std::string relationName = "ExtraRelation WithSpaceInName";
207  EXPECT_B2FATAL(relObjData.registerRelationTo(profileData, DataStore::c_Event, DataStore::c_WriteOut, relationName));
208  }
209 
211  TEST_F(RelationsObjectTest, NamedRelations)
212  {
213  const std::string relationName = "ExtraRelation";
214  relObjData.registerRelationTo(profileData, DataStore::c_Event, DataStore::c_WriteOut, relationName);
215  DataStore::Instance().setInitializeActive(false);
216 
217  //check the hasRelation finder works with and without names
218  EXPECT_TRUE(relObjData.hasRelationTo(profileData, DataStore::c_Event, relationName));
219  EXPECT_FALSE(profileData.hasRelationTo(relObjData, DataStore::c_Event, relationName));
220  EXPECT_FALSE(profileData.hasRelationTo(evtData, DataStore::c_Event, relationName));
221  EXPECT_FALSE(relObjData.hasRelationTo(profileData));
222  EXPECT_FALSE(profileData.hasRelationTo(relObjData));
223 
224  (relObjData)[0]->addRelationTo((profileData)[0], -42.0, relationName);
225 
226  //getRelations
227  RelationVector<ProfileInfo> rels = (relObjData)[0]->getRelationsTo<ProfileInfo>("", relationName);
228  EXPECT_TRUE(rels.size() == 1);
229  EXPECT_TRUE(rels.object(0) == (profileData)[0]);
230  EXPECT_DOUBLE_EQ(rels.weight(0), -42.0);
231  EXPECT_EQ(0u, relObjData[1]->getRelationsTo<ProfileInfo>("", relationName).size());
232  EXPECT_EQ(0u, relObjData[0]->getRelationsFrom<ProfileInfo>("", relationName).size());
233  EXPECT_EQ(1u, relObjData[0]->getRelationsWith<ProfileInfo>("", relationName).size());
234 
235  //getRelated
236  EXPECT_TRUE(profileData[0] == relObjData[0]->getRelatedTo<ProfileInfo>("", relationName));
237  EXPECT_TRUE(nullptr == relObjData[1]->getRelatedTo<ProfileInfo>("", relationName));
238  EXPECT_TRUE(nullptr == relObjData[0]->getRelatedFrom<ProfileInfo>("", relationName));
239  EXPECT_TRUE(profileData[0] == relObjData[0]->getRelated<ProfileInfo>("", relationName));
240 
241  //getRelatedWithWeight
242  EXPECT_TRUE(std::make_pair(profileData[0], -42.0f) == relObjData[0]->getRelatedToWithWeight<ProfileInfo>("", relationName));
243  ProfileInfo* profileNullPtr = nullptr;
244  EXPECT_TRUE(std::make_pair(profileNullPtr, 1.0f) == relObjData[1]->getRelatedToWithWeight<ProfileInfo>("", relationName));
245  EXPECT_TRUE(std::make_pair(profileNullPtr, 1.0f) == relObjData[0]->getRelatedFromWithWeight<ProfileInfo>("", relationName));
246  EXPECT_TRUE(std::make_pair(profileData[0], -42.0f) == relObjData[0]->getRelatedWithWeight<ProfileInfo>("", relationName));
247 
248  // Check if the "ALL" parameter also works
249  StoreEntry* storeEntry = nullptr;
250  int index = -1;
251  DataStore::Instance().getRelationsWith(DataStore::c_FromSide, (relObjData)[0], storeEntry, index,
252  TObject::Class(), "ALL", "");
253 
254  //adding relations to NULL is safe and doesn't do anything
255  (relObjData)[0]->addRelationTo(static_cast<TObject*>(nullptr), 1.0, relationName);
256  (relObjData)[0]->addRelationTo(static_cast<ProfileInfo*>(nullptr), 1.0, relationName);
257 
258  //if we cannot create a relation to an actual object given, this is obivously wrong
259  ProfileInfo notInArray;
260  EXPECT_B2FATAL((relObjData)[0]->addRelationTo(&notInArray, 1.0, relationName));
261  }
262 
263 } // namespace
Belle2::RelationVector::size
size_t size() const
Get number of relations.
Definition: RelationVector.h:98
Belle2::ProfileInfo
Store execution time and memory usage.
Definition: ProfileInfo.h:32
Belle2::StoreEntry
Wraps a stored array/object, stored under unique (name, durability) key.
Definition: StoreEntry.h:15
Belle2::RelationsInterface::getArrayName
std::string getArrayName() const
Get name of array this object is stored in, or "" if not found.
Definition: RelationsObject.h:379
Belle2::RelationVector
Class for type safe access to objects that are referred to in relations.
Definition: DataStore.h:38
Belle2::RelationVector::remove
void remove(int index)
Remove relation at given index.
Definition: RelationVector.h:129
Belle2::RelationVector::setWeight
void setWeight(int index, float weight)
Set a new weight for the given relation.
Definition: RelationVector.h:141
Belle2
Abstract base class for different kinds of events.
Definition: MillepedeAlgorithm.h:19
Belle2::RelationVector::object
T * object(int index) const
Get object with index.
Definition: RelationVector.h:106
Belle2::TEST_F
TEST_F(GlobalLabelTest, LargeNumberOfTimeDependentParameters)
Test large number of time-dep params for registration and retrieval.
Definition: globalLabel.cc:65
Belle2::RelationsInterface::getArrayIndex
int getArrayIndex() const
Returns this object's array index (in StoreArray), or -1 if not found.
Definition: RelationsObject.h:387
Belle2::RelationVector::weight
float weight(int index) const
Get weight with index.
Definition: RelationVector.h:120
Belle2::StoreArray
Accessor to arrays stored in the data store.
Definition: ECLMatchingPerformanceExpertModule.h:33
Belle2::RelationsInterface
Defines interface for accessing relations of objects in StoreArray.
Definition: RelationsObject.h:102