00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
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
00048 BfldLoanPool *BfldLoanPool::fgInstance = 0;
00049
00050
00051 BfldLoanPool::BfldLoanPool()
00052
00053
00054
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
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
00083
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
00097 if (fgInstance == 0) {
00098 MSG("Bfld",Msg::kSynopsis) << "BfldLoanPool instance creation" << endl;
00099
00100
00101
00102
00103 UgliLoanPool::Instance();
00104
00105 static BfldLoanPool::Cleaner c;
00106 c.ClassIsUsed();
00107
00108 fgInstance = new BfldLoanPool;
00109
00110
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
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
00154 MSG("Bfld",Msg::kInfo)
00155 << "BfldLoanPool configured for AllBellsAndWhistles! (toot)! (toot)!"
00156 << endl;
00157 fInZTest = 3;
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
00172 MSG("Bfld",Msg::kInfo)
00173 << "BfldLoanPool configured for old Swimmer"
00174 << endl;
00175 fForceUseEverywhere = 0;
00176 fIgnoreUseEverywhere = 0;
00177 fInZTest = 1;
00178 fDoInterPlaneField = 0;
00179 fDoSMGapAndEndField = 0;
00180 fZTolerance = 0.25*Munits::mm;
00181 handled = true;
00182 }
00183 if ("geo" == swimname) {
00184
00185 MSG("Bfld",Msg::kInfo)
00186 << "BfldLoanPool configured for GeoSwimmer"
00187 << endl;
00188 fForceUseEverywhere = 0;
00189 fIgnoreUseEverywhere = 1;
00190 fInZTest = 3;
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 }
00204
00205 }
00206
00207
00208 const Registry& BfldLoanPool::DefaultConfig() const
00209 {
00210
00211
00212
00213
00214
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
00224 r.Set("MaxUnrefCaches", 1);
00225
00226
00227
00228
00229
00230
00231
00232 r.Set("RequireInZTest", 3);
00233
00234
00235
00236
00237
00238 r.Set("DoLocalTransform", 0);
00239
00240
00241 r.Set("DoBHCorrection", 0);
00242 r.Set("DoSlotCorrection", 0);
00243
00244
00245
00246
00247
00248
00249 r.Set("DoInterPlaneField", 1);
00250
00251 r.Set("DoSMGapAndEndField", 1);
00252
00253 r.Set("UseDCSCoilDir", 1);
00254 r.Set("UseDCSCurrent", 0);
00255 r.Set("GapLineSrc", 3);
00256
00257 r.Set("ApplyBdotScale", 0);
00258
00259
00260
00261 r.Set("AllBellsAndWhistles", 0);
00262 r.Set("SwimmerChoice", "");
00263
00264
00265 r.Set("ZTolerance", 0.0);
00266
00267
00268
00269 r.Set("NoFieldBeyondZ", 9999.0);
00270
00271
00272
00273
00274 r.Set("ForceUseEverywhere", 0);
00275
00276
00277 r.Set("IgnoreUseEverywhere", 1);
00278
00279 r.LockValues();
00280
00281 return r;
00282
00283 }
00284
00285
00286 void BfldLoanPool::SetConfigFromEnvironment()
00287 {
00288
00289
00290
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
00311
00312
00313
00314
00315
00316 BfldMap *bmap;
00317
00318
00319 TIter iter(&fBfldMapList);
00320 while ( ( bmap = (BfldMap *)iter.Next() ) ) {
00321
00322 if ( bmap->GetGrid() == grid &&
00323 bmap->GetVariant() == variant ) return bmap;
00324 }
00325
00326
00327
00328
00329
00330
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
00343 fBfldMapList.Add(bmap);
00344
00345 return bmap;
00346 }
00347
00348
00349 BfldMesh* BfldLoanPool::GetMesh(BfldGrid::Grid_t grid, Int_t variant)
00350 {
00351
00352
00353
00354
00355
00356
00357 BfldMesh *mesh;
00358 Bool_t isRect2d = ( BfldGrid::kRect2dGrid == grid );
00359
00360
00361 TIter iter(&fBfldMeshList);
00362 while ( ( mesh = (BfldMesh *)iter.Next() ) ) {
00363
00364 if ( isRect2d ) {
00365 if ( mesh->GetGrid() == grid &&
00366 mesh->GetVariant() == variant ) return mesh;
00367 }
00368 else if ( mesh->GetGrid() == grid ) return mesh;
00369 }
00370
00371
00372
00373
00374
00375
00376 if ( isRect2d ) {
00377
00378
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
00387
00388 return 0;
00389 }
00390 mesh = new BfldMeshRect2d(bmap2d);
00391 } else {
00392 mesh = new BfldMeshVoronoi(grid,variant);
00393 }
00394
00395 fBfldMeshList.Add(mesh);
00396
00397 return mesh;
00398 }
00399
00400
00401 BfldCache* BfldLoanPool::GetCache(VldContext& vldc)
00402 {
00403
00404
00405 BfldCache *cache;
00406
00407
00408
00409 Int_t todelete = -fMaxUnrefCaches;
00410 TIter iter(&fBfldCacheList);
00411 while ( ( cache = (BfldCache *)iter.Next() ) ) {
00412
00413 if ( cache->GetVldRange().IsCompatible(vldc) ) return cache;
00414 if ( cache->CountRef() <= 0 ) todelete++;
00415 }
00416
00417
00418
00419
00420
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
00433 fBfldCacheList.Compress();
00434 }
00435
00436
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 * ) const
00446 {
00447
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