MCAppValidate Class Reference

#include <MCAppValidate.h>

List of all members.

Public Member Functions

 MCAppValidate ()
virtual ~MCAppValidate ()
bool RunAllTests ()

Private Member Functions

bool TestParticle ()
bool TestStack ()

Detailed Description

Definition at line 16 of file MCAppValidate.h.


Constructor & Destructor Documentation

MCAppValidate::MCAppValidate (  ) 

Definition at line 34 of file MCAppValidate.cxx.

00034                              {
00035   // Default constructor
00036 
00037 }

MCAppValidate::~MCAppValidate (  )  [virtual]

Definition at line 40 of file MCAppValidate.cxx.

00040                               {
00041   // Destructor
00042 
00043 }


Member Function Documentation

bool MCAppValidate::RunAllTests ( void   ) 

Definition at line 46 of file MCAppValidate.cxx.

References TestParticle(), and TestStack().

Referenced by main().

00046                                 {
00047   //
00048   //  Purpose:  Run sequence of MCApplication package validity tests.
00049   //
00050   //  Arguments: none.
00051   //
00052   //  Return:    pass (if all tests successful) or fail
00053   //
00054   //  Contact:   S. Kasahara
00055   // 
00056 
00057   cout << "*** MCAppValidate::RunAllTests ***\n" << endl;
00058   
00059   bool allpassed = true;  // assume the best
00060 
00061   allpassed |= TestParticle();
00062   allpassed |= TestStack();
00063 
00064 
00065   cout << "\n*** Finished all tests: ***" << endl;
00066 
00067   return allpassed;
00068 
00069 }

bool MCAppValidate::TestParticle (  )  [private]

Definition at line 72 of file MCAppValidate.cxx.

References MCAppParticle::AddParent(), MCAppParticle::AddSibling(), UtilIstHEP::AsString(), bfld::AsString(), MuELoss::e, MCAppParticle::GetID(), MCAppParticle::GetNChildren(), MCAppParticle::GetNParents(), MCAppParticle::GetNSiblings(), MCAppParticle::GetParent(), MCAppParticle::GetParentID(), MCAppParticle::GetSibling(), MCAppParticle::GetSiblingID(), MCAppParticle::GetTParticle(), UtilIstHEP::kNFinal, Particle::Mass(), and MCAppParticle::Print().

Referenced by RunAllTests().

