00001 #ifndef DCGRAPH_H
00002 #define DCGRAPH_H
00003 #include <iterator>
00004 #include <vector>
00005 #include <map>
00006 #include <set>
00007 #include "TCanvas.h"
00008 #include "TObject.h"
00009 #include "TH1F.h"
00010 #include "NueAna/NueAnaTools/DCEdge.h"
00011
00012 using std::vector;
00013 using std::cout;
00014 using std::endl;
00015 using std::multiset;
00016
00017 template<class T> class DCVertex;
00018
00019 template<class T> class DCGraph : public TObject
00020 {
00021 public:
00022 DCGraph(){first=0;nverts=0;nedges=0;
00023 summetric=0.;sumxmetric=0.;sumymetric=0.;maxmetric=0.;}
00024
00025 virtual ~DCGraph() { if(first!=0) {delete first; first=0;}}
00026
00027 DCVertex<T> *Find(T *);
00028 bool AddVertex(T*);
00029 bool AddEdge(T* ,T*);
00030 int GetNVerts() const {return nverts;}
00031 int GetNEdges() const {return nedges;}
00032 float GetSummedMetric() const {return summetric;}
00033 float GetXSummedMetric() const {return sumxmetric;}
00034 float GetYSummedMetric() const {return sumymetric;}
00035 float GetMaxMetric() const {return maxmetric;}
00036 float GetSummedZ() const;
00037 DCVertex<T> *GetFirst() {return first;}
00038
00039 vector<float> GetAllWeights();
00040 vector<float> GetAllZ();
00041 void NewFirst(DCVertex<T> *nf) { first=nf; }
00042 virtual void Print(Option_t *t="") const;
00043 virtual void Draw(Option_t *t="");
00044
00045 vector<DCGraph<T>* > FindAllMinSpan(float maxmetric=0., float minz=0.,
00046 float maxlowzmetric=0.);
00047 DCGraph<T>* FindMinSpan(float maxmetric=0.,float minz=0.,
00048 float maxlowzmetric=0.);
00049
00050
00051
00052 bool AddClosestNode(vector<T> &out, float maxmetric=0., float minz=0.,
00053 float maxlowzmetric=0.);
00054
00055 vector<T> Complement(DCGraph<T>*);
00056
00057 DCGraph<T> *GraphMaxHits(int nhits);
00058
00059 private:
00060 DCVertex<T> *first;
00061
00062
00063
00064 int nverts;
00065 int nedges;
00066 float summetric;
00067 float sumxmetric;
00068 float sumymetric;
00069 float maxmetric;
00070
00071 ClassDef(DCGraph<T>,1)
00072 };
00073 ClassImpT(DCGraph,T)
00074
00075
00076
00077 template<class T> DCVertex<T> *DCGraph<T>::Find(T* theData) {
00078 DCVertex<T> *vPtr = first;
00079
00080 while (vPtr != 0) {
00081
00082 if (*vPtr->GetData() == *theData)
00083 return vPtr;
00084
00085 vPtr = vPtr->GetNextVertex();
00086 }
00087
00088
00089 return 0;
00090 }
00091
00092
00093
00094
00095 template<class T> bool DCGraph<T>::AddVertex(T* theData) {
00096
00097
00098
00099 if (Find(theData) != 0 )
00100 return false;
00101
00102
00103
00104 DCVertex<T> *newVertex = new DCVertex<T>(theData, first);
00105
00106 first = newVertex;
00107 nverts++;
00108 return true;
00109 }
00110
00111
00112
00113
00114 template<class T> bool DCGraph<T>::AddEdge(T* Begin, T* End) {
00115
00116
00117 DCVertex<T> *vEnd = Find(End);
00118
00119
00120 if (vEnd == 0) return false;
00121
00122
00123 DCVertex<T> *vBegin = Find(Begin);
00124
00125
00126 if (vBegin == 0) return false;
00127
00128
00129 summetric+=vBegin->ConnectTo(vEnd);
00130 if(vBegin->GetFirstEdge()->GetMetric()>maxmetric){
00131 maxmetric=vBegin->GetFirstEdge()->GetMetric();
00132 }
00133 sumxmetric+=vBegin->GetFirstEdge()->GetXMetric();
00134 sumymetric+=vBegin->GetFirstEdge()->GetYMetric();
00135
00136 nedges++;
00137 return true;
00138 }
00139
00140
00141 template<class T> void DCGraph<T>::Print(Option_t *) const {
00142 cout<<"Tree has "<<nverts<<" Vertices and "<<nedges<<" Edges"<<endl;
00143 cout<<"Summed metric is "<<summetric
00144 <<" and SummedZ is "<<GetSummedZ()<<endl;
00145 cout<<"SummedXmetric is "<<sumxmetric
00146 <<" and SummedYmetric is "<<sumymetric<<endl;
00147
00148 if (first == 0)
00149 cout << "Graph has no vertexes " << endl;
00150 else
00151 first->PrintGraph();
00152 }
00153
00154 template<class T> void DCGraph<T>::Draw(Option_t *)
00155 {
00156
00157 TCanvas *pad = (TCanvas *)(gPad);
00158 if(pad==0){
00159
00160 pad = new TCanvas();
00161 }
00162
00163 pad->Clear();
00164
00165 float x0=0.;
00166 float y0=0.;
00167 float z0=0.;
00168 first->GetData()->GetData(x0,y0,z0);
00169 DCVertex<T> *v=first;
00170 while(v!=0){
00171 float x=0;
00172 float y=0;
00173 float z=0;
00174 v->GetData()->GetData(x,y,z);
00175 if(x<x0){
00176 x0=x;
00177 y0=y;
00178 }
00179 v=v->GetNextVertex();
00180 }
00181
00182
00183
00184 pad->DrawFrame(x0-140,y0-164,x0+700,y0+164);
00185 if (first == 0)
00186 cout << "Graph has no vertexes " << endl;
00187 else{
00188 first->DrawGraph();
00189 }
00190 }
00191
00192 template<class T> DCGraph<T>* DCGraph<T>::FindMinSpan(float maxmetric,
00193 float minz,
00194 float maxlowzmetric)
00195 {
00196
00197 DCGraph<T> *msg = new DCGraph<T>();
00198
00199 DCVertex<T> *v=first;
00200 msg->AddVertex(v->GetData());
00201 vector<T> out = msg->Complement(this);
00202 while(msg->AddClosestNode(out, maxmetric, minz, maxlowzmetric));
00203 return msg;
00204 }
00205
00206 template<class T> bool DCGraph<T>::AddClosestNode(vector<T> &out,
00207 float maxmetric,
00208 float minz,
00209 float maxlowzmetric)
00210 {
00211
00212 float minmetric=-1.;
00213
00214
00215 T *closestin=0;
00216 T *closestout=0;
00217 int closestoutindex=0;
00218 DCVertex<T> *vin=first;
00219 while(vin!=0){
00220
00221 for(unsigned int c=0;c<out.size();c++){
00222 T *vout = &out[c];
00223 if(Find(vout)!=0){
00224 continue;
00225 }
00226 float m = ((*vin->GetData())-(*vout)).abs();
00227 float x,y,z;
00228 vout->GetData(x,y,z);
00229 if(minmetric<0){
00230 if(z<minz&&m>maxlowzmetric&&maxlowzmetric!=0){
00231 }
00232 else if(m>maxmetric&&maxmetric!=0){
00233 }
00234 else{
00235 minmetric = m;
00236 closestout = vout;
00237 closestin = vin->GetData();
00238 closestoutindex=c;
00239 }
00240 }
00241 if(m<minmetric){
00242 if(z<minz&&m>maxlowzmetric&&maxlowzmetric!=0){
00243 }
00244 else if(m>maxmetric&&maxmetric!=0){
00245 }
00246 else{
00247 minmetric = m;
00248 closestout = vout;
00249 closestin = vin->GetData();
00250 closestoutindex=c;
00251 }
00252 }
00253 }
00254 if(vin->GetNextVertex()){
00255 vin=vin->GetNextVertex();
00256 }
00257 else{
00258 vin=0;
00259 }
00260 }
00261
00262 if(closestin==0||closestout==0){
00263
00264 return false;
00265 }
00266
00267 else{
00268
00269
00270
00271 AddVertex(closestout);
00272 AddEdge(closestin,closestout);
00273
00274 out.erase(out.begin()+closestoutindex);
00275 return true;
00276 }
00277
00278 return false;
00279 }
00280
00281 template<class T> float DCGraph<T>::GetSummedZ() const
00282 {
00283
00284 float sumz=0;
00285 if(this==0){
00286 return sumz;
00287 }
00288 DCVertex<T> *vert = first;
00289 while(vert){
00290 float x=0;
00291 float y=0;
00292 float z=0;
00293 vert->GetData()->GetData(x,y,z);
00294 sumz+=z;
00295 vert=vert->GetNextVertex();
00296 }
00297 return sumz;
00298 }
00299
00300 template<class T> vector<T> DCGraph<T>::Complement(DCGraph<T> *g)
00301 {
00302
00303 vector<T> vout;
00304 DCVertex<T> *v = g->GetFirst();
00305 while(v!=0){
00306 if(Find(v->GetData())==0){
00307 vout.push_back(*(v->GetData()));
00308 }
00309 v=v->GetNextVertex();
00310 }
00311 return vout;
00312 }
00313
00314 template<class T> vector<DCGraph<T> *> DCGraph<T>::FindAllMinSpan(float maxmetric, float minz, float maxlowzmetric)
00315 {
00316
00317 vector<DCGraph<T> *> trees;
00318 DCGraph<T> *msg = FindMinSpan(maxmetric,minz,maxlowzmetric);
00319 trees.push_back(msg);
00320 vector<T> out=msg->Complement(this);
00321 while(out.size()>0){
00322
00323
00324 DCGraph<T> ng;
00325 for(unsigned int i=0;i<out.size();i++){
00326
00327 ng.AddVertex(&out[i]);
00328 }
00329 DCGraph<T> *msg2 = ng.FindMinSpan(maxmetric,minz,maxlowzmetric);
00330
00331
00332
00333
00334 vector<T> newout=out;
00335 out.clear();
00336
00337 for(unsigned int i=0;i<newout.size();i++){
00338 if(msg2->Find(&newout[i])==0){
00339
00340
00341 out.push_back(newout[i]);
00342 }
00343 }
00344
00345 trees.push_back(msg2);
00346
00347
00348 }
00349
00350 return trees;
00351 }
00352
00353 template<class T> DCGraph<T> *DCGraph<T>::GraphMaxHits(int nhits)
00354 {
00355
00356 if(nhits==0){
00357 return 0;
00358 }
00359
00360 DCVertex<T> *max[100]={0};
00361 float mz[100]={0.};
00362 int N=nhits;
00363 if(nverts<N){
00364 N=nverts;
00365 }
00366 if(N>100){
00367 N=100;
00368 }
00369
00370
00371 DCVertex<T> *vin=first;
00372 while(vin!=0){
00373 float x=0.;
00374 float y=0.;
00375 float z=0.;
00376 vin->GetData()->GetData(x,y,z);
00377 for(int i=0;i<N;i++){
00378 if(z>mz[i]){
00379 for(int j=N-1;j>i;j--){
00380 max[j]=max[j-1];
00381 mz[j]=mz[j-1];
00382 }
00383 max[i]=vin;
00384 mz[i]=z;
00385 break;
00386 }
00387 }
00388 vin=vin->GetNextVertex();
00389 }
00390
00391 DCGraph<T> g;
00392 for(int i=0;i<N;i++){
00393 g.AddVertex(max[i]->GetData());
00394
00395
00396 }
00397
00398 return g.FindMinSpan();
00399
00400 }
00401
00402 template<class T> vector<float> DCGraph<T>::GetAllWeights()
00403 {
00404 multiset<float> w;
00405 DCVertex<T> *v = first;
00406 DCEdge<T> *e;
00407 while(v!=0){
00408
00409
00410 e = v->GetFirstEdge();
00411 while(e!=0){
00412 w.insert(e->GetMetric());
00413
00414 e = e->GetNext();
00415
00416
00417
00418
00419
00420
00421 }
00422 v=v->GetNextVertex();
00423 }
00424
00425 multiset<float>::iterator it(w.begin());
00426 vector<float> vw;
00427 while(it!=w.end()){
00428
00429 vw.push_back(*it);
00430 it++;
00431 }
00432
00433 return vw;
00434
00435 }
00436
00437
00438 template<class T> vector<float> DCGraph<T>::GetAllZ()
00439 {
00440 multiset<float> w;
00441 DCVertex<T> *v = first;
00442 while(v!=0){
00443 float x,y,z;
00444 v->GetData()->GetData(x,y,z);
00445 w.insert(z);
00446 v=v->GetNextVertex();
00447 }
00448
00449 multiset<float>::iterator it(w.begin());
00450 vector<float> vw;
00451 while(it!=w.end()){
00452
00453 vw.push_back(*it);
00454 it++;
00455 }
00456
00457 return vw;
00458
00459 }
00460
00461
00462
00463 #endif //DCGRAPH_H
00464