Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members  

BfldMapRect2d.cxx

Go to the documentation of this file.
00001 
00002 // $Id: BfldMapRect2d.cxx,v 1.8 2002/06/13 15:02:10 rhatcher Exp $
00003 // 
00004 // BfldMapRect2d 
00005 // 
00006 // This structure provides services for holding the magnetic field components
00007 // at a series of points (cf. BfldMesh).  It encapsulates knowledge 
00008 // about the field values themselves, an possibly how to adjust them
00009 // for external effects (chemistry, coil current, etc.) but doesn't
00010 // explicitly hold any knowledge about the relative spatial placement
00011 // of the field values; that it must glean from BfldMesh.
00012 //
00013 // This rectangular 2-d grid specialization actually does know info
00014 // about the position info (as it was in the file that contained the
00015 // field values), but it provides an interface so that BfldMeshRect2d
00016 // can access it.
00017 //
00018 // Author:  R. Hatcher 2000.06.20
00019 //
00021 #include "BField/BfldMapRect2d.h"
00022 
00023 #include "BField/BfldMeshRect2d.h"
00024 #include "Conventions/Munits.h"
00025 
00026 // necessary so that one can check "InheritsFrom"
00027 #include "TClass.h"
00028 // for expanding filename
00029 #include "TSystem.h"
00030 #include "TMath.h"
00031 
00032 #include "MessageService/MsgService.h"
00033 CVSID("$Id: BfldMapRect2d.cxx,v 1.8 2002/06/13 15:02:10 rhatcher Exp $");
00034 
00035 #include <iostream>
00036 #include <fstream>
00037 #include <iomanip>
00038 
00039 ClassImp(BfldMapRect2d)
00040 
00041 //______________________________________________________________________________
00042 BfldMapRect2d::BfldMapRect2d() 
00043    : BfldMap()
00044 {
00045 
00046 }
00047 
00048 //______________________________________________________________________________
00049 BfldMapRect2d::BfldMapRect2d(BfldGrid::Grid_t grid, Int_t variant) 
00050    : BfldMap(grid,variant), fReadOk(kFALSE)
00051 {
00052    // read in a Map
00053 
00054    // strip off "-" sign if necessary
00055    Int_t varabs = TMath::Abs(variant);
00056 
00057    MSG("Bfld",Msg::kInfo) << "BfldMapRect2d ctor map " << varabs << endl;
00058 
00059    char string[255];
00060 
00061    // format and expand file name
00062    sprintf(string,"$BMAPPATH/bfld_%3d.dat",varabs);
00063    fFilename = string;
00064    gSystem->ExpandPathName(fFilename);
00065 
00066    // open the file for reading
00067    ifstream from;
00068    from.open(fFilename,ios::in);
00069    if (!from) {
00070       MSG("Bfld",Msg::kError) << "can not open input file: '" 
00071                               << fFilename <<"'"<< endl;
00072       return;
00073    }
00074 
00075    // read in the header line
00076    from.getline(string,sizeof(string),'\n');
00077    fHeader = string;
00078 
00079    
00080    MSG("Bfld",Msg::kInfo) << "read file: " << fFilename << endl;
00081    MSG("Bfld",Msg::kInfo) << "   header: " << fHeader << endl;
00082 
00083    from >> fX0 >> fDx >> fNx >> fY0 >> fDy >> fNy;
00084    // lengths read in from map files are in cm, convert to base units
00085    fX0 *= Munits::cm;
00086    fDx *= Munits::cm;
00087    fY0 *= Munits::cm;
00088    fDy *= Munits::cm;
00089 
00090 
00091    MSG("Bfld",Msg::kInfo) 
00092       << " x0 " << fX0 << " dx " << fDx << " nx " << fNx 
00093       << " y0 " << fY0 << " dy " << fDy << " ny " << fNy << endl;
00094 
00095    // read in remainder of the line for any quadflags
00096    from.getline(string,sizeof(string),'\n');
00097    TString quads = string;
00098 
00099    // first 19 characters are useless junk (z0,dz,nz)
00100    // replace "x" with " "
00101    quads = quads.Remove(0,19);
00102    quads = quads.ReplaceAll("x"," ");
00103    // quads should be of the form ' 00 00 00 00  FNAL2'
00104 
00105    fFileForm = 0;
00106    if (quads.Contains("FNAL"))  fFileForm = 1;
00107    if (quads.Contains("FNAL2")) fFileForm = 2;
00108    MSG("Bfld",Msg::kInfo) << "fileform " << fFileForm << endl;
00109 
00110    // remove any "FNAL" flag
00111    if (quads.Length() > 12) quads = quads.Remove(12);
00112 
00113    // scan the remaining part for the quad flags
00114    if (quads.Length() > 0) {
00115       sscanf(quads,"%3d%3d%3d%3d",
00116              fQuadFlags,fQuadFlags+1,fQuadFlags+2,fQuadFlags+3);
00117    } else {
00118       MSG("Bfld",Msg::kInfo) << "no quads info - use defaults" << endl;
00119       fQuadFlags[0] = 0;
00120       fQuadFlags[1] = 2;
00121       fQuadFlags[2] = 3;
00122       fQuadFlags[3] = 1;
00123    }
00124 
00125    // if x0=0,y0=0 assume map only has one quadrant 
00126    fQuadrant = ( 0 == fX0 && 0 == fY0 );
00127 
00128    MSG("Bfld",Msg::kInfo) << "quadflags (" 
00129                           << fQuadFlags[0] << "," 
00130                           << fQuadFlags[1] << "," 
00131                           << fQuadFlags[2] << "," 
00132                           << fQuadFlags[3] << ")  use them " 
00133                           << (fQuadrant ? "'true'" : "'false'") << endl;
00134 
00135    // allocate a container
00136    fFieldVectors = new TClonesArray("TVector3",fNx*fNy);
00137 
00138    Int_t   ii, indx;
00139    Float_t x,y,z;
00140    Float_t bx,by,bz,bmag;
00141 
00142    const Float_t GaussToKGauss = 0.001;
00143    const Float_t TeslaToKGauss = 10.;
00144 
00145    // start reading the file
00146    for (Int_t i=0; i < fNx*fNy; i++) {
00147 
00148       switch (fFileForm) {
00149       case 0:
00150          from >> x >> y >> z >> bx >> by >> bz >> bmag;
00151          // LLNL maps were in gauss ... need kGauss
00152          bx   = bx   * GaussToKGauss;
00153          by   = by   * GaussToKGauss;
00154          bz   = bz   * GaussToKGauss;
00155          bmag = bmag * GaussToKGauss;
00156          break;
00157       case 1:
00158          from >> ii >> x >> y >> bx >> by;
00159          // FNAL (version 1) maps were in Tesla
00160          bx   = bx   * TeslaToKGauss;
00161          by   = by   * TeslaToKGauss;
00162          bz   = 0.0;
00163          break;
00164       case 2:
00165          from >> x >> y >> z >> bx >> by >> bz >> bmag;
00166          // FNAL (version 2) maps were in Tesla
00167          bx   = bx   * TeslaToKGauss;
00168          by   = by   * TeslaToKGauss;
00169          bz   = bz   * TeslaToKGauss;
00170          bmag = bmag * TeslaToKGauss;
00171          break;
00172       default:
00173          MSG("Bfld",Msg::kFatal) << " bad FileForm " << fFileForm << endl;
00174          break;
00175       }
00176       // the above puts field values in kGauss
00177       // convert them to base units
00178       bx   *= Munits::kilogauss;
00179       by   *= Munits::kilogauss;
00180       bz   *= Munits::kilogauss;
00181       bmag *= Munits::kilogauss;
00182       // positions read in are given in cm
00183       x    *= Munits::cm;
00184       y    *= Munits::cm;
00185       z    *= Munits::cm;
00186 
00187       // all the maps aren't in consistent order (ascending/descending x,y)
00188       // so we have to actually interpret the (x,y) values to determine 
00189       // the array index.
00190       // we'll put them in the array in a way that we can lookup 
00191       // based on fX0,fDx,fNx,fY0,fDy,fNy
00192 
00193       indx = LowerLeftGenerator(x,y);
00194 
00195       // create new TVector3 and put it in the TClonesArray
00196       // what a crazy syntax!
00197       new((*fFieldVectors)[indx]) TVector3(bx,by,bz);
00198 
00199 #ifdef BLAHBLAH
00200       // one *might* think of using [i] rather than [indx]
00201       if (indx != i &&  i < 2*fNx ) {
00202          MSG("Bfld",Msg::kWarning) << " i " << i << " indx " << indx
00203                                    << " (" << x << "," << y << ")" << endl;
00204       }
00205 #endif
00206 
00207 
00208    }
00209 
00210    MSG("Bfld",Msg::kInfo) << "BfldMapRect2d file read in" << endl;
00211 
00212    fReadOk = kTRUE;
00213 }
00214 
00215 //______________________________________________________________________________
00216 BfldMapRect2d::~BfldMapRect2d()
00217 {
00218    // dtor deletes owned components
00219 
00220    MSG("Bfld",Msg::kDebug) << "~BfldMapRect2d variant " << fVariant << endl;
00221 
00222    fGrid    = BfldGrid::kUndefined;
00223    fVariant = -1;
00224 
00225    if (fFieldVectors) fFieldVectors->Delete();
00226 
00227    delete fFieldVectors;
00228    fFieldVectors = 0;
00229 
00230 }
00231 
00232 //______________________________________________________________________________
00233 TVector3 BfldMapRect2d::GetBField(Int_t generator)
00234 {
00235    TVector3 bvector = GetRawField(generator);
00236    // apply corrections for coil, chemistry, end plane-ness...
00237    return bvector;
00238 }
00239 
00240 //______________________________________________________________________________
00241 TVector3 BfldMapRect2d::GetRawField(Int_t generator)
00242 {
00243    if (fReadOk && generator > 0 && generator <= fFieldVectors->GetLast()) {
00244       TVector3* raw = dynamic_cast<TVector3*>(fFieldVectors->At(generator));
00245       if (raw) return *raw;
00246       MSG("Bfld",Msg::kError)
00247          << " no raw field for generator " << generator << endl;
00248    }
00249    return TVector3(0.,0.,0.);
00250 }
00251 
00252 //______________________________________________________________________________
00253 void BfldMapRect2d::SetMesh(BfldMesh *mesh)
00254 {
00255    fMesh = mesh;
00256    BfldMeshRect2d* rect2dMesh = dynamic_cast<BfldMeshRect2d*>(mesh);
00257    if ( rect2dMesh ) {
00258       rect2dMesh->SetMapRect2d(this);
00259    } else {
00260       MSG("Bfld",Msg::kWarning) << "BfldMapRect2d::SetMesh wasn't passed a Rect2 object" << endl;
00261    }
00262 }
00263 
00264 //______________________________________________________________________________
00265 Int_t BfldMapRect2d::IndicesToGenerator(Int_t ix, Int_t iy)
00266 {
00267    // return the generator (indx) based on x-y indices
00268 
00269    return ix*fNy + iy;
00270 }
00271 
00272 //______________________________________________________________________________
00273 void BfldMapRect2d::GeneratorToIndices(Int_t gen, Int_t &ix, Int_t &iy)
00274 {
00275    // return the x-y indices base on generator number
00276 
00277    // composed via ix*fNy + iy;
00278 
00279    ix = gen/fNy;
00280    iy = gen%fNy;
00281 
00282 }
00283 
00284 //______________________________________________________________________________
00285 Int_t BfldMapRect2d::LowerLeftGenerator(Float_t x, Float_t y)
00286 {
00287    // return the generator (indx) associated with the (x,y) position
00288 
00289    if ( fQuadrant ) {
00290       // symmetry case -- assume quadrant symmetry
00291       x = TMath::Abs(x);
00292       y = TMath::Abs(y);
00293    }
00294 
00295    // add epsilon to deal with roundoff errors introduced in
00296    // converting from cm in map file to Munits base length
00297    const Float_t epsilon = 1.0e-5;
00298 
00299    Float_t xx = (x - fX0) / fDx + epsilon;
00300    Float_t yy = (y - fY0) / fDy + epsilon;
00301    Int_t ix = (int)xx;
00302    Int_t iy = (int)yy;
00303 
00304    ix = TMath::Min(ix,fNx-1);
00305    iy = TMath::Min(iy,fNy-1);
00306 
00307    ix = TMath::Max(ix,0);
00308    iy = TMath::Max(iy,0);
00309 
00310    return IndicesToGenerator(ix,iy);
00311 }
00312 
00313 //______________________________________________________________________________
00314 Int_t BfldMapRect2d::LowerLeftGenerator(TVector3 xyz)
00315 {
00316    // return the generator (indx) associated with the (x,y) position
00317 
00318    return LowerLeftGenerator(xyz.X(),xyz.Y());
00319 }
00320 
00321 //______________________________________________________________________________
00322 Int_t BfldMapRect2d::NeighborGenerator(Int_t gen, Int_t dnx, Int_t dny)
00323 {
00324    // return the generator (indx) which is a neighbor to the input one
00325    // return -1 if no such index
00326 
00327    Int_t ix = 0;
00328    Int_t iy = 0;
00329 
00330    GeneratorToIndices(gen,ix,iy);
00331 
00332    ix = ix + dnx;
00333    iy = iy + dny;
00334 
00335    if (ix<0 || ix>=fNx) return -1;
00336    if (iy<0 || iy>=fNy) return -1;
00337 
00338    return IndicesToGenerator(ix,iy);
00339 
00340 }
00341 
00342 //______________________________________________________________________________

Generated on Wed Sep 4 19:00:54 2002 for loon by doxygen1.2.16