00072                                  {
00073   //  Test MCAppParticle class
00074 
00075   bool pass = true;
00076   cout << "*** TestParticle ***" << endl;
00077   
00078   // Only so much one can do here. Create a particle and test that
00079   // it's attributes match expected. Print particle.
00080   Int_t particleId = 0;
00081   Int_t pdgcode = 13; // muon
00082   const TDatabasePDG& dbpdg = *(TDatabasePDG::Instance());
00083   Double_t mass = dbpdg.GetParticle(pdgcode) -> Mass();
00084   Double_t charge = dbpdg.GetParticle(pdgcode) -> Charge();
00085   
00086   Int_t statuscode = UtilIstHEP::kNFinal;
00087   TLorentzVector pmom(1.,2.,3.,4.);
00088   TLorentzVector pos(5.,6.,7.,8.);
00089   Double_t pol[3] = {1.,0.,0.};
00090   Double_t weight = 1.;
00091   TMCProcess process = kPPrimary;
00092   
00093   MCAppParticle particle(particleId,pdgcode,statuscode,
00094                          pmom.Px(),pmom.Py(),pmom.Pz(),pmom.E(),
00095                          pos.X(),pos.Y(),pos.Z(),pos.T(),process);
00096   
00097   particle.SetPolarisation(pol[0],pol[1],pol[2]);
00098   particle.SetWeight(weight);
00099 
00100   Int_t childId = particleId + 1;
00101   MCAppParticle childparticle(childId,const_cast<TParticle*>
00102                                 (particle.GetTParticle()),process);
00103   particle.AddChild(&childparticle);
00104   childparticle.AddParent(&particle);
00105   
00106   Int_t siblingId = childId + 1;
00107   MCAppParticle siblingparticle(siblingId,const_cast<TParticle*>
00108                                 (childparticle.GetTParticle()),
00109                                 process);
00110   childparticle.AddSibling(&siblingparticle);  
00111   
00112   particle.Print();
00113   particle.GetTParticle()->Print();
00114   childparticle.Print();
00115   siblingparticle.Print();
00116   
00117   if ( particle.GetID() != particleId ) {
00118     cout << "particle.GetID() " << particle.GetID() << " != particleId " 
00119          << particleId << endl;
00120     pass = false; 
00121   }
00122 
00123   if ( particle.GetNChildren() != 1 ) {
00124     cout << "particle.GetNChildren() " << particle.GetNChildren()
00125          << " != 1" << endl;
00126     pass = false;
00127   }
00128   if ( particle.GetChild(0)->GetID() != 1 ) {
00129     cout << "particle.GetChild(0)->GetID() " 
00130          << particle.GetChild(0)->GetID()
00131          << " != 1 " << endl;
00132     pass = false;
00133   }
00134   if ( particle.GetChildID(0) != 1 ) {
00135     cout << "particle.GetChildID(0) " 
00136          << particle.GetChildID(0)
00137          << " != 1 " << endl;
00138     pass = false;
00139   }
00140   
00141   if ( particle.GetNParents() != 0 ) {
00142     cout << "particle.GetNParents() " << particle.GetNParents()
00143          << " != 0" << endl;
00144     pass = false;
00145   }
00146   
00147   if ( particle.GetNSiblings() != 0 ) {
00148     cout << "particle.GetNSiblings() " << particle.GetNSiblings()
00149          << " != 0" << endl;
00150     pass = false;
00151   }
00152   
00153   if ( childparticle.GetNParents() != 1 ) {
00154     cout << "childparticle.GetNParents() " << childparticle.GetNParents()
00155          << " != 1" << endl;
00156     pass = false;
00157   }
00158   if ( childparticle.GetParent(0)->GetID() != 0 ) {
00159     cout << "childparticle.GetParent(0)->GetID() " 
00160          << childparticle.GetParent(0)->GetID()
00161          << " != 0 " << endl;
00162     pass = false;
00163   }
00164   if ( childparticle.GetParentID(0) != 0 ) {
00165     cout << "childparticle.GetParentID(0) " 
00166          << childparticle.GetParentID(0)
00167          << " != 0 " << endl;
00168     pass = false;
00169   }
00170 
00171   if ( childparticle.GetNChildren() != 0 ) {
00172     cout << "childparticle.GetNChildren() " << childparticle.GetNChildren()
00173          << " != 0" << endl;
00174     pass = false;
00175   }
00176 
00177   if ( childparticle.GetNSiblings() != 1 ) {
00178     cout << "childparticle.GetNSiblings() " << childparticle.GetNSiblings()
00179          << " != 1" << endl;
00180     pass = false;
00181   }
00182   if ( childparticle.GetSibling(0)->GetID() != 2 ) {
00183     cout << "childparticle.GetSibling(0)->GetID() " 
00184          << childparticle.GetSibling(0)->GetID()
00185          << " != 2 " << endl;
00186     pass = false;
00187   }
00188   if ( childparticle.GetSiblingID(0) != 2 ) {
00189     cout << "childparticle.GetSiblingID(0) " 
00190          << childparticle.GetSiblingID(0)
00191          << " != 2 " << endl;
00192     pass = false;
00193   }
00194   
00195 
00196   if ( particle.GetProcess() != process ) {
00197     cout << "particle.GetProcess() " << particle.GetProcess()
00198          << " != process " << endl;
00199     pass = false;
00200   } 
00201   
00202   if ( particle.GetPdgCode() != pdgcode ) {
00203     cout << "particle.GetPdgCode() " << particle.GetPdgCode() 
00204          << " != pdgcode " << pdgcode << endl;
00205     pass = false; 
00206   }
00207 
00208   if ( particle.GetEnergy() != pmom.E() ) {
00209     cout << "particle.GetEnergy() " << particle.GetEnergy() 
00210          << " != pmom.E() " << pmom.E() << endl;
00211     pass = false; 
00212   }
00213 
00214   if ( particle.GetMass() != mass ) {
00215     cout << "particle.GetMass() " << particle.GetMass() << " != mass " 
00216          << mass << endl;
00217     pass = false; 
00218   }
00219 
00220   if ( particle.GetStatusCode() != statuscode ) {
00221     cout << "particle.GetStatusCode() " << particle.GetStatusCode() 
00222          << " != statuscode " << statuscode << endl;
00223     pass = false; 
00224   }
00225 
00226   if ( particle.GetStatusCodeName() != 
00227        std::string(UtilIstHEP::AsString(statuscode))) {
00228     cout << "particle.GetStatusCodeName() " 
00229          << (particle.GetStatusCodeName()).c_str() 
00230          << " != UtilIstHEP::AsString(statuscode) " 
00231          << UtilIstHEP::AsString(statuscode) << endl;
00232     pass = false; 
00233   }
00234 
00235   if ( particle.GetCharge() != charge ) {
00236     cout << "particle.GetCharge() " << particle.GetCharge() << " != charge " 
00237          << charge << endl;
00238     pass = false; 
00239   }
00240 
00241   if ( particle.GetWeight() != weight ) {
00242     cout << "particle.GetWeight() " << particle.GetWeight() 
00243          << " != weight " 
00244          << weight << endl;
00245     pass = false; 
00246   }
00247 
00248   TVector3 polvec;
00249   particle.GetPolarisation(polvec);
00250 
00251   if ( polvec.X() != pol[0] ) {
00252     cout << "polvec.X() " << polvec.X() << " != pol[0] " 
00253          << pol[0] << endl;
00254     pass = false; 
00255   }
00256   if ( polvec.Y() != pol[1] ) {
00257     cout << "polvec.Y() " << polvec.Y() << " != pol[1] " 
00258          << pol[1] << endl;
00259     pass = false; 
00260   }
00261   if ( TMath::Abs(polvec.Z() - pol[2]) >= 1.e-6 ) {
00262     cout << "polvec.Z() " << polvec.Z() << " != pol[2] " 
00263          << pol[2] << endl;
00264     pass = false; 
00265   }
00266   
00267 
00268   TLorentzVector particlepmom;
00269   particle.ProductionMomentum(particlepmom);
00270 
00271   if ( particlepmom.Px() != pmom.Px() ) {
00272     cout << "particlepmom.Px() " << particlepmom.Px() << " != pmom.Px() " 
00273          << pmom.Px() << endl;
00274     pass = false; 
00275   }
00276   if ( particlepmom.Py() != pmom.Py() ) {
00277     cout << "particlepmom.Py() " << particlepmom.Py() << " != pmom.Py() " 
00278          << pmom.Py() << endl;
00279     pass = false; 
00280   }
00281   if ( particlepmom.Pz() != pmom.Pz() ) {
00282     cout << "particlepmom.Pz() " << particlepmom.Pz() << " != pmom.Pz() " 
00283          << pmom.Pz() << endl;
00284     pass = false; 
00285   }
00286   if ( particlepmom.E() != pmom.E() ) {
00287     cout << "particlepmom.E() " << particlepmom.E() << " != pmom.E() " 
00288          << pmom.E() << endl;
00289     pass = false; 
00290   }
00291 
00292   TLorentzVector particlevtx;
00293   particle.ProductionVertex(particlevtx);
00294 
00295   if ( particlevtx.X() != pos.X() ) {
00296     cout << "particlevtx.X() " << particlevtx.X() << " != pos.X() " 
00297          << pos.X() << endl;
00298     pass = false; 
00299   }
00300   if ( particlevtx.Y() != pos.Y() ) {
00301     cout << "particlevtx.Y() " << particlevtx.Y() << " != pos.Y() " 
00302          << pos.Y() << endl;
00303     pass = false; 
00304   }
00305   if ( particlevtx.Z() != pos.Z() ) {
00306     cout << "particlevtx.Z() " << particlevtx.Z() << " != pos.Z() " 
00307          << pos.Pz() << endl;
00308     pass = false; 
00309   }
00310   if ( particlevtx.T() != pos.T() ) {
00311     cout << "particlevtx.T() " << particlevtx.T() << " != pos.T() " 
00312          << pos.T() << endl;
00313     pass = false; 
00314   }
00315 
00316   if ( pass ) cout << "*** All TestParticle tests Passed ***" << endl;
00317   else cout << "*** At least one TestParticle test FAILED ***" << endl;
00318 
00319   return pass;
00320 
00321 }

