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