CMS 3D CMS Logo

clusteringTreeConverters.h
Go to the documentation of this file.
1 //
2 // Code converting data between FFTJet clustering tree objects and
3 // event-storable entities. The data can be stored in either single
4 // or double precision. If the data is stored in double precision,
5 // the clustering tree can be restored in its original form.
6 //
7 // Written by:
8 //
9 // Terence Libeiro
10 // Igor Volobouev
11 //
12 // June 2010
13 
14 #ifndef RecoJets_FFTJetAlgorithms_clusteringTreeConverters_h
15 #define RecoJets_FFTJetAlgorithms_clusteringTreeConverters_h
16 
17 #include <cfloat>
18 
19 #include "fftjet/Peak.hh"
20 #include "fftjet/AbsClusteringTree.hh"
21 #include "fftjet/SparseClusteringTree.hh"
22 
26 
27 namespace fftjetcms {
28  // The function below makes PattRecoTree storable in the event
29  // record out of a sparse clustering tree of fftjet::Peak objects
30  template<class Real>
32  const fftjet::SparseClusteringTree<fftjet::Peak,long>& in,
33  bool writeOutScaleInfo,
35 
36  // The function below restores sparse clustering tree of fftjet::Peak
37  // objects using the PattRecoTree. The "completeEventScale" parameter
38  // should be set to the appropriate scale in case the complete event
39  // was written out and its scale not stored in the event. If the complete
40  // event was not written out, the scale must be set to 0.
41  template<class Real>
44  const std::vector<double>* scaleSetIfNotAdaptive,
45  double completeEventScale,
46  fftjet::SparseClusteringTree<fftjet::Peak,long>* out);
47 
48  // The function below makes PattRecoTree storable in the event
49  // record out of a dense clustering tree of fftjet::Peak objects
50  template<class Real>
52  const fftjet::AbsClusteringTree<fftjet::Peak,long>& in,
53  bool writeOutScaleInfo,
55 
56  // The function below restores dense clustering tree of fftjet::Peak
57  // objects using the PattRecoTree. The "completeEventScale" parameter
58  // should be set to the appropriate scale in case the complete event
59  // was written out and its scale not stored in the event. If the complete
60  // event was not written out, the scale must be set to 0.
61  template<class Real>
64  const std::vector<double>* scaleSetIfNotAdaptive,
65  double completeEventScale,
66  fftjet::AbsClusteringTree<fftjet::Peak,long>* out);
67 }
68 
70 //
71 // Implementation follows
72 //
74 
75 namespace fftjetcms {
76  // The function below makes PattRecoTree storable in the event
77  // record out of a sparse clustering tree of fftjet::Peak objects
78  template<class Real>
80  const fftjet::SparseClusteringTree<fftjet::Peak,long>& sparseTree,
81  const bool writeOutScaleInfo,
83  {
84  typedef fftjet::SparseClusteringTree<fftjet::Peak,long> SparseTree;
85  typedef reco::PattRecoPeak<Real> StoredPeak;
86  typedef reco::PattRecoNode<StoredPeak> StoredNode;
87  typedef reco::PattRecoTree<Real,StoredPeak> StoredTree;
88 
89  assert(tree);
90 
91  tree->clear();
92  tree->setSparse(true);
93 
94  const unsigned nNodes = sparseTree.size();
95  double hessian[3] = {0., 0., 0.};
96 
97  // Do not write out the meaningless top node
98  tree->reserveNodes(nNodes - 1);
99  for (unsigned i=1; i<nNodes; ++i)
100  {
101  const SparseTree::Node& node(sparseTree.getNode(i));
102  const fftjet::Peak& peak(node.getCluster());
103  peak.hessian(hessian);
104  StoredNode sn(StoredPeak(peak.eta(),
105  peak.phi(),
106  peak.magnitude(),
107  hessian,
108  peak.driftSpeed(),
109  peak.magSpeed(),
110  peak.lifetime(),
111  peak.scale(),
112  peak.nearestNeighborDistance(),
113  peak.clusterRadius(),
114  peak.clusterSeparation(),
115  peak.splitTime(),
116  peak.mergeTime()),
117  node.originalLevel(),
118  node.mask(),
119  node.parent());
120  tree->addNode(sn);
121  }
122 
123  // Do we want to write out the scales? We will use the following
124  // convention: if the tree is using an adaptive algorithm, the scales
125  // will be written out. If not, they are not going to change from
126  // event to event. In this case the scales would waste disk space
127  // for no particularly good reason, so they will not be written out.
128  if (writeOutScaleInfo)
129  {
130  // Do not write out the meaningless top-level scale
131  const unsigned nScales = sparseTree.nLevels();
132  tree->reserveScales(nScales - 1);
133  for (unsigned i=1; i<nScales; ++i)
134  tree->addScale(sparseTree.getScale(i));
135  }
136  }
137 
138  // The function below restores sparse clustering tree of fftjet::Peak
139  // objects using the PattRecoTree
140  template<class Real>
143  const std::vector<double>* scaleSetIfNotAdaptive,
144  const double completeEventScale,
145  fftjet::SparseClusteringTree<fftjet::Peak,long>* out)
146  {
147  typedef fftjet::SparseClusteringTree<fftjet::Peak,long> SparseTree;
148  typedef reco::PattRecoPeak<Real> StoredPeak;
149  typedef reco::PattRecoNode<StoredPeak> StoredNode;
150  typedef reco::PattRecoTree<Real,StoredPeak> StoredTree;
151 
152  if (!in.isSparse())
153  throw cms::Exception("FFTJetBadConfig")
154  << "can't restore sparse clustering tree"
155  << " from densely stored record" << std::endl;
156 
157  assert(out);
158  out->clear();
159 
160  const std::vector<StoredNode>& nodes(in.getNodes());
161  const unsigned n = nodes.size();
162  out->reserveNodes(n + 1U);
163 
164  double hessian[3] = {0., 0., 0.};
165 
166  for (unsigned i=0; i<n; ++i)
167  {
168  const StoredNode& snode(nodes[i]);
169  const StoredPeak& p(snode.getCluster());
170  p.hessian(hessian);
171  fftjet::Peak peak(p.eta(), p.phi(), p.magnitude(),
172  hessian, p.driftSpeed(),
173  p.magSpeed(), p.lifetime(),
174  p.scale(), p.nearestNeighborDistance(),
175  1.0, 0.0, 0.0,
176  p.clusterRadius(), p.clusterSeparation());
177  peak.setSplitTime(p.splitTime());
178  peak.setMergeTime(p.mergeTime());
179  const SparseTree::Node node(peak, snode.originalLevel(),
180  snode.mask());
181  out->addNode(node, snode.parent());
182  }
183 
184  const std::vector<Real>& storedScales(in.getScales());
185  if (!storedScales.empty())
186  {
187  const unsigned nsc = storedScales.size();
188  out->reserveScales(nsc + 1U);
189  out->addScale(DBL_MAX);
190  const Real* scales = &storedScales[0];
191  for (unsigned i=0; i<nsc; ++i)
192  out->addScale(scales[i]);
193  }
194  else if (scaleSetIfNotAdaptive && !scaleSetIfNotAdaptive->empty())
195  {
196  const unsigned nsc = scaleSetIfNotAdaptive->size();
197  // There may be the "complete event" scale added at the end.
198  // Reserve a sufficient number of scales to take this into
199  // account.
200  if (completeEventScale)
201  out->reserveScales(nsc + 2U);
202  else
203  out->reserveScales(nsc + 1U);
204  out->addScale(DBL_MAX);
205  const double* scales = &(*scaleSetIfNotAdaptive)[0];
206  for (unsigned i=0; i<nsc; ++i)
207  out->addScale(scales[i]);
208  if (completeEventScale)
209  out->addScale(completeEventScale);
210  }
211  else
212  {
213  throw cms::Exception("FFTJetBadConfig")
214  << "can't restore sparse clustering tree scales"
215  << std::endl;
216  }
217  }
218 
219  // The function below makes PattRecoTree storable in the event
220  // record out of a dense clustering tree of fftjet::Peak objects
221  template<class Real>
223  const fftjet::AbsClusteringTree<fftjet::Peak,long>& in,
224  bool writeOutScaleInfo,
226  {
227  typedef fftjet::AbsClusteringTree<fftjet::Peak,long> DenseTree;
228  typedef reco::PattRecoPeak<Real> StoredPeak;
229  typedef reco::PattRecoNode<StoredPeak> StoredNode;
230  typedef reco::PattRecoTree<Real,StoredPeak> StoredTree;
231 
232  assert(out);
233  out->clear();
234  out->setSparse(false);
235 
236  const unsigned nLevels = in.nLevels();
237  double hessian[3] = {0., 0., 0.};
238 
239  // Do not write out the meaningless top node
240  out->reserveNodes(in.nClusters() - 1);
241 
242  for (unsigned i=1; i<nLevels; ++i)
243  {
244  const unsigned int nclus = in.nClusters(i);
245  DenseTree::NodeId id(i,0);
246  for (; id.second<nclus; ++id.second)
247  {
248  const fftjet::Peak& peak(in.getCluster(id));
249  peak.hessian(hessian);
250  StoredNode sn(StoredPeak(peak.eta(),
251  peak.phi(),
252  peak.magnitude(),
253  hessian,
254  peak.driftSpeed(),
255  peak.magSpeed(),
256  peak.lifetime(),
257  peak.scale(),
258  peak.nearestNeighborDistance(),
259  peak.clusterRadius(),
260  peak.clusterSeparation(),
261  peak.splitTime(),
262  peak.mergeTime()),
263  i,
264  0,
265  0);
266  out->addNode(sn);
267  }
268  }
269 
270  // Do we want to write out the scales? We will use the following
271  // convention: if the tree is using an adaptive algorithm, the scales
272  // will be written out. If not, they are not going to change from
273  // event to event. In this case the scales would waste disk space
274  // for no particularly good reason, so they will not be written out.
275  if (writeOutScaleInfo)
276  {
277  // Do not write out the meaningless top-level scale
278  const unsigned nScales = in.nLevels();
279  out->reserveScales(nScales - 1);
280  for (unsigned i=1; i<nScales; ++i)
281  out->addScale(in.getScale(i));
282  }
283  }
284 
285  // The function below restores dense clustering tree of fftjet::Peak
286  // objects using the PattRecoTree
287  template<class Real>
290  const std::vector<double>* scaleSetIfNotAdaptive,
291  const double completeEventScale,
292  fftjet::AbsClusteringTree<fftjet::Peak,long>* out)
293  {
294  typedef fftjet::AbsClusteringTree<fftjet::Peak,long> DenseTree;
295  typedef reco::PattRecoPeak<Real> StoredPeak;
296  typedef reco::PattRecoNode<StoredPeak> StoredNode;
297  typedef reco::PattRecoTree<Real,StoredPeak> StoredTree;
298 
299  if (in.isSparse())
300  throw cms::Exception("FFTJetBadConfig")
301  << "can't restore dense clustering tree"
302  << " from sparsely stored record" << std::endl;
303 
304  assert(out);
305  out->clear();
306 
307  const std::vector<StoredNode>& nodes(in.getNodes());
308  const unsigned n = nodes.size();
309  double hessian[3] = {0., 0., 0.};
310 
311  const std::vector<Real>& scales (in.getScales());
312  unsigned int scnum = 0;
313  std::vector<fftjet::Peak> clusters;
314  const unsigned scsize1 = scales.size();
315  unsigned scsize2 = scaleSetIfNotAdaptive ? scaleSetIfNotAdaptive->size() : 0;
316  if (scsize2 && completeEventScale) ++scsize2;
317  const unsigned scsize = (scsize1==0?scsize2:scsize1);
318 
319  if (scsize == 0)
320  throw cms::Exception("FFTJetBadConfig")
321  << " No scales passed to the function densePeakTreeFromStorable()"
322  << std::endl;
323 
324  // to check whether the largest level equals the size of scale vector
325  const double* sc_not_ad = scsize2 ? &(*scaleSetIfNotAdaptive)[0] : 0;
326 
327  unsigned templevel = n ? nodes[0].originalLevel() : 1;
328  for (unsigned i=0; i<n; ++i)
329  {
330  const StoredNode& snode(nodes[i]);
331  const StoredPeak& p(snode.getCluster());
332  p.hessian(hessian);
333 
334  const unsigned levelNumber = snode.originalLevel();
335 
336  if (templevel != levelNumber)
337  {
338  if (scnum >= scsize)
339  throw cms::Exception("FFTJetBadConfig")
340  << "bad scales, please check the scales"
341  << std::endl;
342  const double scale = ( (scsize1==0) ? sc_not_ad[scnum] : scales[scnum] );
343  out->insert(scale, clusters, 0L);
344  clusters.clear();
345  templevel = levelNumber;
346  ++scnum;
347  }
348 
349  fftjet::Peak apeak(p.eta(), p.phi(), p.magnitude(),
350  hessian, p.driftSpeed(),
351  p.magSpeed(), p.lifetime(),
352  p.scale(), p.nearestNeighborDistance(),
353  1.0, 0.0, 0.0,
354  p.clusterRadius(), p.clusterSeparation());
355  apeak.setSplitTime(p.splitTime());
356  apeak.setMergeTime(p.mergeTime());
357  clusters.push_back(apeak);
358 
359  if (i==(n-1) && levelNumber!=scsize)
360  throw cms::Exception("FFTJetBadConfig")
361  << "bad scales, please check the scales"
362  << std::endl;
363  }
364 
365  const double scale = scsize1 ? scales[scnum] : completeEventScale ?
366  completeEventScale : sc_not_ad[scnum];
367  out->insert(scale, clusters, 0L);
368  }
369 }
370 
371 #endif // RecoJets_FFTJetAlgorithms_clusteringTreeConverters_h
Tree nodes for storing FFTJet preclusters.
Definition: PattRecoNode.h:16
Class for storing FFTJet sparse clustering trees.
Definition: PattRecoTree.h:20
Preclusters from FFTJet pattern recognition stage.
Definition: PattRecoPeak.h:16
void sparsePeakTreeToStorable(const fftjet::SparseClusteringTree< fftjet::Peak, long > &in, bool writeOutScaleInfo, reco::PattRecoTree< Real, reco::PattRecoPeak< Real > > *out)
void densePeakTreeToStorable(const fftjet::AbsClusteringTree< fftjet::Peak, long > &in, bool writeOutScaleInfo, reco::PattRecoTree< Real, reco::PattRecoPeak< Real > > *out)
double Real
void sparsePeakTreeFromStorable(const reco::PattRecoTree< Real, reco::PattRecoPeak< Real > > &in, const std::vector< double > *scaleSetIfNotAdaptive, double completeEventScale, fftjet::SparseClusteringTree< fftjet::Peak, long > *out)
void densePeakTreeFromStorable(const reco::PattRecoTree< Real, reco::PattRecoPeak< Real > > &in, const std::vector< double > *scaleSetIfNotAdaptive, double completeEventScale, fftjet::AbsClusteringTree< fftjet::Peak, long > *out)
Definition: tree.py:1