bool MCAppValidate::TestStack (  )  [private]

Definition at line 324 of file MCAppValidate.cxx.

References MCAppStack< T >::GetCurrentParentTrackNumber(), MCAppStack< T >::GetCurrentTrack(), MCAppStack< T >::GetCurrentTrackNumber(), MCAppParticle::GetID(), MCAppStack< T >::GetNprimary(), MCAppStack< T >::GetNtrack(), MCAppStack< T >::GetParticle(), UtilIstHEP::kNFinal, UtilIstHEP::kNInitial, UtilIstHEP::kNIntermediate, MCAppStack< T >::PopNextTrack(), MCAppStack< T >::PopPrimaryForTracking(), Lit::Print(), MCAppStack< T >::Print(), MCAppStack< T >::PushTrack(), MCAppStack< T >::Reset(), and MCAppStack< T >::SetCurrentTrack().

Referenced by RunAllTests().

00324                               {
00325   //  Test MCAppStack methods
00326 
00327   bool pass = true;
00328   cout << "*** TestStack ***" << endl;
00329 
00330   MCAppStack<MCAppParticle> mcappstack;
00331 
00332   const Int_t nevent = 1000000;
00333   for ( int ievt = 0; ievt < nevent; ievt++ ) {
00334     // Create a set of particles and push to stack.
00335     // Do this nevent times, each time resetting stack, to look for
00336     // memory leaks and test performance.
00337 
00338     TLorentzVector pmom(1.,2.,3.,4.);
00339     TLorentzVector pos(5.,6.,7.,8.);
00340     Double_t pol[3] = {1.,0.,0.};
00341     Double_t weight = 1.;
00342   
00343     Int_t nprimary = 0;
00344     Int_t ntr = -1;
00345     const Int_t ntrack = 7;
00346     Int_t pdg[ntrack] = {0};
00347     Int_t parentId[ntrack] = {0};
00348     
00349  
00350     // track 0, primary initial state, not to be done
00351     pdg[ntr+1] = 12; // nu_e
00352     Int_t toBeDone = 0;
00353     parentId[ntr+1] = -1;
00354     Int_t statuscode = UtilIstHEP::kNInitial;
00355     mcappstack.PushTrack(toBeDone,parentId[ntr+1],pdg[ntr+1],
00356                          pmom.Px(),pmom.Py(),pmom.Pz(),
00357                          pmom.E(),pos.X(),pos.Y(),pos.Z(),pos.T(),
00358                          pol[0],pol[1],pol[2],kPPrimary,
00359                          ntr,weight,statuscode);
00360 
00361     // track 1, primary final state, to be done
00362     pdg[ntr+1] = 2112; // neutron
00363     toBeDone = 1;
00364     parentId[ntr+1] = -1;
00365     nprimary++;
00366     statuscode = UtilIstHEP::kNFinal;
00367     mcappstack.PushTrack(toBeDone,parentId[ntr+1],pdg[ntr+1],
00368                          pmom.Px(),pmom.Py(),pmom.Pz(),
00369                          pmom.E(),pos.X(),pos.Y(),pos.Z(),pos.T(),
00370                          pol[0],pol[1],pol[2],kPPrimary,
00371                          ntr,weight,statuscode);
00372 
00373     // track 2, intermediate daughter state of track 0, not to be done
00374     pdg[ntr+1] = 14; // nu_mu
00375     toBeDone = 0;
00376     parentId[ntr+1] = 0;
00377     statuscode = UtilIstHEP::kNIntermediate;
00378     mcappstack.PushTrack(toBeDone,parentId[ntr+1],pdg[ntr+1],
00379                          pmom.Px(),pmom.Py(),pmom.Pz(),
00380                          pmom.E(),pos.X(),pos.Y(),pos.Z(),pos.T(),
00381                          pol[0],pol[1],pol[2],kPPrimary,
00382                          ntr,weight,statuscode);
00383 
00384     // track 3, final daughter state of track 2, to be done
00385     pdg[ntr+1] = 13; // muon
00386     toBeDone = 1;
00387     parentId[ntr+1] = 2;
00388     nprimary++;
00389     statuscode = UtilIstHEP::kNFinal;
00390     mcappstack.PushTrack(toBeDone,parentId[ntr+1],pdg[ntr+1],
00391                          pmom.Px(),pmom.Py(),pmom.Pz(),
00392                          pmom.E(),pos.X(),pos.Y(),pos.Z(),pos.T(),
00393                          pol[0],pol[1],pol[2],kPPrimary,
00394                          ntr,weight,statuscode);
00395 
00396     // track 4, rootino, not to be done
00397     pdg[ntr+1] = 0; // rootino
00398     toBeDone = 0;
00399     parentId[ntr+1] = 0;
00400     statuscode = 999;
00401     mcappstack.PushTrack(toBeDone,parentId[ntr+1],pdg[ntr+1],
00402                          pmom.Px(),pmom.Py(),pmom.Pz(),
00403                          pmom.E(),pos.X(),pos.Y(),pos.Z(),pos.T(),
00404                          pol[0],pol[1],pol[2],kPPrimary,
00405                          ntr,weight,statuscode);
00406 
00407     // track 5, secondary of track 3, to be done
00408     pdg[ntr+1] = 22; // gamma
00409     toBeDone = 1;
00410     parentId[ntr+1] = 3;
00411     statuscode = 0;
00412     mcappstack.PushTrack(toBeDone,parentId[ntr+1],pdg[ntr+1],pmom.Px(),
00413                          pmom.Py(),pmom.Pz(),
00414                          pmom.E(),pos.X(),pos.Y(),pos.Z(),pos.T(),
00415                          pol[0],pol[1],pol[2],kPBrem,
00416                          ntr,weight,statuscode);
00417 
00418     // track 6, secondary of track 1, to be done
00419     pdg[ntr+1] = 111; // pi0
00420     toBeDone = 1;
00421     parentId[ntr+1] = 1;
00422     statuscode = 0;
00423     mcappstack.PushTrack(toBeDone,parentId[ntr+1],pdg[ntr+1],
00424                          pmom.Px(),pmom.Py(),pmom.Pz(),
00425                          pmom.E(),pos.X(),pos.Y(),pos.Z(),pos.T(),
00426                          pol[0],pol[1],pol[2],kPHadronic,
00427                          ntr,weight,statuscode);
00428 
00429     if ( ievt < 2 ) mcappstack.Print();
00430 
00431     if ( mcappstack.GetNtrack() != ntr+1 ) {
00432       cout << "mcappstack.GetNtrack() " << mcappstack.GetNtrack() 
00433            << " != ntr+1 " << ntr+1 << endl;
00434       pass = false; 
00435     }
00436 
00437     if ( mcappstack.GetNprimary() != nprimary ) {
00438       cout << "mcappstack.GetNprimary() " << mcappstack.GetNprimary() 
00439            << " != nprimary " << nprimary << endl;
00440       pass = false; 
00441     }
00442 
00443     if ( mcappstack.GetCurrentTrack() != 0 ) {
00444       cout << "mcappstack.GetCurrentTrack() != 0 " << endl;
00445       pass = false;
00446     }
00447 
00448     Int_t track = -1;
00449     TParticle* particle = 0;
00450     const Int_t nstack = 4;
00451     Int_t stackorder[nstack] = {6,5,3,1};
00452     Int_t pdgorder[nstack] = {0};
00453     Int_t parentorder[nstack] = {0};
00454     for ( int ist = 0; ist < nstack; ist++ ) {
00455       pdgorder[ist] = pdg[stackorder[ist]];
00456       parentorder[ist] = parentId[stackorder[ist]];
00457     }
00458       
00459     Int_t istack = 0;
00460     while ( (particle = mcappstack.PopNextTrack(track)) ) {
00461       if ( istack < nstack ) {
00462         if ( track != stackorder[istack] ) {
00463           cout << "mcappstack.PopNextTrack popped " << istack << "th track "
00464                << "with id " << track 
00465                << " expected id " << stackorder[istack] << endl;
00466           pass = false;
00467         }
00468         if ( mcappstack.GetCurrentTrackNumber() != stackorder[istack] ) {
00469           cout << "mcappstack.GetCurrentTrackNumber() " 
00470                << mcappstack.GetCurrentTrackNumber() 
00471                << " not equal to " << stackorder[istack] << endl;
00472           pass = false;
00473         }
00474         if (mcappstack.GetCurrentParentTrackNumber() != parentorder[istack] ) {
00475           cout << "mcappstack.GetCurrentParentTrackNumber() " 
00476                << mcappstack.GetCurrentParentTrackNumber() 
00477                << " not equal to " << parentorder[istack] << endl;
00478           pass = false;
00479         }
00480         if ((mcappstack.GetCurrentTrack())->GetPdgCode() != pdgorder[istack]) {
00481           cout << "(mcappstack.GetCurrentTrack())->GetPdgCode() " 
00482                << (mcappstack.GetCurrentTrack())->GetPdgCode()  
00483                << " not equal to " << pdgorder[istack] << endl;
00484           pass = false;
00485         }
00486       }
00487       else {
00488         cout << "mcappstack.PopNextTrack popped " << istack << "th track "
00489              << " expected only " << nstack << " tracks " << endl;
00490         pass = false;
00491       }
00492       istack++;
00493     }
00494 
00495     const Int_t nprim = 2;
00496     Int_t primaryorder[nprim] = {1,3};
00497     Int_t primarypdgorder[nprim] = {0};
00498     Int_t primaryparentorder[nprim] = {0};
00499     
00500     for ( Int_t iprim = 0; iprim < nprim; iprim++ ) {
00501       primarypdgorder[iprim] = pdg[primaryorder[iprim]];
00502       primaryparentorder[iprim] = parentId[primaryorder[iprim]];
00503     }
00504        
00505     for ( Int_t iprim = 0; iprim < mcappstack.GetNprimary(); iprim++ ) {
00506       TParticle* primary = mcappstack.PopPrimaryForTracking(iprim);
00507       if ( primary->GetPdgCode() != primarypdgorder[iprim] ) {
00508         cout << "mcappstack.PopPrimaryForTracking(iprim)->GetPdgCode() "
00509              << primary->GetPdgCode() << " not equal to " 
00510              << primarypdgorder[iprim] << endl;
00511         pass = false;
00512       }
00513       if ( mcappstack.GetCurrentTrackNumber() != primaryorder[iprim] ) {
00514         cout << "mcappstack.GetCurrentTrackNumber() " 
00515              << mcappstack.GetCurrentTrackNumber() 
00516              << " for primary " << iprim
00517              << " not equal to " << primaryorder[iprim] << endl;
00518         pass = false;
00519       }
00520       if ( mcappstack.GetCurrentParentTrackNumber() 
00521            != primaryparentorder[iprim] ) {
00522         cout << "mcappstack.GetCurrentParentTrackNumber() " 
00523              << mcappstack.GetCurrentParentTrackNumber() 
00524              << " for primary " << iprim
00525              << " not equal to " << primaryparentorder[iprim] << endl;
00526         pass = false;
00527       }
00528       if ( (mcappstack.GetCurrentTrack())->GetPdgCode() 
00529             != primarypdgorder[iprim] ) {
00530         cout << "(mcappstack.GetCurrentTrack())->GetPdgCode() " 
00531              << (mcappstack.GetCurrentTrack())->GetPdgCode()  
00532              << " for primary " << iprim
00533              << " not equal to " << primarypdgorder[iprim] << endl;
00534         pass = false;
00535       }
00536     }
00537 
00538     mcappstack.SetCurrentTrack(5);
00539     if ( mcappstack.GetCurrentTrackNumber() != 5 ) {
00540       cout << "mcappstack.GetCurrentTrackNumber() "
00541            << mcappstack.GetCurrentTrackNumber() 
00542            << " not equal to 5 after SetCurrentTrack " << endl;
00543       pass = false;
00544     }
00545 
00546     const Int_t nparticle = 7;
00547     Int_t particleorder[nparticle] = {0,1,2,3,4,5,6};
00548 
00549     for ( int ip = 0; ip < nparticle; ip++ ) {
00550       const MCAppParticle* particle = mcappstack.GetParticle(ip);
00551       if ( particle->GetID() != particleorder[ip] ) {
00552         cout << "mcappstack.GetParticle(ip)->GetID() with ip " << ip 
00553              << " not equal to " << particleorder[ip] << endl;
00554         pass = false;
00555       }
00556       if ( ievt < 2 ) particle -> Print();
00557     }
00558 
00559     mcappstack.Reset();
00560     
00561   }
00562   
00563   if ( pass ) cout << "*** All TestStack tests Passed ***" << endl;
00564   else cout << "*** At least one TestStack test FAILED ***" << endl;
00565 
00566   return pass;
00567   
00568 }


The documentation for this class was generated from the following files:

Generated on 2 Nov 2017 for loon by  doxygen 1.6.1