Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

LatValidate.cxx

Go to the documentation of this file.
00001 
00002 // $Id: LatValidate.cxx,v 1.4 2003/03/25 07:20:58 west Exp $
00003 //
00004 // LatValidate
00005 //
00006 // Begin_Html<img src="../../pedestrians.gif" align=center>
00007 // <a href="../source_warning.html">Warning for beginners</a>.<br>
00008 // Also see <a href="../../root_crib/index.html">The ROOT Crib</a> and
00009 // <a href="../index.html">The MINOS Class User Guide</a>End_Html
00010 //
00011 // N. West 03/2000
00012 //
00013 // Purpose: Validation system for Lat.
00014 //
00015 //    RunAllTests  can be used to run the full test suite.
00016 //    RunTest      can be used to run a specific test.
00017 //
00018 //
00019 // Example usage:-
00020 // =============
00021 //
00022 //    LatValidate v;
00023 //    v.RunAllTests();
00024 //
00025 //
00027 
00028 #include <string.h>
00029 
00030 #include "TList.h"
00031 
00032 #include "MessageService/MsgService.h"
00033 #include "Lattice/Lattice.h"
00034 #include "Lattice/LatticeBuilder.h"
00035 #include "Lattice/LatticeLink.h"
00036 #include "Lattice/LatticeMaker.h"
00037 #include "Lattice/test/LatValidate.h"
00038 
00039 
00040 // Some typedefs to eliminate tedious typing.
00041 
00042 typedef   Lattice::ID                ID;
00043 typedef   Lattice::VectorID          VectorID;
00044 typedef   VectorID::const_iterator   IDItr;
00045 typedef   LatticeLink                Link;
00046 
00047 ClassImp(LatValidate)
00048 
00049 //   Internal classes and functions used in Test_3
00050 
00051 typedef    Bool_t  AssociateFunc(const TObject*,const TObject*);
00052 
00053 class Primary: public TObject {
00054 public:
00055     Primary(Int_t id): fId(id) {}
00056    ~Primary() {}
00057   Int_t GetId() const { return fId; }
00058 private:
00059     Int_t fId;
00060 };
00061 
00062 class Secondary: public TObject {
00063 public:
00064     Secondary(Int_t id): fIdPrimary(id) {}
00065    ~Secondary() {}
00066   Int_t GetIdPrimary() const { return fIdPrimary; }
00067 private:
00068     Int_t fIdPrimary;
00069 };
00070 
00071 static Bool_t MatchPrimSec(const TObject* p,const TObject* s) {
00072   const Primary*   pp = dynamic_cast<const Primary*>(p);
00073   const Secondary* ps = dynamic_cast<const Secondary*>(s);
00074   return ( pp && ps ) ? pp->GetId() == ps->GetIdPrimary() : kFALSE;
00075 }
00076 
00077 static Bool_t MatchSecPrim(const TObject* s,const TObject* p) {
00078   const Primary*   pp = dynamic_cast<const Primary*>(p);
00079   const Secondary* ps = dynamic_cast<const Secondary*>(s);
00080   return ( pp && ps ) ? pp->GetId() == ps->GetIdPrimary() : kFALSE;
00081 }
00082 
00083 static Long_t PrimaryKey(const TObject* p) {
00084   const Primary*   pp = dynamic_cast<const Primary*>(p);
00085   return ( pp ) ?  pp->GetId() : 0;
00086 }
00087 
00088 static Long_t SecondaryKey(const TObject* s) {
00089   const Secondary* ps = dynamic_cast<const Secondary*>(s);
00090   return ( ps ) ? ps->GetIdPrimary() : kFALSE;
00091 }
00092 
00093 //   Definition of static data members
00094 //   *********************************
00095 
00096 CVSID("$Id: LatValidate.cxx,v 1.4 2003/03/25 07:20:58 west Exp $");
00097 
00098 // Definition of member functions (alphabetical order)
00099 // ***************************************************
00100 
00101 //.....................................................................
00102 
00103 LatValidate::LatValidate() :
00104   fNumFail(0),
00105   fNumPass(0)
00106 {
00107 
00108 //  Purpose:   Default constructor.
00109 //  Arguments: None.
00110 //  Return:    None.
00111 
00112 //  Contact:   N. West
00113 
00114 //  Specification:-
00115 //  =============
00116 
00117 //  o  Create default object.
00118 
00119 
00120   MSG("Lat",Msg::kVerbose) << "LatValidate ctor 1 at " << this 
00121                              << "\n";
00122 
00123 }
00124 
00125 
00126 //.....................................................................
00127 
00128 LatValidate::~LatValidate() {
00129 
00130 
00131 //  Purpose:   Destructor.
00132 //  Arguments: None.
00133 //  Return:    None.
00134 
00135 //  Contact:   N. West
00136 
00137 //  Specification:-
00138 //  =============
00139 
00140 //  o  Destroy object.
00141 
00142   MSG("Lat",Msg::kVerbose) << "LatValidate dtor at " << this << "\n";
00143 
00144 }
00145 
00146 
00147 //.....................................................................
00148 
00149 Bool_t LatValidate::RunAllTests() {
00150 
00151 
00152 //  Purpose:   Run all tests.
00153 //  Arguments: None.
00154 //  Return:    = kTRUE if all tests are O.K., kFALSE otherwise.
00155 
00156 //  Contact:   N. West
00157 
00158 
00159 //  Specification:-
00160 //  =============
00161 
00162 //  o  Run all tests
00163 
00164 
00165   Bool_t ok = kTRUE;
00166 
00167   for ( Int_t testNum = 1; testNum <= kNUMTESTS; testNum++  ) {
00168     if ( ! RunTest(testNum) ) ok = kFALSE;
00169   }
00170   return ok;
00171 }
00172 
00173 
00174 //.....................................................................
00175 
00176 Bool_t LatValidate::RunTest(Int_t testNum) {
00177 
00178 
00179 //  Purpose:   Run a specific test.
00180 //  Arguments: 
00181 //    testNum      in  Test to be run.
00182 
00183 //  Return:    = kTRUE if all tests are O.K., kFALSE otherwise.  
00184 
00185 //  Contact:   N. West
00186 
00187 //  Specification:-
00188 //  =============
00189 
00190 //  Program Notes
00191 //  =============
00192 
00193 //  Banner printing not yet implemented.
00194 
00195 //  Dispatch to appropriate test.
00196 
00197   switch ( testNum ) {
00198   case 1: return Test_1();
00199   case 2: return Test_2();
00200   case 3: return Test_3();
00201   }
00202   MSG("Lat",Msg::kError) << "Undefined test: " << testNum << "\n";
00203   return kFALSE;
00204 
00205 }
00206 //.....................................................................
00207 
00208 Bool_t LatValidate::Test_1() {
00209 
00210 
00211 //  Purpose:   
00212 //  Arguments: None.
00213 //  Return:    = kTRUE if all tests are O.K., kFALSE otherwise.  
00214 
00215 //  Contact:   N. West
00216 
00217 //  Specification:-
00218 //  =============
00219 
00220 //  o Lattice builder tests.
00221  
00222 
00223   MSG("Lat",Msg::kInfo) 
00224     << "Test 1: Ignore warnings - they are part of the test." << endl;
00225 
00226   Bool_t ok = kTRUE;
00227 
00228   Lattice lat("apples","oranges",LatticeBase::RLinkMulti);
00229   LatticeBuilder builder;
00230 
00231 
00232   Int_t  obj;
00233   ID id  = &obj;
00234 
00235   //  Should not be able to add primary without a lattice
00236   if ( builder.AddPrimary(1,id) ) {
00237     MSG("Lat",Msg::kError) 
00238         << "Bulder accepted primary without lattice present"
00239         << endl;
00240     ok = kFALSE;
00241   }
00242 
00243   builder.DockLattice( &lat, Lattice::kLeft );
00244 
00245   //  Should not be able to add secondary without a primary
00246   if ( builder.AddSecondary(1,id) ) {
00247     MSG("Lat",Msg::kError) 
00248         << "Bulder accepted secondary without primary present"
00249         << endl;
00250     ok = kFALSE;
00251   }
00252 
00253 
00254   //  Should be able to add primary with a lattice
00255   if ( ! builder.AddPrimary(1,id) ) {
00256     MSG("Lat",Msg::kError) 
00257         << "Bulder did not accepted primary with lattice present"
00258         << endl;
00259     ok = kFALSE;
00260   }
00261 
00262   //  Should be able to add secondary with a primary.
00263   if ( ! builder.AddSecondary(1,id) ) {
00264     MSG("Lat",Msg::kError) 
00265         << "Bulder did not accepted secondary with primary present"
00266         << endl;
00267     ok = kFALSE;
00268   }
00269   
00270 
00271   //  Should not be able to add secondary with an invalid primary key
00272   if ( builder.AddSecondary(2,id) ) {
00273     MSG("Lat",Msg::kError) 
00274         << "Bulder accepted secondary with invalid primary key"
00275         << endl;
00276     ok = kFALSE;
00277   }
00278 
00279 
00280   //  The lattice should now have one primary and one secondary.
00281 
00282   VectorID  primIDs;
00283   VectorID  secIDs;
00284   lat.GetAllIDs( Lattice::kLeft,  primIDs);
00285   lat.GetAllIDs( Lattice::kRight, secIDs);
00286 
00287   if ( 1 != primIDs.size() || 1 != secIDs.size() ) {
00288     MSG("Lat",Msg::kError) << "Lattice should have 1 primary and 1 "
00289                            << "secondary. Has primaries: " 
00290                            << primIDs.size()
00291                            << ", secondaries: " << secIDs.size()  
00292                            << endl;
00293     ok = kFALSE;
00294 
00295   }
00296 
00297   
00298   MSG("Lat",Msg::kInfo) 
00299        << "Test 1: LatticeBuilder tests                   ...... ";
00300   MSG("Lat",Msg::kInfo) << ( ok ? "O.K." : "Failed") ;
00301   MSG("Lat",Msg::kInfo) << "\n";
00302 
00303   if ( ok ) fNumPass++; else fNumFail++;
00304 
00305   return ok;
00306   
00307 }
00308 //.....................................................................
00309 
00310 Bool_t LatValidate::Test_2() {
00311 
00312 
00313 //  Purpose:   
00314 //  Arguments: None.
00315 //  Return:    = kTRUE if all tests are O.K., kFALSE otherwise.  
00316 
00317 //  Contact:   N. West
00318 
00319 //  Specification:-
00320 //  =============
00321 
00322 //  o Set up simple 1:n lattice and check 2-way navigation.
00323  
00324 
00325   Bool_t ok = kTRUE;
00326 
00327   Lattice lat("apples","oranges",LatticeBase::RLinkMulti);
00328 
00329   //  0 terminated list of secondaries for each primary.
00330 
00331   UInt_t numSecForPrim[] = {5, 10, 3, 7, 0};
00332 
00333   UInt_t  numPrim = 0;
00334   UInt_t  numSec  = 0;
00335 
00336   for ( Int_t index = 0; numSecForPrim[index]; index++ ) {
00337     numPrim++;
00338     numSec += numSecForPrim[index];
00339   }
00340 
00341   MSG("Lat",Msg::kDebug) << "# primaries: " << numPrim
00342                          << " # secondaries: " << numSec  << endl;
00343 
00344   // The primaries and secondaries are simple Int_ts stored in a buffer
00345 
00346   Int_t* buffer = new Int_t[numPrim+numSec];
00347  
00348 
00349   // Fill the Lattice.
00350 
00351   LatticeBuilder builder;
00352   builder.DockLattice( &lat, Lattice::kLeft );
00353 
00354   Int_t*  objPtr   = buffer;
00355   for ( Int_t index = 0; numSecForPrim[index]; index++ ) {
00356     ID prim = objPtr++;
00357     MSG("Lat",Msg::kDebug) << "Primary " <<  index << " " << prim << endl;
00358     builder.AddPrimary(index, prim);
00359   }
00360 
00361   for ( Int_t index = 0; numSecForPrim[index]; index++ ) {
00362     for ( UInt_t iSec = 0; iSec < numSecForPrim[index]; iSec++ ) {
00363      ID sec  = objPtr++;
00364      MSG("Lat",Msg::kDebug) << "Secondary " << index << " " << sec << endl;
00365      builder.AddSecondary(index, sec);
00366     }
00367   }
00368 
00369   builder.DockLattice( 0, Lattice::kLeft );
00370 
00371   // Examine the lattice.
00372 
00373 
00374   VectorID  primIDs;
00375   VectorID  secIDs;
00376   lat.GetAllIDs( Lattice::kLeft,  primIDs);
00377   lat.GetAllIDs( Lattice::kRight, secIDs);
00378 
00379 
00380 //  Check the total number of primaries and secondaries.
00381 
00382 
00383   if ( numPrim != primIDs.size() || numSec != secIDs.size() ) {
00384     MSG("Lat",Msg::kError) << "# primaries: " << primIDs.size()
00385                            << " != " << numPrim
00386                            << " || # secondaries: " << secIDs.size()  
00387                            << " != " << numSec
00388                            << endl;
00389     ok = kFALSE;
00390 
00391   }
00392 
00393 //  Loop over all primaries checking each has the correct number
00394 //  of secondaries and that each secondary points back to its
00395 //  primary.
00396 
00397   
00398   Int_t iPrim = 0;
00399   for ( IDItr pItr = primIDs.begin(); pItr != primIDs.end(); pItr++ ) {
00400     lat.GetFarIDs( Lattice::kLeft, *pItr, secIDs );
00401 
00402     if ( secIDs.size() != numSecForPrim[iPrim] ) {
00403       MSG("Lat",Msg::kError) 
00404         << "Primary: " << iPrim << " has " << secIDs.size()
00405         << " secondaries but should have " <<  numSecForPrim[iPrim] 
00406         << endl;
00407       ok = kFALSE;
00408     }
00409 
00410     for ( IDItr sItr = secIDs.begin(); sItr != secIDs.end(); sItr++) {
00411       VectorID primIDs2;
00412       lat.GetFarIDs( Lattice::kRight, *sItr, primIDs2 );
00413 
00414       if ( primIDs2.size() != 1 || *(primIDs2.begin()) != *pItr ) {
00415         MSG("Lat",Msg::kError) 
00416           << "Primary: " << iPrim << " has a bad secondary"
00417           << " #primary " <<  primIDs2.size() 
00418           << " pID " << *pItr << " pID2 " << *(primIDs2.begin()) 
00419           << endl;
00420         ok = kFALSE;
00421 
00422       }
00423     }
00424     iPrim++;
00425   }
00426 
00427 
00428   // Finally remove the buffer.
00429 
00430   delete[] buffer;
00431 
00432   MSG("Lat",Msg::kInfo) 
00433        << "Test 2: 2-way test over 1:n lattice            ...... ";
00434   MSG("Lat",Msg::kInfo) << ( ok ? "O.K." : "Failed") ;
00435   MSG("Lat",Msg::kInfo) << "\n";
00436 
00437   if ( ok ) fNumPass++; else fNumFail++;
00438 
00439   return ok;
00440   
00441 }
00442 
00443 //.....................................................................
00444 
00445 Bool_t LatValidate::Test_3() {
00446 
00447 
00448 //  Purpose:   
00449 //  Arguments: None.
00450 //  Return:    = kTRUE if all tests are O.K., kFALSE otherwise.  
00451 
00452 //  Contact:   N. West
00453 
00454 //  Specification:-
00455 //  =============
00456 
00457 //  o Testing of LatticeMaker
00458  
00459 
00460   Bool_t ok = kTRUE;
00461 
00462 
00463 // Create collections of primaries and secondaries.
00464 
00465   TList primaries;
00466   TList secondaries;
00467   UInt_t numSecondaries = 0;
00468 
00469   enum { NUM_PRIMARIES = 5 };
00470   Int_t NumSecForPrimary[NUM_PRIMARIES] = { 7, 9, 0, 4, 1 };
00471 
00472   for ( Int_t iPrim = 0; iPrim < NUM_PRIMARIES; ++iPrim) {
00473     primaries.AddLast(new Primary(iPrim));
00474     numSecondaries += NumSecForPrimary[iPrim];
00475 
00476     for ( Int_t iSec = 0; iSec < NumSecForPrimary[iPrim]; ++iSec ) {
00477       secondaries.AddLast(new Secondary(iPrim));
00478     }
00479   }
00480 
00481 
00482 // Build  lattices in various ways and check them out.
00483 
00484   LatticeMaker maker;
00485   const char* testNames[] = { "n:m with 1 func",
00486                               "1:n with 1 func",
00487                               "n:1 with 1 func",
00488                               "1:n with 2 funcs" };
00489 
00490 
00491   for (UInt_t test =0; test < 4; ++test) {
00492 
00493     Lattice* lat = 0;
00494     switch ( test ) {
00495     case 0:
00496       lat = maker.CreateLattice(&primaries,
00497                                 &secondaries,
00498                                 MatchPrimSec,
00499                                 "n:m");
00500       break;
00501     case 1:
00502       lat = maker.CreateLattice(&primaries,
00503                                 &secondaries,
00504                                 MatchPrimSec,
00505                                 "1:n");
00506       break;
00507     case 2:
00508       lat = maker.CreateLattice(&secondaries,
00509                                 &primaries,
00510                                 MatchSecPrim,
00511                                 "n:1");
00512       break;
00513     case 3:
00514       lat = maker.Create1ToNLattice(&primaries,
00515                                 &secondaries,
00516                                 PrimaryKey,
00517                                 SecondaryKey);
00518       break;
00519 
00520     }
00521   
00522 //  Check the sizes.
00523 
00524     VectorID  primIDs;
00525     VectorID  secIDs;
00526     if ( test != 2 ) {
00527       lat->GetAllIDs( Lattice::kLeft,  primIDs);
00528       lat->GetAllIDs( Lattice::kRight, secIDs);
00529     } else {
00530       lat->GetAllIDs( Lattice::kRight, primIDs);
00531       lat->GetAllIDs( Lattice::kLeft,  secIDs);
00532     }
00533   
00534 // One primary has no secondary so is not in the lattice.
00535     if (    primIDs.size() != NUM_PRIMARIES-1 
00536          || secIDs.size()  != numSecondaries ) {
00537       MSG("Lat",Msg::kError)
00538           << "sub-test " << test << "(" << testNames[test]
00539           << ") No. of primaries " << primIDs.size()  
00540           << " but should be " << NUM_PRIMARIES-1
00541           << ", No. of secondaries " << secIDs.size()
00542           << " but should be " <<  numSecondaries 
00543           << endl;
00544       ok = kFALSE;
00545   
00546     }
00547 
00548     
00549 // Loop over all primaries, checking that each has the right number
00550 // of secondaries.
00551 
00552     IDItr pItr = primIDs.begin();
00553     for ( Int_t iPrim = 0; iPrim < NUM_PRIMARIES; ++iPrim) {
00554       UInt_t numSec = NumSecForPrimary[iPrim];
00555       if ( numSec == 0 ) continue;
00556       if ( test != 2 ) lat->GetFarIDs(Lattice::kLeft,  *pItr, secIDs);
00557       else             lat->GetFarIDs(Lattice::kRight, *pItr, secIDs);
00558       if (  secIDs.size() != numSec )  {
00559         MSG("Lat",Msg::kError)
00560             << "sub-test " << test << "(" << testNames[test]
00561             << ") For primary " << iPrim  
00562             << ", No. of secondaries " << secIDs.size()
00563             << " but should be " <<  numSec 
00564             << endl;
00565         ok = kFALSE;
00566       }
00567       ++pItr;
00568     }
00569 
00570     delete lat;
00571   }
00572 
00573   MSG("Lat",Msg::kInfo) 
00574        << "Test 3: 1:n, n:1 and n:m LatticeMaker test     ...... ";
00575   MSG("Lat",Msg::kInfo) << ( ok ? "O.K." : "Failed") ;
00576   MSG("Lat",Msg::kInfo) << "\n";
00577 
00578   if ( ok ) fNumPass++; else fNumFail++;
00579 
00580   return ok;
00581   
00582 }

Generated on Mon Feb 15 11:06:51 2010 for loon by  doxygen 1.3.9.1