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

UgliLoanPool.cxx

Go to the documentation of this file.
00001 
00002 // $Id: UgliLoanPool.cxx,v 1.50 2009/05/18 14:59:06 kasahara Exp $
00003 //
00004 // UgliLoanPool
00005 //
00006 // UgliLoanPool is Singleton for managing the "active" Ugliii
00007 //
00008 // Author:  R. Hatcher 2000.05.15
00009 //
00011 
00012 #include "UgliGeometry/UgliLoanPool.h"
00013 
00014 #include <vector>
00015 
00016 #include "TSystem.h"
00017 #include "TROOT.h"
00018 #include "TClass.h"
00019 #include "TFile.h"
00020 
00021 class UgliGeometryReroot;
00022 
00023 #include "UgliGeometry/UgliGeometry.h"
00024 #include "UgliGeometry/UgliGeomHandle.h"
00025 #include "UgliGeometry/UgliDbiTables.h"
00026 #include "Util/UtilString.h"
00027 #include "Validity/VldContext.h"
00028 #include "Validity/VldRange.h"
00029 #include "Util/UtilString.h"
00030 #include "LeakChecker/LeaMemMonitor.h"
00031 
00032 #include "MessageService/MsgService.h"
00033 CVSID("$Id: UgliLoanPool.cxx,v 1.50 2009/05/18 14:59:06 kasahara Exp $");
00034 
00035 #include <cassert>
00036 
00037 ClassImp(UgliLoanPool)
00038 
00039 //_____________________________________________________________________________
00040 // Initialize static members
00041 
00042 UgliLoanPool *UgliLoanPool::fgInstance = 0;
00043 
00044 const Int_t dfltMaxUnused = 1;
00045 
00046 //____________________________________________________________________________
00047 
00048 void UgliLoanPool::SetAlwaysUseDbi(Bool_t flag)
00049 {
00050   UgliLoanPool::Instance()->Set(Form("AlwaysUseDbi=%d",(int)flag));
00051 }
00052 
00053 //____________________________________________________________________________
00054 
00055 Bool_t UgliLoanPool::GetAlwaysUseDbi()
00056 {
00057   const Registry& r = UgliLoanPool::Instance()->GetConfig();
00058   int tmpi = 1;
00059   r.Get("AlwaysUseDbi",tmpi);
00060   return tmpi;
00061 }
00062 
00063 //____________________________________________________________________________
00064 
00065 void UgliLoanPool::SetUseGeo(Bool_t flag)
00066 {
00067   // Can be used to reconfigure UgliLoanPool for geometry model choice
00068   UgliLoanPool::Instance()->Set(Form("UseGeo=%d",(int)flag));
00069   fUseGeo = flag;
00070 }
00071 
00072 //____________________________________________________________________________
00073 
00074 void UgliLoanPool::SetUseNewCavern(Bool_t flag)
00075 {
00076   // Can be used to reconfigure UgliLoanPool for use of new cavern layout
00077   // Default: false
00078   UgliLoanPool::Instance()->Set(Form("UseNewCavern=%d",(int)flag));
00079 
00080 }
00081 
00082 //____________________________________________________________________________
00083 
00084 void UgliLoanPool::SetShieldOff(Bool_t flag)
00085 {
00086   // Can be used to reconfigure UgliLoanPool to turn shield off
00087   UgliLoanPool::Instance()->Set(Form("ShieldOff=%d",(int)flag));
00088 
00089 }
00090 
00091 //____________________________________________________________________________
00092 
00093 void UgliLoanPool::SetSwimMethodLowField(Geo::ESwimMethod swimmethod)
00094 {
00095   // Used to reconfigure UgliLoanPool swim method in low field regions 
00096   UgliLoanPool::Instance()->Set(Form("SwimMethodLowField=%d",(int)swimmethod));
00097 }
00098 
00099 //____________________________________________________________________________
00100 
00101 bool UgliLoanPool::GetUseNewCavern() const 
00102 {
00103   // Used to retrieve UseNewCavern flag
00104   const Registry& r = UgliLoanPool::Instance()->GetConfig();
00105   int usenewcavern = 0;
00106   if ( r.Get("UseNewCavern",usenewcavern) ) return usenewcavern;
00107   return false;
00108 }
00109 
00110 //____________________________________________________________________________
00111 
00112 bool UgliLoanPool::GetShieldOff() const 
00113 {
00114   // Used to retrieve ShieldOff flag
00115   const Registry& r = UgliLoanPool::Instance()->GetConfig();
00116   int shieldoff = 0;
00117   if ( r.Get("ShieldOff",shieldoff) ) return shieldoff;
00118   return false;
00119 }
00120 
00121 //____________________________________________________________________________
00122 
00123 Geo::ESwimMethod UgliLoanPool::GetSwimMethodLowField() const
00124 {
00125   // Used to retrieve swim method configuration in low field region
00126   const Registry& r = UgliLoanPool::Instance()->GetConfig();
00127   int swimmethod = -1;
00128   if ( r.Get("SwimMethodLowField",swimmethod) ) 
00129     return (Geo::ESwimMethod)swimmethod;
00130   else return Geo::kUnknownSwimMethod;
00131 
00132 }
00133 
00134 //____________________________________________________________________________
00135 
00136 void UgliLoanPool::SetSwimMethodHighField(Geo::ESwimMethod swimmethod)
00137 {
00138   // Used to reconfigure UgliLoanPool swim method in high field regions 
00139   UgliLoanPool::Instance()
00140                      ->Set(Form("SwimMethodHighField=%d",(int)swimmethod));
00141 }
00142 
00143 //____________________________________________________________________________
00144 
00145 Geo::ESwimMethod UgliLoanPool::GetSwimMethodHighField() const
00146 {
00147   // Used to retrieve swim method configuration in high field region
00148   const Registry& r = UgliLoanPool::Instance()->GetConfig();
00149   int swimmethod = -1;
00150   if ( r.Get("SwimMethodHighField",swimmethod) )
00151     return (Geo::ESwimMethod)swimmethod;
00152   else return Geo::kUnknownSwimMethod;
00153 
00154 }
00155 
00156 //____________________________________________________________________________
00157 
00158 void UgliLoanPool::SetMedium(Geo::EDetComponent detcomp, const char* medName)
00159 {
00160   // Used to configure medium in specified detector component
00161   Registry& r = UgliLoanPool::Instance()->GetConfig();
00162   Registry mediumMap;
00163   if ( !r.Get("MediumMap",mediumMap) ) {
00164     MSG("Ugli",Msg::kError) << "SetMedium " << medName << " for det component "
00165                             << Geo::AsString(detcomp) << " failed due to "
00166                             << "missing MediumMap Registry." << endl;
00167     return;
00168   }
00169   mediumMap.UnLockKeys();
00170   mediumMap.UnLockValues();
00171   mediumMap.Set(Geo::AsString(detcomp),medName);
00172   mediumMap.LockValues();
00173   mediumMap.LockKeys();
00174 
00175   r.UnLockValues();
00176   r.Set("MediumMap",mediumMap);
00177   r.LockValues();
00178   
00179 }
00180 
00181 //____________________________________________________________________________
00182 const char* UgliLoanPool::GetMedium(Geo::EDetComponent detcomp) const
00183 {
00184   // Used to retrieve medium for specified detector component if configured
00185   // by user.  Returns empty string if not found.
00186   const Registry& r = UgliLoanPool::Instance()->GetConfig();
00187   Registry mediumMap;
00188   if ( !r.Get("MediumMap",mediumMap) ) {
00189     MSG("Ugli",Msg::kError) << "GetMedium for det component "
00190                             << Geo::AsString(detcomp) << " failed due to "
00191                             << "missing MediumMap registry." << endl;
00192     return "";
00193   }
00194   const char* tmps;
00195   if ( mediumMap.Get(Geo::AsString(detcomp),tmps) ) 
00196                              return std::string(tmps).c_str();
00197 
00198   return ""; // null if no entry in map
00199 
00200 }
00201 
00202 //____________________________________________________________________________
00203 void UgliLoanPool::SetProcess(UtilMCFlag::EProcess process, Int_t value,
00204                               const char* medName) {
00205   // Used to configure physics process flag value for a specific medium
00206 
00207   Registry& r = UgliLoanPool::Instance()->GetConfig();
00208   Registry medConfig;
00209   bool isNew = false;
00210   // fill it with existing registry if present
00211   if ( !r.Get(medName,medConfig) ) isNew = true; 
00212 
00213   medConfig.UnLockKeys();
00214   medConfig.UnLockValues();
00215   medConfig.Set(UtilMCFlag::AsString(process),value);
00216   medConfig.LockValues();
00217   medConfig.LockKeys();
00218 
00219   if ( isNew ) r.UnLockKeys();
00220   r.UnLockValues();
00221   r.Set(medName,medConfig);
00222   r.LockValues();
00223   if ( isNew ) r.LockKeys();
00224   
00225 }
00226 
00227 //____________________________________________________________________________
00228 void UgliLoanPool::SetCut(UtilMCFlag::ECut cut, Double_t value,
00229                           const char* medName) {
00230   // Used to configure cut flag value for a specific medium
00231 
00232   Registry& r = UgliLoanPool::Instance()->GetConfig();
00233   Registry medConfig;
00234   bool isNew = false;
00235   // fill it with existing registry if present
00236   if ( !r.Get(medName,medConfig) ) isNew = true; 
00237 
00238   medConfig.UnLockKeys();
00239   medConfig.UnLockValues();
00240   medConfig.Set(UtilMCFlag::AsString(cut),value);
00241   medConfig.LockValues();
00242   medConfig.LockKeys();
00243 
00244   if ( isNew ) r.UnLockKeys();
00245   r.UnLockValues();
00246   r.Set(medName,medConfig);
00247   r.LockValues();
00248   if ( isNew ) r.LockKeys();
00249   
00250 }
00251 
00252 //____________________________________________________________________________
00253 void UgliLoanPool::SetTracking(UtilMCFlag::ETracking trk, Double_t value,
00254                                const char* medName) {
00255   // Used to configure tracking flag value for a specific medium
00256 
00257   Registry& r = UgliLoanPool::Instance()->GetConfig();
00258   Registry medConfig;
00259   bool isNew = false;
00260   // fill it with existing registry if present
00261   if ( !r.Get(medName,medConfig) ) isNew = true; 
00262 
00263   medConfig.UnLockKeys();
00264   medConfig.UnLockValues();
00265   medConfig.Set(UtilMCFlag::AsString(trk),value);
00266   medConfig.LockValues();
00267   medConfig.LockKeys();
00268 
00269   if ( isNew ) r.UnLockKeys();
00270   r.UnLockValues();
00271   r.Set(medName,medConfig);
00272   r.LockValues();
00273   if ( isNew ) r.LockKeys();
00274   
00275 }
00276 
00277 //____________________________________________________________________________
00278 Registry UgliLoanPool::GetMediumRegistry(const char* medName) const {
00279   // Used to retrieve configuration registry for a given medium.  If
00280   // it doesn't exist, an empty registry is returned.
00281 
00282   const Registry& r = UgliLoanPool::Instance()->GetConfig();
00283   Registry medConfig;  // empty by default
00284   r.Get(medName,medConfig); // fills registry if key exists 
00285   return medConfig; 
00286 
00287 }
00288 
00289 //_____________________________________________________________________________
00290 UgliLoanPool *UgliLoanPool::Instance()
00291 {
00292 // protect Singleton to ensure there is only one
00293    if (fgInstance == 0) {
00294       MSG("Ugli",Msg::kSynopsis) << "UgliLoanPool instance creation" << endl;
00295 
00296       static UgliLoanPool::Cleaner c; // end-of-run clean up
00297       c.ClassIsUsed();
00298 
00299       fgInstance = new UgliLoanPool;
00300 
00301       // intialize intial (default) configuration
00302       Registry& r = fgInstance->GetConfig();
00303       r.SetName("UgliLoanPool Configuration");
00304       r.Merge(fgInstance->DefaultConfig());
00305       r.LockKeys();
00306       fgInstance->SetConfigFromEnvironment();
00307       fgInstance->Update();
00308       // if Config has 'Cache' try reading that
00309       // do this here rather than in Config() so that it only happens
00310       // on the first creation (i.e. later Config's don't redo this)
00311       if ( r.KeyExists("Cache") ) {
00312         const char* cache_location = "";
00313         if ( r.Get("Cache",cache_location) && strlen(cache_location) )
00314           UgliLoanPool::ReadFromFile(cache_location);
00315       }
00316    }
00317    return fgInstance;
00318 }
00319 
00320 //_____________________________________________________________________________
00321 void UgliLoanPool::Config()
00322 {
00323   //  Reconfigure after internal registry update.
00324 
00325   MSG("Ugli",Msg::kDebug) << "UgliLoanPool::Config " << endl;
00326 
00327   Registry& r = GetConfig();
00328   // r.Print();
00329 
00330   int tmpi;
00331   if (r.Get("MaxUnref",tmpi)) fMaxUnref = tmpi;
00332   if (r.Get("UseGeo",tmpi)) fUseGeo = tmpi;
00333   
00334   const char* dets[] = { "Near","Far","CalDet"};
00335   char itemnameAlg[1024];
00336   char itemnameCut[1024];
00337 
00338   for (unsigned int i=0; i<sizeof(dets)/sizeof(char*); ++i) {
00339 
00340     sprintf(itemnameAlg,"Algorithmic%s",dets[i]);
00341     MSG("Ugli",Msg::kDebug)
00342       << "lookup in Config's registry for " << itemnameAlg << endl;
00343     if (r.Get(itemnameAlg,tmpi)) {
00344       Detector::Detector_t det = 
00345         Detector::CharToEnum(dets[i][0]);
00346       // actual set flag only if it's different from current value
00347       bool new_setting = tmpi;
00348       bool current_setting = UgliDbiTables::IsAlgorithmic(det);
00349       if (new_setting != current_setting) {
00350         MSG("Ugli",Msg::kInfo)
00351           << "Set Algorithmic geometry for " << Detector::AsString(det)
00352           << " to " << (tmpi?"true":"false") << endl;
00353         UgliDbiTables::SetAlgorithmic(det,tmpi);
00354       }
00355     }
00356 
00357     sprintf(itemnameCut,"CutOnPlnInstall%s",dets[i]);
00358     MSG("Ugli",Msg::kDebug)
00359       << "lookup in Config's registry for " << itemnameCut << endl;
00360     if (r.Get(itemnameCut,tmpi)) {
00361       Detector::Detector_t det = 
00362         Detector::CharToEnum(dets[i][0]);
00363       // actual set flag only if it's different from current value
00364       bool new_setting = tmpi;
00365       bool current_setting = UgliDbiTables::IsCutOnPlnInstall(det);
00366       if (new_setting != current_setting) {
00367         MSG("Ugli",Msg::kDebug)
00368           << "Set CutOnPlnInstall geometry for " << Detector::AsString(det)
00369           << " to " << (tmpi?"true":"false") << endl;
00370         UgliDbiTables::SetCutOnPlnInstall(det,tmpi);
00371       }
00372     }
00373 
00374   }
00375 
00376 }
00377 
00378 //_____________________________________________________________________________
00379 const Registry& UgliLoanPool::DefaultConfig() const
00380 {
00381   //======================================================================
00382   // The default configuration for this framework component
00383   //======================================================================
00384   int itrue  = 1; // Work around for Registry's lack of bool
00385   int ifalse = 0; // Work around for Registry's lack of bool
00386   static Registry r;
00387   
00388   std::string name = this->GetName();
00389   name += ".config.default";
00390   r.SetName(name.c_str());
00391   
00392   r.UnLockValues();
00393   r.Set("AlwaysUseDbi",          1);
00394   r.Set("MaxUnref",              dfltMaxUnused);
00395   r.Set("UseGeo",                itrue);
00396   r.Set("UseNewCavern",          ifalse);
00397   r.Set("ShieldOff",             ifalse);
00398   r.Set("SwimMethodHighField",   Geo::kRungeKutta);
00399   r.Set("SwimMethodLowField",    Geo::kNoFieldSwim);
00400   r.Set("Cache",                 "");        // use no cache by default
00401   r.Set("CacheWrite",            itrue);     // if cache used, write at job end
00402   r.Set("AlgorithmicNear",       ifalse);
00403   r.Set("AlgorithmicFar",        ifalse);
00404   r.Set("AlgorithmicCalDet",     ifalse);
00405   r.Set("CutOnPlnInstallNear",   ifalse);    // worry about keeping up
00406   r.Set("CutOnPlnInstallFar",    itrue);     // construction complete!
00407 //r.Set("CutOnPlnInstallFar",    ifalse);    // table isn't complete! (veto)
00408   r.Set("CutOnPlnInstallCalDet", ifalse);    // no entries
00409   // how to apply cut to MC
00410   //   0=no cut, 1=use MC table, 2=force use of Data table
00411   r.Set("CutAppliesToMC",        0);         // don't apply cut to MC
00412   r.Set("CutAppliesToVetoShield",ifalse);    // don't apply cut to VetoShield
00413   r.Set("CutMsgLevel",           "Synopsis"); // MsgLevel to report cuts at
00414   r.Set("PurgeDbiTableCache",    itrue);     // purge Dbi cache when geom built
00415   r.Set("MediumMap", Registry()); // empty registry 
00416 
00417   r.LockValues();
00418   r.LockKeys();
00419   
00420   return r;
00421 
00422 }
00423 
00424 //_____________________________________________________________________________
00425 void UgliLoanPool::SetConfigFromEnvironment()
00426 {
00427   // Setup configuration from ENV_UGLI environment variable
00428   // which conists of a semi-colon separated list of DBI
00429   // configuration requests.
00430 
00431   const char* strENV_UGLI = gSystem->Getenv("ENV_UGLI");
00432   if ( strENV_UGLI == 0 || strlen(strENV_UGLI) == 0 ) return;
00433 
00434   MSG("Ugli",Msg::kInfo)
00435     << "Configuring UgliGeometry from the environment variable ENV_UGLI:" << endl
00436     << "   " << strENV_UGLI << endl;
00437 
00438   std::vector<std::string> configRequests;
00439   UtilString::StringTok(configRequests, strENV_UGLI, ";");
00440 
00441   for (unsigned entry = 0; entry < configRequests.size(); ++entry)
00442     this->Set(configRequests[entry].c_str());
00443 
00444 }
00445 
00446 //_____________________________________________________________________________
00447 bool UgliLoanPool::DoesValidGeomExist(const VldContext& vldc, 
00448                                       Ugli::EModifyMode mmode,
00449                                       Geo::EAppType apptype)
00450 {
00451    // testing if ctor of UgliGeomHandle will construct a new geometry
00452 
00453    Bool_t use_frozen = true;
00454    switch (mmode) {
00455    case (Ugli::kModifiable): use_frozen = false; break;
00456    case (Ugli::kFrozen):     use_frozen = true;  break;
00457    case (Ugli::kUseGlobal): 
00458       use_frozen = true;
00459       if (Ugli::kModifiable == 
00460           Ugli::GetDefaultModifyMode()) use_frozen = false;
00461       break;
00462    }
00463 
00464    if ( !UseGeo() ) {
00465      UgliGeometry *geom = GetExistingUgliGeometry(vldc,use_frozen);
00466      if ( geom ) return true;
00467    }
00468    else {
00469      GeoGeometry* geom = GetExistingGeoGeometry(vldc,use_frozen,apptype);
00470      if ( geom ) return true;
00471    }
00472    
00473    return false;
00474 }
00475 
00476 //_____________________________________________________________________________
00477 void UgliLoanPool::ClearPool(Bool_t frozen, Bool_t modifiable)
00478 {
00479 
00480    //LeaMemMonitor::PrintMemStat("Before UgliLoanPool::ClearPool");
00481    if ( frozen ) {     
00482      fFrozenUgliGeomList.Delete();
00483      fFrozenGeoGeomList.Delete();
00484    }
00485    if ( modifiable ) {
00486      fModifiableUgliGeomList.Delete();
00487      fModifiableGeoGeomList.Delete();
00488    }
00489    //LeaMemMonitor::PrintMemStat("After UgliLoanPool::ClearPool");
00490 }
00491 
00492 //_____________________________________________________________________________
00493 bool UgliLoanPool::PurgeDbiTableCache() const
00494 {
00495    // Does the config suggest that DbiTable caches should be purged
00496    // after the UgliGeometry has been constructed?
00497 
00498    Registry& r = fgInstance->GetConfig();
00499    int dopurge = true;  // default
00500    r.Get("PurgeDbiTableCache",dopurge);
00501    return dopurge;
00502 
00503 }
00504 
00505 //_____________________________________________________________________________
00506 UgliLoanPool::UgliLoanPool()
00507   : fMaxUnref(dfltMaxUnused),fUseGeo(true)
00508 {
00509    // Default ctor -- called by self only
00510 
00511    if (fgInstance && fgInstance != this) {
00512      MSG("Ugli",Msg::kWarning)
00513        << "UgliLoanPool ctor() called but global already exists"
00514        << " -- memory leak (existing one will be lost)"
00515        << endl;
00516    }
00517    fgInstance = this;
00518 
00519    MSG("Ugli",Msg::kSynopsis) << "UgliLoanPool ctor" << endl;
00520 
00521    fFrozenUgliGeomList.SetOwner(true);
00522    fModifiableUgliGeomList.SetOwner(true);
00523    fFrozenGeoGeomList.SetOwner(true);
00524    fModifiableGeoGeomList.SetOwner(true);
00525    
00526 }
00527 
00528 //_____________________________________________________________________________
00529 UgliLoanPool::UgliLoanPool(const UgliLoanPool &plp)
00530   : TObject(plp), CfgConfigurable(plp)
00531 {
00532    // copy constuctor should never get called
00533    MSG("Ugli",Msg::kFatal) << 
00534                "UgliLoanPool copy constructor called" << endl;
00535    assert(0);
00536 }
00537 
00538 //_____________________________________________________________________________
00539 UgliLoanPool::~UgliLoanPool()
00540 {
00541   // Destroy UgliLoanPool
00542   // Write out to Cache first (if requested)
00543 
00544   MSG("Ugli",Msg::kSynopsis) << "UgliLoanPool shutdown" << endl;
00545 
00546   Registry& r = GetConfig();
00547   if ( r.KeyExists("Cache") ) {
00548     const char* cache_location = "";
00549     if ( r.Get("Cache",cache_location) && strlen(cache_location) ) {
00550       int dowrite = true;
00551       if ( ! r.Get("CacheWrite",dowrite) ) {
00552         MSG("Ugli",Msg::kInfo)
00553           << "UgliLoanPool not configured for 'CacheWrite', assume "
00554           << dowrite << "." << endl;
00555       }
00556       if (dowrite) {
00557         MSG("Ugli",Msg::kInfo) 
00558           << "UgliLoanPool writing file " 
00559           << cache_location << " ..." << flush;
00560         UgliLoanPool::SaveToFile(cache_location);
00561         MSG("Ugli",Msg::kInfo) << " done" << endl;
00562       }
00563     }
00564   }
00565 
00566   // delete all the owned sub-objects
00567   ClearPool(true,true);
00568 
00569 }
00570 
00571 //_____________________________________________________________________________
00572 UgliGeometry* UgliLoanPool::GetUgliGeometry(const VldContext& vldc, 
00573                                             Bool_t frozen)
00574 {
00575    // Find (or create) the right UgliGeometry to give to a handle
00576 
00577    UgliGeometry *geom = GetExistingUgliGeometry(vldc,frozen);
00578    if (geom) return geom;
00579 
00580    // nothing appropriate, choose one of the managed lists
00581    // geometry should be placed in
00582    TObjArray*   geomList = &fFrozenUgliGeomList;
00583    if (!frozen) geomList = &fModifiableUgliGeomList;
00584 
00585    // first count the # of (other) unreferenced geoms
00586    UgliGeometry *other_geom = 0;
00587    Int_t todelete = -fMaxUnref;
00588    TObjArrayIter iter_cnt(geomList);
00589    while ( ( other_geom = (UgliGeometry *)iter_cnt.Next() ) ) {
00590       if ( other_geom->CountRef() <= 0 ) todelete++;
00591    }
00592    // if more unreferenced geometries than desired clean them out
00593    // iterate from the front (default) so oldest get cleaned out first
00594    if (todelete > 0) {
00595       TObjArrayIter iter_rm(geomList);
00596       while ( ( other_geom = (UgliGeometry *)iter_rm.Next() ) && 
00597               todelete > 0 ) {
00598          if ( other_geom->CountRef() <= 0 ) {
00599             geomList->Remove(other_geom);
00600             delete other_geom;
00601             todelete--;
00602          }
00603       }
00604       // remove the spaces we freed up
00605       geomList->Compress();
00606       MSG("Ugli",Msg::kVerbose) 
00607          << "GetUgliGeometry removed old unref'd geoms" << endl;
00608    }
00609 
00610    // no valid UgliGeometry available need to build one
00611    geom = BuildUgliGeometry(vldc,frozen);
00612    if ( !geom) {
00613       MSG("Ugli",Msg::kFatal)
00614          << "UgliLoanPool failed to build for: " << endl;
00615       vldc.Print();
00616       assert(geom);
00617    }
00618 
00619    // append this new geometry into the list
00620    MSG("Ugli",Msg::kVerbose) 
00621       << "GetUgliGeometry returned created new "
00622       << ((frozen)? "frozen" : "modifiable")
00623       << " UgliGeometry " << endl;
00624    geomList->AddLast(geom);
00625 
00626    return geom;
00627 
00628 }
00629 
00630 //_____________________________________________________________________________
00631 GeoGeometry* UgliLoanPool::GetGeoGeometry(const VldContext& vldc, 
00632                                           Bool_t frozen, Geo::EAppType apptype)
00633 {
00634    // Find (or create) the right GeoGeometry to give to a handle
00635    GeoGeometry *geom = GetExistingGeoGeometry(vldc,frozen,apptype);
00636    if (geom) return geom;
00637 
00638    // nothing appropriate, choose one of the managed lists
00639    // geometry should be placed in
00640    TObjArray*   geomList = &fFrozenGeoGeomList;
00641    if (!frozen) geomList = &fModifiableGeoGeomList;
00642 
00643    // first count the # of (other) unreferenced geoms
00644    GeoGeometry *other_geom = 0;
00645    Int_t todelete = -fMaxUnref;
00646    TObjArrayIter iter_cnt(geomList);
00647    while ( ( other_geom = (GeoGeometry *)iter_cnt.Next() ) ) {
00648       if ( other_geom->CountRef() <= 0 ) todelete++;
00649    }
00650    // if more unreferenced geometries than desired clean them out
00651    // iterate from the front (default) so oldest get cleaned out first
00652    if (todelete > 0) {
00653       TObjArrayIter iter_rm(geomList);
00654       while ( ( other_geom = (GeoGeometry *)iter_rm.Next() ) && 
00655               todelete > 0 ) {
00656          if ( other_geom->CountRef() <= 0 ) {
00657             geomList->Remove(other_geom);
00658             delete other_geom;
00659             todelete--;
00660          }
00661       }
00662       // remove the spaces we freed up
00663       geomList->Compress();
00664       MSG("Ugli",Msg::kVerbose) 
00665          << "GetGeoGeometry removed old unref'd geoms" << endl;
00666    }
00667 
00668    // no valid GeoGeometry available need to build one
00669    geom = BuildGeoGeometry(vldc,frozen,apptype);
00670    if ( !geom) {
00671       MSG("Ugli",Msg::kFatal)
00672         << "UgliLoanPool failed to build GeoGeometry for:\n" << vldc
00673         << " apptype " << Geo::AsString(apptype) << "." << endl;
00674       assert(geom);
00675    }
00676 
00677    // append this new geometry into the list
00678    MSG("Ugli",Msg::kVerbose) 
00679       << "GetGeoGeometry returned created new "
00680       << ((frozen)? "frozen" : "modifiable")
00681       << " GeoGeometry for:\n" << vldc << " apptype "  
00682       << Geo::AsString(apptype) << "." << endl;
00683    geomList->AddLast(geom);
00684 
00685    return geom;
00686 
00687 }
00688 
00689 //_____________________________________________________________________________
00690 UgliGeometry* UgliLoanPool::GetExistingUgliGeometry(const VldContext& vldc, 
00691                                             Bool_t frozen)
00692 {
00693    // Find the right UgliGeometry if it exists
00694 
00695    UgliGeometry *geom = 0;
00696 
00697    // geometry should come from or be placed in one of
00698    // the two lists
00699    TObjArray*   geomList = &fFrozenUgliGeomList;
00700    if (!frozen) geomList = &fModifiableUgliGeomList;
00701 
00702    // look in the current shared or writable list
00703    // iterate from the back as that is what was added most recently
00704    // and thus most likely what we want
00705    TObjArrayIter iter(geomList,kIterBackward);
00706    // search the current list
00707    MSG("Ugli",Msg::kVerbose) << "look for match to VldContext " 
00708                              << vldc << endl;
00709    while ( ( geom = dynamic_cast<UgliGeometry *>(iter.Next()) ) ) {
00710       // check if it is compatible
00711       if ( geom->IsCompatible(vldc) ) {
00712          // create another handle to this UgliGeometry
00713          MSG("Ugli",Msg::kVerbose) << 
00714             "GetUgliGeometry returned found handle " << endl;
00715          return geom;
00716       }
00717    }
00718    return 0; // found nothing appropriate
00719 }
00720 
00721 //_____________________________________________________________________________
00722 GeoGeometry* UgliLoanPool::GetExistingGeoGeometry(const VldContext& vldc,
00723                                    Bool_t frozen, Geo::EAppType apptype)
00724 {
00725    // Find the right GeoGeometry if it exists
00726 
00727    GeoGeometry *geom = 0;
00728    
00729    // geometry should come from or be placed in one of
00730    // the two lists
00731    TObjArray*   geomList = &fFrozenGeoGeomList;
00732    if (!frozen) geomList = &fModifiableGeoGeomList;
00733 
00734    // look in the current shared or writable list
00735    // iterate from the back as that is what was added most recently
00736    // and thus most likely what we want
00737    TObjArrayIter iter(geomList,kIterBackward);
00738    // search the current list
00739    MSG("Ugli",Msg::kVerbose) << "look for Geo match to VldContext " 
00740                              << vldc << " and apptype " << apptype << endl;
00741    while ( ( geom = dynamic_cast<GeoGeometry *>(iter.Next()) ) ) {
00742       // check if it is compatible
00743       if ( geom->IsCompatible(vldc,apptype) ) {
00744          // create another handle to this GeoGeometry
00745          MSG("Ugli",Msg::kVerbose) << 
00746             "GetGeoGeometry returned found handle " << endl;
00747          return geom;
00748       }
00749    }
00750    return 0; // found nothing appropriate
00751 }
00752    
00753 //_____________________________________________________________________________
00754 
00755 UgliGeometry* UgliLoanPool::BuildUgliGeometry(const VldContext& vldc,
00756                                               Bool_t frozen)
00757 {
00758    // Fake up a UgliGeometry from where ever
00759 
00760    UgliGeometry *ugliGeometry = 0;
00761 
00762    MSG("Ugli",Msg::kVerbose)
00763      << "BuildUgliGeometry SimFlag=" << SimFlag::AsString(vldc.GetSimFlag())
00764      << " AlwaysUseDbi=" << (GetAlwaysUseDbi()?"true":"false") << endl << endl;
00765 
00766    if (vldc.GetSimFlag() == SimFlag::kReroot && !GetAlwaysUseDbi()) {
00767       // remove circular dependency by using RTTI-like info
00768       // for UgliGeometryReroot default ctor picks up vldc from RerootExodus
00769       //was: ugliGeometry = new UgliGeometryReroot(vldc);
00770 
00771       static bool first = true;
00772       if (first) {
00773          first = false;
00774          gROOT->LoadClass("UgliGeometryReroot","libUgliGeometry.so");
00775       }
00776       void *ptr = gROOT->GetClass("UgliGeometryReroot",kTRUE)->New();
00777       if (!ptr) {
00778          MSG("Ugli",Msg::kFatal)
00779             <<  "BuildUgliGeometry failed to instantiate UgliGeometryReroot "
00780             << vldc << endl;
00781          assert(0);
00782       }
00783 
00784       MSG("Ugli",Msg::kDebug)
00785          << "BuildUgliGeometry vldc "
00786          << vldc << " (REROOT)" << endl;
00787 
00788       // can't dynamic_cast void* pointers
00789       //    ugliGeometry = dynamic_cast<UgliGeometryReroot*>(ptr);
00790       //    ugliGeometry = dynamic_cast<UgliGeometry *>(ptr);
00791       // UgliGeometryReroot isn't know to be a base type for UgliGeometry
00792       //    ugliGeometry = (UgliGeometryReroot *)(ptr);
00793       ugliGeometry = (UgliGeometry *)(ptr);
00794       if (ugliGeometry->GetMINFStatus() == UgliGeometry::kNotThere) {
00795          // perhaps this data is from a written out "streams file"
00796          // rather than an old REROOT file
00797          MSG("Ugli",Msg::kWarning)
00798             << "UgliGeometryReroot constructed " << endl
00799             << "   but there is no gMINFast, revert to using DBI version"
00800             << endl;
00801          delete ugliGeometry;
00802          ugliGeometry = 0;
00803       }
00804    }
00805 
00806    if (!ugliGeometry) {
00807       MSG("Ugli",Msg::kDebug)
00808          << "BuildUgliGeometry vldc "
00809          << vldc << " (std)" << endl;
00810       ugliGeometry = new UgliGeometry(vldc,frozen);
00811    }
00812 
00813    // we do this after-the-fact because we can't pass this into
00814    // the ctor of UgliGeometryReroot in the above scheme
00815    ugliGeometry->SetFrozen(frozen);
00816 
00817    return ugliGeometry;
00818 }
00819 
00820 //_____________________________________________________________________________
00821 
00822 GeoGeometry* UgliLoanPool::BuildGeoGeometry(const VldContext& vldc, 
00823                                             Bool_t frozen,
00824                                             Geo::EAppType apptype)
00825 {
00826    // Build a GeoGeometry for specified vld and application type
00827 
00828    GeoGeometry *geoGeometry = 0;
00829    if ( !frozen ) {
00830      MSG("Ugli",Msg::kFatal) << "Geo modifiable geometries not supported yet." 
00831                              << endl;
00832      abort();
00833    }
00834    
00835    MSG("Ugli",Msg::kVerbose) 
00836      << "BuildGeoGeometry for: " << vldc
00837      << " for apptype " << Geo::AsString(apptype) << "." << endl;
00838 
00839    if (!geoGeometry) {
00840       MSG("Ugli",Msg::kDebug) 
00841          << "BuildGeoGeometry vldc "
00842          << vldc << " app type " << Geo::AsString(apptype) << "." << endl;
00843       geoGeometry = new GeoGeometry(vldc,apptype);
00844    }
00845 
00846    return geoGeometry;
00847 }
00848 
00849 //_____________________________________________________________________________
00850 void UgliLoanPool::Print(Option_t *option) const
00851 {
00852 // Print info about the current loan pool
00853 
00854    MSG("Ugli",Msg::kVerbose) << "Print" << endl;
00855 
00856    GetConfig().Print();
00857 
00858    if ( !UseGeo() || !fFrozenUgliGeomList.IsEmpty() 
00859                   || !fModifiableUgliGeomList.IsEmpty() ) {
00860      UgliGeometry *geom = 0;
00861      MSG("Ugli",Msg::kInfo) << " --- Frozen UgliLoanPool ---" << endl;
00862      TIter frozen(&fFrozenUgliGeomList);
00863      while ( ( geom = (UgliGeometry *)frozen.Next() ) ) geom->Print(option);
00864    
00865      MSG("Ugli",Msg::kInfo) << " --- Modifiable UgliLoanPool ---" << endl;
00866      TIter modifiable(&fModifiableUgliGeomList);
00867      while ( ( geom = (UgliGeometry *)modifiable.Next() ) )geom->Print(option);
00868    }
00869    
00870    if ( UseGeo() || !fFrozenGeoGeomList.IsEmpty()
00871                  || !fModifiableGeoGeomList.IsEmpty() ) {
00872      GeoGeometry* geom = 0;
00873   
00874      MSG("Ugli",Msg::kInfo) << " --- Geo Frozen UgliLoanPool ---" << endl;
00875      TIter frozen(&fFrozenGeoGeomList);
00876      while ( ( geom = (GeoGeometry *)frozen.Next() ) ) geom->Print(option);
00877 
00878      MSG("Ugli",Msg::kInfo) << " --- Geo Modifiable UgliLoanPool ---" << endl;
00879      TIter modifiable(&fModifiableGeoGeomList);
00880      while ( ( geom = (GeoGeometry *)modifiable.Next() ) ) geom->Print(option);
00881    }
00882    
00883    MSG("Ugli",Msg::kInfo) << " --- End of UgliLoanPool ---" << endl;
00884 }
00885 
00886 //_____________________________________________________________________________
00887 void UgliLoanPool::SaveToFile(const char* filename, bool recreate)
00888 {
00889   // save a UgliLoanPool to a file
00890 
00891   UgliLoanPool* plp = UgliLoanPool::Instance(); // make sure there is one
00892 
00893   const char* fmode = "RECREATE";
00894   if (!recreate) fmode = "UPDATE";
00895   TFile f(filename,fmode);
00896   plp->Write();
00897   f.Write();
00898   f.Close();
00899 }
00900 
00901 //_____________________________________________________________________________
00902 void UgliLoanPool::ReadFromFile(const char* filename)
00903 {
00904   // read a UgliLoanPool from a file
00905   // ensure that there isn't a memory leak if a UgliLoanPool already exists
00906   // by merging the two
00907 
00908   if ( gSystem->AccessPathName(filename,kFileExists) ) {
00909     // note funky return value:  FALSE is you _can_ access file
00910     MSG("Ugli",Msg::kInfo)
00911       << "UgliLoanPool::ReadFromFile() no such file: " << filename << endl;
00912     return;
00913   }
00914 
00915   // bitch in general because it really isn't a good idea!
00916   MSG("Ugli",Msg::kInfo)
00917     << "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << endl 
00918     << "UgliLoanPool::ReadFromFile() used to build some geometries. " << endl
00919     << "This is really not a safe thing to do in that it bypasses the" << endl
00920     << "database and thus is not subject to rolling updates.  Any geometry" << endl
00921     << "will thus reflect the status at the time the file was written" << endl
00922     << "and may be outdated.  Use at your own risk." << endl
00923     << "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" << endl;
00924 
00925   UgliLoanPool* ulpPrev = fgInstance;  // save any existing global
00926   fgInstance = 0;  // so we don't complain about a memory leak
00927 
00928   TFile f(filename);
00929   UgliLoanPool* ulp = dynamic_cast<UgliLoanPool*>(f.Get("UgliLoanPool"));
00930 
00931   if (!ulp) {
00932     // file didn't have any UgliLoanPool!
00933     MSG("Ugli",Msg::kWarning)
00934       << "UgliLoanPool::ReadFromFile() found no pool in file:"
00935       << filename
00936       << endl;
00937     // revert to old
00938     fgInstance = ulpPrev;
00939   }
00940   else if (ulpPrev) {
00941     // file had a UgliLoanPool, but we already had one as well
00942     // merge the two
00943     MSG("Ugli",Msg::kInfo)
00944       << "UgliLoanPool::ReadFromFile() will now merge newly read data "
00945       << "into prior loan pool" << endl;
00946     // make old loan pool the global one to preserve order
00947     fgInstance = ulpPrev;
00948     // loop over elements of newly read pool and move them to global copy
00949     TObjArray *from, *to;
00950     for (int pubpriv = 0; pubpriv <= 1; ++pubpriv) {
00951       if (pubpriv) {
00952         from = &ulp->fFrozenUgliGeomList;
00953         to   = &fgInstance->fFrozenUgliGeomList;
00954       }
00955       else {
00956         from = &ulp->fModifiableUgliGeomList;
00957         to   = &fgInstance->fModifiableUgliGeomList;
00958       }
00959       for (int indx = 0; indx <= from->GetLast(); ++indx) {
00960         UgliGeometry* ugligeom = 
00961           dynamic_cast<UgliGeometry*>(from->RemoveAt(indx));
00962         if (ugligeom) {
00963           // make sure merged geometry has fPlaneTable filled
00964           ugligeom->RestorePlaneTable(false);
00965           to->Add(ugligeom);
00966         }
00967       } // loop over elements
00968     } // shared/private 
00969 
00970     // Repeat for Geo arrays
00971     for (int pubpriv = 0; pubpriv <= 1; ++pubpriv) {
00972       if (pubpriv) {
00973         from = &ulp->fFrozenGeoGeomList;
00974         to   = &fgInstance->fFrozenGeoGeomList;
00975       }
00976       else {
00977         from = &ulp->fModifiableGeoGeomList;
00978         to   = &fgInstance->fModifiableGeoGeomList;
00979       }
00980       for (int indx = 0; indx <= from->GetLast(); ++indx) {
00981         GeoGeometry* geogeom= dynamic_cast<GeoGeometry*>(from->RemoveAt(indx));
00982         if (geogeom) to->Add(geogeom);
00983       } // loop over elements
00984     } // shared/private 
00985     // delete newly read, but now empty, pool
00986     // inhibit writing it out though
00987     ulp->GetConfig().RemoveKey("Cache");
00988     delete ulp;
00989   }
00990 
00991 
00992 }
00993 
00994 //_____________________________________________________________________________

Generated on Sat Nov 21 22:48:02 2009 for loon by  doxygen 1.3.9.1