Diana Software
QIntervalSet.cc
Go to the documentation of this file.
1 #include "QIntervalSet.hh"
2 #include <algorithm>
3 #include "TString.h"
4 using std::list;
5 
6 QObjectImp(Diana::QIntervalSet);
7 
9 
11  : fIsLowerBoundSet(false), fIsUpperBoundSet(false)
12 {
13 }
14 
15 QIntervalSet::QIntervalSet(const double min, const double max)
16  : fIsLowerBoundSet(false), fIsUpperBoundSet(false)
17 {
18  QInterval interval(min, max);
19  fIntervals.push_back(interval);
20 }
21 
23 {
24  fIntervals.clear();
25  fIsLowerBoundSet = false;
26  fIsUpperBoundSet = false;
29 }
30 
31 void QIntervalSet::CloseGapsSmallerThan(const double smallestAllowedGap)
32 {
33  if (Size() >= 2) {
34  list<QInterval>::iterator currentInterval = fIntervals.begin();
35  list<QInterval>::iterator nextInterval = currentInterval;
36  ++nextInterval;
37  while (nextInterval != fIntervals.end()) {
38  const double gap
39  = nextInterval->GetMin() - currentInterval->GetMax();
40  if (gap <= smallestAllowedGap) {
41  // combine current and next intervals, eliminating gap
42  currentInterval->SetMax(nextInterval->GetMax());
43  fIntervals.erase(nextInterval);
44  }
45  else {
46  ++currentInterval;
47  }
48  nextInterval = currentInterval;
49  ++nextInterval;
50  }
51  }
52 
53  if (fIsLowerBoundSet && !fIntervals.empty()) {
54  const double gap = fIntervals.front().GetMin() - fLowerBound;
55  if (gap <= smallestAllowedGap) {
56  // eliminate gap between lower bound and first interval
57  fIntervals.front().SetMin(fLowerBound);
58  }
59  }
60  if (fIsUpperBoundSet && !fIntervals.empty()) {
61  const double gap = fUpperBound - fIntervals.back().GetMax();
62  if (gap <= smallestAllowedGap) {
63  // eliminate gap between last interval and upper bound
64  fIntervals.back().SetMax(fUpperBound);
65  }
66  }
67 }
68 
70 {
71  bool foundOverlappedIntervals = false;
72 
73  list<QInterval>::iterator currentInterval = fIntervals.begin();
74  while (foundOverlappedIntervals == false
75  && currentInterval != fIntervals.end()) {
76  list<QInterval>::iterator nextInterval = currentInterval;
77  ++nextInterval;
78  if (nextInterval != fIntervals.end()) {
79  if (currentInterval->GetMax() >= nextInterval->GetMin()) {
80  foundOverlappedIntervals = true;
81  currentInterval->SetMax(
82  std::max(currentInterval->GetMax(), nextInterval->GetMax())
83  );
84  fIntervals.erase(nextInterval);
85  }
86  }
87 
88  ++currentInterval;
89  }
90 
91  if (foundOverlappedIntervals) {
92  Consolidate();
93  }
94 
95  return foundOverlappedIntervals;
96 }
97 
98 bool QIntervalSet::Contains(const double value) const
99 {
100  bool contains = false;
101 
102  list<QInterval>::const_iterator currentInterval = fIntervals.begin();
103  while (currentInterval != fIntervals.end()
104  && value >= currentInterval->GetMin()) {
105  contains = currentInterval->Contains(value);
106  ++currentInterval;
107  }
108 
109  return contains;
110 }
111 
113 {
114  QMatrix matrix(Size(), 2);
115  int row = 0;
116  std::list<QInterval>::const_iterator interval;
117  for (interval = fIntervals.begin();
118  interval != fIntervals.end();
119  ++interval, ++row) {
120  matrix(row, 0) = interval->GetMin();
121  matrix(row, 1) = interval->GetMax();
122  }
123  return matrix;
124 }
125 
127 {
128  if (fIsLowerBoundSet && interval.GetMin() < fLowerBound) {
129  if (interval.GetMax() <= fLowerBound) {
130  return;
131  }
132  interval.SetMin(fLowerBound);
133  }
134  if (fIsUpperBoundSet && interval.GetMax() > fUpperBound) {
135  if (interval.GetMin() >= fUpperBound) {
136  return;
137  }
138  interval.SetMax(fUpperBound);
139  }
140 
141  if (fIntervals.empty()) {
142  fIntervals.push_back(interval);
143  }
144  else if (interval.GetMin() > GetMax()) {
145  fIntervals.push_back(interval);
146  }
147  else if (interval.GetMax() < GetMin()) {
148  fIntervals.insert(fIntervals.begin(), interval);
149  }
150  else {
151  list<QInterval>::iterator insertionPoint
152  = lower_bound(fIntervals.begin(), fIntervals.end(), interval);
153  // insertionPoint refers to the first position in which interval can be
154  // inserted while preserving the ordering
155  // (the ordering is like std::pair)
156  if (insertionPoint == fIntervals.end()) {
157  bool intersectsPreceeding
158  = interval.GetMin() <= fIntervals.back().GetMax();
159  if (intersectsPreceeding) {
160  // expand preceeding interval
161  fIntervals.back().SetMax(
162  std::max(interval.GetMax(), fIntervals.back().GetMax()));
163  }
164  else {
165  // interval is past last interval in fIntervals
166  fIntervals.push_back(interval);
167  }
168  }
169  else if (insertionPoint == fIntervals.begin()) {
170  bool intersectsFollowing
171  = interval.GetMax() >= fIntervals.front().GetMin();
172  if (intersectsFollowing) {
173  // extend following interval
174  fIntervals.front().SetMin(
175  std::min(interval.GetMin(), fIntervals.front().GetMin())
176  );
177  fIntervals.front().SetMax(
178  std::max(interval.GetMax(), fIntervals.front().GetMax())
179  );
180  }
181  else {
182  // interval is before first interval in fIntervals
183  fIntervals.insert(insertionPoint, interval);
184  }
185  }
186  else {
187  list<QInterval>::iterator preceedingInterval = insertionPoint;
188  --preceedingInterval;
189  bool intersectsPreceeding
190  = interval.GetMin() <= preceedingInterval->GetMax();
191  bool intersectsFollowing
192  = interval.GetMax() >= insertionPoint->GetMin();
193  if (!intersectsPreceeding && !intersectsFollowing) {
194  // interval is disjoint from existing intervals in fIntervals
195  // insert interval
196  fIntervals.insert(insertionPoint, interval);
197  }
198  else if (intersectsPreceeding && !intersectsFollowing) {
199  // extend preceeding interval
200  preceedingInterval->SetMax(
201  std::max(
202  interval.GetMax(),
203  preceedingInterval->GetMax()
204  )
205  );
206  }
207  else if (intersectsFollowing && !intersectsPreceeding) {
208  // extend following interval
209  insertionPoint->SetMin(
210  std::min(
211  interval.GetMin(),
212  insertionPoint->GetMin()
213  )
214  );
215  insertionPoint->SetMax(
216  std::max(
217  interval.GetMax(),
218  insertionPoint->GetMax()
219  )
220  );
221  }
222  else if (intersectsPreceeding && intersectsFollowing) {
223  // combine preceeding and following intervals
224  preceedingInterval->SetMax(
225  std::max(
226  interval.GetMax(),
227  insertionPoint->GetMax()
228  )
229  );
230  fIntervals.erase(insertionPoint);
231  }
232  }
233  }
234 
235  Consolidate();
236 }
237 
238 double QIntervalSet::Length() const
239 {
240  double length = 0;
241  for (list<QInterval>::const_iterator interval = fIntervals.begin();
242  interval != fIntervals.end();
243  ++interval) {
244  length += interval->Length();
245  }
246  return length;
247 }
248 
249 void QIntervalSet::RemoveIntervalsShorterThan(const double minimumLength)
250 {
251  list<QInterval>::iterator currentInterval = fIntervals.begin();
252  while (currentInterval != fIntervals.end()) {
253  if (currentInterval->Length() <= minimumLength) {
254  currentInterval = fIntervals.erase(currentInterval);
255  }
256  else {
257  ++currentInterval;
258  }
259  }
260 }
261 
262 void QIntervalSet::SetLowerBound(const double lowerBound)
263 {
264  fLowerBound = lowerBound;
265  fIsLowerBoundSet = true;
266 
267  while (!fIntervals.empty() && GetMin() < fLowerBound) {
268  if (fIntervals.front().GetMax() <= fLowerBound) {
269  fIntervals.pop_front();
270  }
271  else {
272  fIntervals.front().SetMin(fLowerBound);
273  break;
274  }
275  }
276 }
277 
278 void QIntervalSet::SetUpperBound(const double upperBound)
279 {
280  fUpperBound = upperBound;
281  fIsUpperBoundSet = true;
282 
283  while (!fIntervals.empty() && GetMax() > fUpperBound) {
284  if (fIntervals.back().GetMin() >= fUpperBound) {
285  fIntervals.pop_back();
286  }
287  else {
288  fIntervals.back().SetMax(fUpperBound);
289  break;
290  }
291  }
292 }
293 
294 void QIntervalSet::Dump(std::ostream &o) const {
295  o << "Lower Bound : " << (fIsLowerBoundSet ? Form("%f",fLowerBound) : "None") << std::endl;
296  o << "Upper Bound : " << (fIsUpperBoundSet ? Form("%f",fUpperBound) : "None") << std::endl;
297 
298  std::list<QInterval>::const_iterator it;
299  for(it=fIntervals.begin();it!=fIntervals.end();it++) {
300  o << "\t" << it->GetMin() << " - " << it->GetMax() << std::endl;
301  }
302 }
303 
double max
Definition: CheckOF.C:53
#define Q_DOUBLE_DEFAULT
Definition: QDiana.hh:24
#define Q_END_NAMESPACE
Definition: QDiana.hh:22
#define Q_BEGIN_NAMESPACE
Definition: QDiana.hh:20
QObjectImp(Diana::QIntervalSet)
double min(const Diana::QVector &v)
Definition: QVector.cc:878
void RemoveIntervalsShorterThan(const double minimumLength)
Remove intervals shorter than minimumLength.
std::list< QInterval > fIntervals
Intervals in the set.
Definition: QIntervalSet.hh:84
double Length() const
Get total length of all intervals in the set.
void CloseGapsSmallerThan(const double smallestAllowedGap)
Close gaps smaller than smallestAllowedGap.
Definition: QIntervalSet.cc:31
void Dump(std::ostream &o) const
Dump the intervals to a stream.
void SetLowerBound(const double lowerBound)
Set lower bound on the contents of the set.
QIntervalSet()
Default constructor.
Definition: QIntervalSet.cc:10
QMatrix GetMatrix()
Get matrix containing the intervals.
double fUpperBound
Upper bound on the contents of the set.
Definition: QIntervalSet.hh:96
double GetMax() const
Get maximum of all intervals in the set.
Definition: QIntervalSet.hh:50
size_t Size() const
Get number of intervals in the set.
Definition: QIntervalSet.hh:77
void Insert(const double min, const double max)
Add interval to the set.
Definition: QIntervalSet.hh:58
void Clear()
Clear()
Definition: QIntervalSet.cc:22
bool Contains(const double value) const
Return whether the interval set contains a value.
Definition: QIntervalSet.cc:98
double GetMin() const
Get minimum of all intervals in the set.
Definition: QIntervalSet.hh:54
void SetUpperBound(const double upperBound)
Set upper bound on the contents of the set.
bool Consolidate()
Consolidate overlapped intervals.
Definition: QIntervalSet.cc:69
bool fIsLowerBoundSet
Whether or not a lower bound is set.
Definition: QIntervalSet.hh:87
bool fIsUpperBoundSet
Whether or not an upper bound is set.
Definition: QIntervalSet.hh:90
double fLowerBound
Lower bound on the contents of the set.
Definition: QIntervalSet.hh:93
Interval of real numbers.
Definition: QInterval.hh:17
void SetMin(const double min)
Set minimum of the interval.
Definition: QInterval.hh:71
void SetMax(const double max)
Set maximum of the interval.
Definition: QInterval.hh:68
double GetMax() const
Get maximum of interval.
Definition: QInterval.hh:54
double GetMin() const
Get minimum of interval.
Definition: QInterval.hh:57
Interface for matrices in Diana analysis.
Definition: QMatrix.hh:24