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

BfldLoanPool.cxx

Go to the documentation of this file.
00001 
00002 // $Id: BfldLoanPool.cxx,v 1.32 2009/09/16 16:55:44 rhatcher Exp $
00003 //
00004 // BfldLoanPool
00005 //
00006 // A singleton class to instantiate BfldMesh (rectangular grids and
00007 // Voronoi diagrams) and BfldMaps.
00008 //
00009 // It does NOT -construct- them in the sense of turning an FEA node
00010 // list into a Voronoi diagram or running ANSYS, but rather simply
00011 // supplies methods for getting a copy of the appropriate structure
00012 // (presumably by reading it from a file or using data from the database).
00013 //
00014 // This version is *NOT* thread safe!!!
00015 //
00016 // Author:  R. Hatcher 2000.06.20
00017 //
00019 #include "BField/BfldLoanPool.h"
00020 
00021 #include <cassert>
00022 #include <iomanip>
00023 
00024 #include "TSystem.h"
00025 #include "TString.h"
00026 
00027 #include "Util/UtilString.h"
00028 
00029 #include "BField/BfldCache.h"
00030 
00031 #include "BField/BfldMeshRect2d.h"
00032 #include "BField/BfldMapRect2d.h"
00033 
00034 #include "BField/BfldMeshVoronoi.h"
00035 #include "BField/BfldMapVoronoi.h"
00036 
00037 #include "UgliGeometry/UgliLoanPool.h"
00038 
00039 #include "MessageService/MsgService.h"
00040 CVSID("$Id: BfldLoanPool.cxx,v 1.32 2009/09/16 16:55:44 rhatcher Exp $");
00041 #include "MessageService/MsgFormat.h"
00042 
00043 
00044 ClassImp(BfldLoanPool)
00045 
00046 //_____________________________________________________________________________
00047 // initialize static member
00048 BfldLoanPool *BfldLoanPool::fgInstance = 0;
00049 
00050 //_____________________________________________________________________________
00051 BfldLoanPool::BfldLoanPool()
00052   // these initializations will immediately get overridden by 
00053   // DefaultConfig() initializing the Registry in Instance()
00054   // followed by the Update().
00055   : fMaxUnrefCaches(1),     fInZTest(3),              fDoLocalTransform(0),
00056     fDoBHCorrection(0),     fDoSlotCorrection(0), 
00057     fDoInterPlaneField(1),  fDoSMGapAndEndField(1),   fUseDCSCoilDir(1),
00058     fUseDCSCurrent(0),      fGapLineSrc(3),           fApplyBdotScale(0),
00059     fZTolerance(0.0),       fNoFieldBeyondZ(9999.), 
00060     fForceUseEverywhere(0), fIgnoreUseEverywhere(1)
00061 {
00062   // Default ctor -- called by self only
00063 
00064    if (fgInstance && fgInstance != this) {
00065      MSG("Bfld",Msg::kWarning)
00066        << "BfldLoanPool ctor() called but global already exists"
00067        << " -- memory leak (existing one will be lost)"
00068        << endl;
00069    }
00070    fgInstance = this;
00071 
00072    MSG("Bfld",Msg::kSynopsis) << "BfldLoanPool ctor" << endl;
00073 
00074    fBfldMeshList.SetOwner(true);
00075    fBfldMapList.SetOwner(true);
00076    fBfldCacheList.SetOwner(true);
00077 }
00078 
00079 //_____________________________________________________________________________
00080 BfldLoanPool::~BfldLoanPool()
00081 {
00082   // dtor
00083   // delete all the owned sub-objects
00084 
00085    MSG("Bfld",Msg::kSynopsis) << "BfldLoanPool shutdown" << endl;
00086 
00087    fgInstance = 0;
00088    fBfldMeshList.Delete();
00089    fBfldMapList.Delete();
00090    fBfldCacheList.Delete();
00091 }
00092 
00093 //_____________________________________________________________________________
00094 BfldLoanPool *BfldLoanPool::Instance()
00095 {
00096   // protect Singleton to ensure there is only one
00097   if (fgInstance == 0) {
00098      MSG("Bfld",Msg::kSynopsis) << "BfldLoanPool instance creation" << endl;
00099 
00100      // before creating the first & only instance make sure that
00101      // there is a UgliLoanPool instance to ensure that the
00102      // singleton dtor's happen in the right order ( first ctor, last dtor )
00103      UgliLoanPool::Instance();
00104 
00105      static BfldLoanPool::Cleaner c; // end-of-run clean up
00106      c.ClassIsUsed();
00107 
00108      fgInstance = new BfldLoanPool;
00109 
00110      // initialize initial (default) configuration
00111      Registry& r = fgInstance->GetConfig();
00112      r.SetName("BfldLoanPool Registry");
00113      r.Merge(fgInstance->DefaultConfig());
00114      r.LockKeys();
00115      fgInstance->SetConfigFromEnvironment();
00116      fgInstance->Update();
00117   }
00118   return fgInstance;
00119 }
00120 //_____________________________________________________________________________
00121 void BfldLoanPool::Config()
00122 {
00123   //  Reconfigure after internal registry update.
00124 
00125   Registry& r = GetConfig();
00126 
00127   int    tmpi;
00128   double tmpd;
00129   const char* tmps;
00130 
00131   if (r.Get("MaxUnrefCaches",     tmpi)) fMaxUnrefCaches     = tmpi;
00132 
00133   if (r.Get("RequireInZTest",     tmpi)) fInZTest            = tmpi;
00134   if (r.Get("DoLocalTransform",   tmpi)) fDoLocalTransform   = tmpi;
00135 
00136   if (r.Get("DoBHCorrection",     tmpi)) fDoBHCorrection     = tmpi;
00137   if (r.Get("DoSlotCorrection",   tmpi)) fDoSlotCorrection   = tmpi;
00138   if (r.Get("DoInterPlaneField",  tmpi)) fDoInterPlaneField  = tmpi;
00139   if (r.Get("DoSMGapAndEndField", tmpi)) fDoSMGapAndEndField = tmpi;
00140   if (r.Get("UseDCSCoilDir",      tmpi)) fUseDCSCoilDir      = tmpi;
00141   if (r.Get("UseDCSCurrent",      tmpi)) fUseDCSCurrent      = tmpi;
00142   if (r.Get("GapLineSrc",         tmpi)) fGapLineSrc         = tmpi;
00143   if (r.Get("ApplyBdotScale",     tmpi)) fApplyBdotScale     = tmpi;
00144 
00145   if (r.Get("ZTolerance",         tmpd)) fZTolerance         = tmpd;
00146 
00147   if (r.Get("NoFieldBeyondZ",     tmpd)) fNoFieldBeyondZ     = tmpd;
00148 
00149   if (r.Get("ForceUseEverywhere", tmpi)) fForceUseEverywhere = tmpi;
00150   if (r.Get("IgnoreUseEverywhere",tmpi)) fIgnoreUseEverywhere= tmpi;
00151 
00152   if (r.Get("AllBellsAndWhistles",tmpi) && tmpi != 0 ) {
00153     // maximum enhancements! damn the torpedos
00154     MSG("Bfld",Msg::kInfo)
00155       << "BfldLoanPool configured for AllBellsAndWhistles! (toot)! (toot)!"
00156       << endl;
00157     fInZTest             =   3; // this is needed for InterPlaneField
00158     fDoLocalTransform    =   2;
00159     fDoInterPlaneField   =   1;
00160     fDoBHCorrection      =  -1;
00161     fDoSlotCorrection    =   1;
00162     fApplyBdotScale      =   1; 
00163   }
00164 
00165   if (r.Get("SwimmerChoice",tmps) && tmps != 0 ) {
00166     TString swimname(tmps);
00167     swimname.Remove(TString::kBoth,' ').ToLower();
00168     bool handled = false;
00169 
00170     if ("old" == swimname) {
00171       // old swimmer behaviour
00172       MSG("Bfld",Msg::kInfo)
00173         << "BfldLoanPool configured for old Swimmer"
00174         << endl;
00175       fForceUseEverywhere  =   0;
00176       fIgnoreUseEverywhere =   0;
00177       fInZTest             =   1;  // steel within tolerance, complain outside
00178       fDoInterPlaneField   =   0;
00179       fDoSMGapAndEndField  =   0;
00180       fZTolerance          =  0.25*Munits::mm;
00181       handled = true;
00182     }
00183     if ("geo" == swimname) {
00184       // GeoSwimmer behaviour
00185       MSG("Bfld",Msg::kInfo)
00186         << "BfldLoanPool configured for GeoSwimmer"
00187         << endl;
00188       fForceUseEverywhere  =   0;
00189       fIgnoreUseEverywhere =   1;
00190       fInZTest             =   3;  // steel within tolerance, complain outside
00191       fDoInterPlaneField   =   1;
00192       fDoSMGapAndEndField  =   1;
00193       fZTolerance          =  0.0*Munits::mm;
00194       handled = true;
00195     } 
00196 
00197     if ( ! handled && swimname != "" ) {
00198       MSG("Bfld",Msg::kInfo)
00199         << "BfldLoanPool doesn't know how to configure for Swimmer: "
00200         << "\"" << swimname << "\""
00201         << endl;
00202     }
00203   } // non-zero SwimmerChoice
00204 
00205 }
00206 
00207 //_____________________________________________________________________________
00208 const Registry& BfldLoanPool::DefaultConfig() const
00209 {
00210   //======================================================================
00211   // The default configuration for this framework component
00212   //======================================================================
00213   //int itrue  = 1; // Work around for Registry's lack of bool
00214   //int ifalse = 0; // Work around for Registry's lack of bool
00215   static Registry r;
00216   
00217   std::string name = this->GetName();
00218   name += ".config.default";
00219   r.SetName(name.c_str());
00220   
00221   r.UnLockValues();
00222 
00223   // Limit # of spare caches (depends on geometry)
00224   r.Set("MaxUnrefCaches",         1);
00225     
00226   // Require (even if UseEverywhere) that we only compute BField 
00227   // inside z boundary of steel
00228   //  0 = no test
00229   //  1 = complain if problems
00230   //  2 = complain and return B=0 if outside any steel z range
00231   //  3 = use gap map or line current when outside steel
00232   r.Set("RequireInZTest",         3);
00233 
00234   // do coordinate transformation local <--> global for steel
00235   // 0 = none:  assume x0-y0 global = x0-y0 map, no rotation
00236   // 1 = transform position before lookup
00237   // 2 = transform resulting field back (account for rotation)
00238   r.Set("DoLocalTransform",       0);
00239 
00240   // configurable additions to the basic map interpolation
00241   r.Set("DoBHCorrection",     0);  // -1 = use BHFactor/BHCutoff method
00242   r.Set("DoSlotCorrection",   0);
00243 
00244   // 0 = no field outside steel
00245   // 1 = use detail map if in that region
00246   //     use full map if it exists, or line current if not
00247   // 2 = like 1, except always use line current outside detail
00248   // 3 = use detail map if in that region, otherwise zero
00249   r.Set("DoInterPlaneField",  1);
00250 
00251   r.Set("DoSMGapAndEndField", 1);
00252 
00253   r.Set("UseDCSCoilDir",      1);  // generally 1 or 0
00254   r.Set("UseDCSCurrent",      0);  // don't use CoilTools::CoilCurrent()
00255   r.Set("GapLineSrc",         3);  // 3= central + return line src
00256 
00257   r.Set("ApplyBdotScale",     0);  // for now have this off ...
00258                                    // until numbers have been validated
00259 
00260   // turn on all the above flags in one go or based on swimmer
00261   r.Set("AllBellsAndWhistles",    0);
00262   r.Set("SwimmerChoice",         "");  // "old", "geo"
00263 
00264   // Limit on the out-of-steel tolerance in z position
00265   r.Set("ZTolerance",      0.0);   // was 0.25*Munits::mm
00266 
00267   // Force B=0 for positions beyond this z.
00268   // Useful for UseEverywhere with 2nd SuperModule not energizied.
00269   r.Set("NoFieldBeyondZ",      9999.0);
00270 
00271   // Force a particular map?
00272   // Even overrides any value passed to BField ctor, but in turn 
00273   // overridden by IgnoreUseEverywhere.
00274   r.Set("ForceUseEverywhere",     0);
00275   // Ignore the UseEverywhere flag in favor of the geometry?
00276   // Use BfldDbiPlaneMap for determining which map to use for each plane
00277   r.Set("IgnoreUseEverywhere",    1);
00278 
00279   r.LockValues();
00280 
00281   return r;
00282 
00283 }
00284 
00285 //_____________________________________________________________________________
00286 void BfldLoanPool::SetConfigFromEnvironment()
00287 {
00288   // Setup configuration from ENV_BFLD environment variable
00289   // which consists of a semi-colon separated list of 
00290   // configuration requests
00291 
00292   const char* strENV_BFLD = gSystem->Getenv("ENV_BFLD");
00293   if ( strENV_BFLD == 0 || strlen(strENV_BFLD) == 0 ) return;
00294   
00295   MSG("Plex",Msg::kInfo) 
00296     << "Configuring BField from the environment variable ENV_BFLD:" << endl
00297     << "   " << strENV_BFLD << endl;
00298 
00299   std::vector<std::string> configRequests;
00300   UtilString::StringTok(configRequests, strENV_BFLD, ";");
00301 
00302   for (unsigned entry = 0; entry < configRequests.size(); ++entry)
00303     this->Set(configRequests[entry].c_str());
00304 
00305 }
00306 
00307 //_____________________________________________________________________________
00308 BfldMap* BfldLoanPool::GetMap(BfldGrid::Grid_t grid, Int_t variant)
00309 {
00310    // Get the requested magnetic field map
00311    //
00312    // Assumes that "BfldMap" structure supports a query about
00313    // what type of grid it is (returns BfldGrid::Grid_t) and
00314    // what variant it is.
00315 
00316    BfldMap *bmap;
00317 
00318    // Look in the list for a match
00319    TIter iter(&fBfldMapList);
00320    while ( ( bmap = (BfldMap *)iter.Next() ) ) {
00321      // Check if it is compatible
00322      if ( bmap->GetGrid()    == grid && 
00323           bmap->GetVariant() == variant ) return bmap;
00324    }
00325 
00326    // Nothing in the list matches
00327 
00328    // actual code for retrieving a copy of the appropriate BFieldMap
00329    // appropriate for this grid and variant (which might specify
00330    // plane chemistry or an end-plane variation)
00331 
00332    MSG("Bfld",Msg::kInfo) 
00333      << "BfldLoanPool::GetMap new map, type " 
00334      << (int)grid << " '" << BfldGrid::AsString(grid)
00335      << "', variant " << variant << endl;
00336 
00337    if (BfldGrid::kRect2dGrid == grid) {
00338       bmap = new BfldMapRect2d(grid,variant);
00339    } else {
00340       bmap = new BfldMapVoronoi(grid,variant);
00341    }
00342    // add it to the list
00343    fBfldMapList.Add(bmap);
00344 
00345    return bmap;
00346 }
00347 
00348 //_____________________________________________________________________________
00349 BfldMesh* BfldLoanPool::GetMesh(BfldGrid::Grid_t grid, Int_t variant)
00350 {
00351    // Get the requested Mesh Diagram
00352    //
00353    // Assumes that "Mesh" structure supports a query about
00354    // what type of grid it is (returns BfldGrid::Grid_t)
00355    // Rect2d mesh's are particular for a given map variant
00356 
00357    BfldMesh *mesh;
00358    Bool_t isRect2d = ( BfldGrid::kRect2dGrid == grid );
00359 
00360    // Look in the list for a match
00361    TIter iter(&fBfldMeshList);
00362    while ( ( mesh = (BfldMesh *)iter.Next() ) ) {
00363       // Check if it is compatible
00364      if ( isRect2d ) {
00365        if ( mesh->GetGrid()    == grid && 
00366             mesh->GetVariant() == variant ) return mesh;
00367      }  // voronoi doesn't care about variant like rect2d
00368      else if ( mesh->GetGrid() == grid )    return mesh;
00369    }
00370 
00371    // Nothing in the list matches
00372 
00373    // actual code for retrieving a copy of the appropriate Mesh diagram
00374    // pass back a pointer to the object
00375   
00376    if ( isRect2d ) {
00377       // the associated mesh should have been created when the map was
00378       // perhaps we're calling them out of order
00379       BfldMapRect2d* bmap2d = 
00380         dynamic_cast<BfldMapRect2d*>(GetMap(grid,variant));
00381       if ( ! bmap2d ) {
00382         MSG("Bfld",Msg::kError)
00383           << "BfldLoanPool::GetMap for Rect2d variant " << variant
00384           << " failed, building mesh is going to fail."
00385           << endl;
00386         // caller probably isn't going to expect this
00387         // but the BfldMeshRect2d ctor will definitely SEGV
00388         return 0;  
00389       }
00390       mesh = new BfldMeshRect2d(bmap2d);
00391    } else {
00392       mesh = new BfldMeshVoronoi(grid,variant);
00393    }
00394    // add it to the list
00395    fBfldMeshList.Add(mesh);
00396    
00397    return mesh;
00398 }
00399 
00400 //_____________________________________________________________________________
00401 BfldCache* BfldLoanPool::GetCache(VldContext& vldc)
00402 {
00403    // Get a shared cache 
00404    //
00405    BfldCache *cache;
00406 
00407    // Look in the list for a match
00408    // Count # of unreferenced caches in case we don't find a match
00409    Int_t todelete = -fMaxUnrefCaches;   
00410    TIter iter(&fBfldCacheList);
00411    while ( ( cache = (BfldCache *)iter.Next() ) ) {
00412      // Check if it is compatible
00413      if ( cache->GetVldRange().IsCompatible(vldc) ) return cache;
00414      if ( cache->CountRef() <= 0 ) todelete++;
00415    }
00416 
00417    // Nothing in the list matches
00418 
00419    // Purge extraneous unref'd caches
00420    // Iterate from the front (default) so oldest gets cleaned out first
00421    if (todelete > 0) {
00422      TObjArrayIter iter_rm(&fBfldCacheList);
00423      BfldCache* other_cache = 0;
00424      while ( ( other_cache = (BfldCache *)iter_rm.Next() ) &&
00425              todelete > 0 ) {
00426        if ( other_cache->CountRef() <= 0 ) {
00427          fBfldCacheList.Remove(other_cache);
00428          delete other_cache;
00429          todelete--;
00430        }
00431      }
00432      // remove the spaces we freed up
00433      fBfldCacheList.Compress();
00434    }
00435 
00436    // Create an appropriate entry
00437    MSG("Bfld",Msg::kDebug) 
00438      << "GetCache created a new BfldCache" << endl;
00439    cache = new BfldCache(vldc);
00440    fBfldCacheList.Add(cache);
00441 
00442    return cache;
00443 }
00444 //_____________________________________________________________________________
00445 void BfldLoanPool::Print(Option_t * /* option */) const
00446 {
00447    // output info about what the loan pool has in stock
00448 
00449    MSG("Bfld",Msg::kVerbose) 
00450       << "BfldLoanPool::Print" << endl;
00451 
00452    MSG("Bfld",Msg::kInfo) 
00453      << "BfldLoanPool Configuration (local values):" << endl
00454      << " InZTest: " << fInZTest
00455      << ", ZTolerance: " << (fZTolerance/Munits::mm) << "mm"
00456      << ", NoFieldBeyondZ: " << fNoFieldBeyondZ
00457      << endl
00458      << " UseDCSCoilDir: " << fUseDCSCoilDir
00459      << ", UseDCSCurrent: " << fUseDCSCurrent
00460      << ", GapLineSrc: " << fGapLineSrc
00461      << ", InterPlaneField: " << fDoInterPlaneField
00462      << ", SMGapAndEndField: " << fDoSMGapAndEndField
00463      << ", ApplyBdotScale: " << (fApplyBdotScale?"yes":"no")
00464      << endl
00465      << " BHCorr: " << fDoBHCorrection
00466      << ", SlotCorr: " << fDoSlotCorrection
00467      << ", ForceUseEverywhere: " << fForceUseEverywhere
00468      << ", IgnoreUseEverywhere: " << fIgnoreUseEverywhere
00469      << endl;
00470 
00471    GetConfig().Print();
00472 
00473    static MsgFormat i4("i4");
00474    Bool_t doheader;
00475 
00476 
00477    BfldGrid::Grid_t grid;
00478 
00479    BfldMesh *mesh;
00480 
00481    MSG("Bfld",Msg::kInfo) 
00482       << " --- Mesh list : " << fBfldMeshList.GetEntries() 
00483       << " entries ---" << endl;
00484 
00485    doheader = kTRUE;
00486    TIter itermesh(&fBfldMeshList);
00487    while ( ( mesh = (BfldMesh *)itermesh.Next() ) ) {
00488       if (doheader) {
00489          doheader = kFALSE;
00490          MSG("Bfld",Msg::kInfo) 
00491            << "   RefCnt  Grid " << endl;
00492       }
00493       grid = mesh->GetGrid();
00494       MSG("Bfld",Msg::kInfo) 
00495         << "     " << i4(mesh->CountRef())
00496         << "  " << BfldGrid::AsString(grid) << endl;
00497    }
00498 
00499    MSG("Bfld",Msg::kInfo) 
00500       << " --- Map list : " << fBfldMapList.GetEntries() 
00501       << " entries ---" << endl;
00502 
00503    BfldMap *bmap;
00504 
00505    doheader = kTRUE;
00506    TIter iterbmap(&fBfldMapList);
00507    while ( ( bmap = (BfldMap *)iterbmap.Next() ) ) {
00508       if (doheader) {
00509          doheader = kFALSE;
00510          MSG("Bfld",Msg::kInfo) 
00511            << "   RefCnt  Variant  Grid " << endl;
00512       }
00513       grid = bmap->GetGrid();
00514       MSG("Bfld",Msg::kInfo) 
00515         << "     " << i4(bmap->CountRef())
00516         << "     " << i4(bmap->GetVariant())
00517         << "  " << BfldGrid::AsString(grid) << endl;
00518    }
00519 
00520    BfldCache *cache;
00521    int icache=0;
00522 
00523    MSG("Bfld",Msg::kInfo) 
00524       << " --- Cache list : " << fBfldCacheList.GetEntries() 
00525       << " entries ---" << endl;
00526 
00527    doheader = kTRUE;
00528    TIter itercache(&fBfldCacheList);
00529    while ( ( cache = (BfldCache *)itercache.Next() ) ) {
00530       if (doheader) {
00531          doheader = kFALSE;
00532       }
00533       MSG("Bfld",Msg::kInfo) << " [" << setw(2) << icache << "] ";
00534       cache->Print();
00535       icache++;
00536    }
00537 
00538    MSG("Bfld",Msg::kInfo) 
00539      << " --- End of BfldLoanPool ---" 
00540      << endl;
00541 }
00542 
00543 //_____________________________________________________________________________
00544 void BfldLoanPool::ClearPool(Bool_t cache, Bool_t map, Bool_t mesh)
00545 {
00546   if (cache) fBfldCacheList.Delete();
00547   if (map)   fBfldMapList.Delete();
00548   if (mesh)  fBfldMeshList.Delete();
00549 }
00550 
00551 //_____________________________________________________________________________

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