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

RerootExodus.cxx

Go to the documentation of this file.
00001 
00002 // $Id: RerootExodus.cxx,v 1.62 2008/05/16 15:50:29 rhatcher Exp $
00003 //
00004 // RerootExodus
00005 //
00006 // RerootExodus is static-only class for dealing with the REROOT data
00007 //
00008 // Author:  R. Hatcher 2000.05.19
00009 //
00011 
00012 #include "RerootExodus/RerootExodus.h"
00013 
00014 // needed for "rgeo" and "revt"
00015 #include "MINF_Classes/MINFast.h"
00016 
00017 #include "TArrayI.h"
00018 #include "TMath.h"
00019 #include "TSystem.h"
00020 
00021 #include "MessageService/MsgService.h"
00022 CVSID("$Id: RerootExodus.cxx,v 1.62 2008/05/16 15:50:29 rhatcher Exp $");
00023 
00024 #include <cassert>
00025 
00026 
00027 static Int_t        LastSteelMapGeometry  = -999;
00028 static TArrayI     *SteelMap              = 0;
00029 static Bool_t       FirstPasvAir          = false;  // set with steel map
00030 static VldTimeStamp NullVldTimeStamp      = VldTimeStamp((time_t)0,0);
00031 
00032 VldTimeStamp RerootExodus::fInitialVldTimeStamp = NullVldTimeStamp;
00033 VldTimeStamp RerootExodus::fLastVldTimeStamp    = NullVldTimeStamp;
00034 VldTimeStamp RerootExodus::fSpillTimeInterval   = 
00035            VldTimeStamp((time_t)1,900000000);
00036 //                              s mmmuuunnn
00037 UInt_t       RerootExodus::fNSpills = 0;
00038 UInt_t       RerootExodus::fSnarlNum = 0;
00039 
00040 static SimFlag::SimFlag_t DefaultSimFlag  = SimFlag::kReroot;
00041 static Detector::Detector_t ForceDetector = Detector::kUnknown;
00042 
00043 const Int_t  kSubRunMagic = 100000;
00044 
00045 ClassImp(RerootExodus)
00046 
00047 //_____________________________________________________________________________
00048 RerootExodus::RerootExodus()
00049 {
00050    // Default constructor -- called by self only
00051 }
00052 
00053 //_____________________________________________________________________________
00054 RerootExodus::RerootExodus(const RerootExodus &plp)
00055   : TObject(plp)
00056 {
00057    // copy constuctor should never get called
00058    MSG("Exodus",Msg::kFatal) << 
00059                "RerootExodus copy constructor called" << endl;
00060    assert(0);
00061 }
00062 
00063 //_____________________________________________________________________________
00064 RerootExodus::~RerootExodus()
00065 {
00066    // delete all the owned sub-objects
00067 }
00068 
00069 //_____________________________________________________________________________
00070 Detector::Detector_t RerootExodus::GetDetector()
00071 {
00072    // interpret GeomMisc_NearFar to get detector type
00073    // unless ForceDetector is set to something other than kUnknown
00074    // in which case use that.
00075 
00076   if ( ForceDetector != Detector::kUnknown ) return ForceDetector;
00077 
00078    if (!gMINFast) {
00079       static int nmsg = 10;
00080       if (nmsg) {
00081          MSG("Exodus",Msg::kFatal) 
00082             << "GetDetector lacked gMINFast" 
00083             << endl;
00084          nmsg--;
00085          if (!nmsg) MSG("Exodus",Msg::kFatal) 
00086             << " ... last such message" << endl;
00087       }
00088       return Detector::kUnknown;
00089    }
00090 
00091    REROOT_GeomMisc *geommisc = GetGeomMisc();
00092    Int_t nearfar = geommisc->NearFar();
00093 
00094    if ( nearfar < 0 ) {
00095       return Detector::kNear;
00096    } else if ( nearfar > 0 ) {
00097       return Detector::kFar;
00098    } else if ( nearfar == 0 ) {
00099       return Detector::kCalDet;
00100    } else {
00101       return Detector::kUnknown;  // pass back a bad value
00102    }
00103 
00104 }
00105 
00106 //_____________________________________________________________________________
00107 void RerootExodus::SetVldSimFlag(SimFlag::SimFlag_t flag)
00108 {
00109   // Set the default SimFlag
00110   DefaultSimFlag = flag;
00111 }
00112 
00113 SimFlag::SimFlag_t RerootExodus::GetVldSimFlag()
00114 {
00115   // get the default SimFlag
00116   return DefaultSimFlag;
00117 }
00118 
00119 void RerootExodus::SetForceDetector(Detector::Detector_t det)
00120 {
00121   // Set the ForceDetector -- if anything but kUnknown then
00122   // the GetDetector() and BuildVldContext() will use this to
00123   // override what it would otherwise choose.
00124   ForceDetector = det;
00125 
00126   if ( det != Detector::kUnknown ) {
00127     MSG("Exodus",Msg::kWarning)
00128       << endl
00129       << "#################################################################" 
00130       << endl
00131       << "Whoa!  You are forcing VldContext to use k"
00132       << Detector::AsString(det) << " as the detector," << endl
00133       << "which overrides what might be found in the reroot file." 
00134       << "  I sure " << endl
00135       << "hope you know what you're doing!  Don't say I didn't warn you." 
00136       << endl
00137       << "#################################################################" 
00138       << endl;
00139   }
00140 
00141 }
00142 
00143 Detector::Detector_t RerootExodus::GetForceDetector()
00144 {
00145   // get the ForceDetector setting
00146   return ForceDetector;
00147 }
00148 //_____________________________________________________________________________
00149 VldContext RerootExodus::BuildVldContext(void)
00150 {   // Build a VldContext object from the REROOT
00151    // geometry and event currently available
00152 
00153    if (!gMINFast) {
00154       static int nmsg = 10;
00155       if (nmsg) {
00156          MSG("Exodus",Msg::kFatal) 
00157             << "BuildVldContext lacked gMINFast" 
00158             << endl;
00159          nmsg--;
00160          if (!nmsg) MSG("Exodus",Msg::kFatal) 
00161             << " ... last such message" << endl;
00162       }
00163       VldTimeStamp now;
00164       return VldContext(Detector::kUnknown,DefaultSimFlag,now);
00165    }
00166 
00167    // Determine detector type
00168    Detector::Detector_t detector = GetDetector();
00169 
00170    // By definition these should be flagged as Reroot derived
00171    SimFlag::SimFlag_t simflag = DefaultSimFlag;
00172 
00173    // determine run and event numbers
00174    // Int_t run = GetRunNo(); 
00175    Int_t evt = GetEventNo();
00176    static Int_t evt_last = 0;
00177 
00178    // Set inital timestamp if not yet set
00179    if (fInitialVldTimeStamp == NullVldTimeStamp) {
00180 
00181      fInitialVldTimeStamp = GetLastEventHistoryTimeStamp(true); // no hr,min,sec
00182 
00183      MSG("Exodus",Msg::kInfo)
00184        << "RerootExodus::BuildVldContext initial timestamp "
00185        << fInitialVldTimeStamp
00186        << " spill interval " 
00187        << fSpillTimeInterval.AsString("2")
00188        << endl;
00189    }
00190 
00191    // if it's a new event move things along
00192    if ( evt_last != evt ) {
00193      evt_last = evt;
00194      fNSpills++;
00195      // make time stamping independent of where we start in the file
00196      fLastVldTimeStamp = fInitialVldTimeStamp;
00197      fLastVldTimeStamp.Add(fSpillTimeInterval*GetEventRecord());
00198    }
00199 
00200    // Construct and return a VldContext
00201    return VldContext(detector,simflag,fLastVldTimeStamp);
00202 }
00203 
00204 //_____________________________________________________________________________
00205 Int_t RerootExodus::GetTimeFrame(VldContext& /* vldc */)
00206 {
00207   // return the TimeFrame that corresponds to this VldContext
00208   return Int_t( fSpillTimeInterval*(GetSnarlNum()%kSubRunMagic) );
00209 }
00210 
00211 //_____________________________________________________________________________
00212 Short_t RerootExodus::GetSubRunNum()
00213 {
00214   // return the SubRun #
00215   // it's embedded into the GEANT event #
00216   return GetEventNo()/kSubRunMagic;
00217 }
00218 
00219 //_____________________________________________________________________________
00220 Int_t RerootExodus::GetSnarlNum()
00221 {
00222   // assign a SnarlNum()  tie to tree entry, but different for subruns
00223   return kSubRunMagic*GetSubRunNum() + GetEventRecord();
00224 }
00225 
00226 //_____________________________________________________________________________
00227 VldRange RerootExodus::BuildVldRange(void)
00228 {
00229    VldContext vldc = BuildVldContext();
00230 
00231    VldTimeStamp start = vldc.GetTimeStamp();
00232    Int_t maxdt        = 4*24*60*60;  // max sec of reroot *file* generation
00233    VldTimeStamp end   = VldTimeStamp(start.GetSec()+maxdt,999999999);
00234 
00235    return VldRange(vldc.GetDetector(),
00236                    vldc.GetSimFlag(),
00237                    start,end,"RerootExodus");
00238 }
00239 
00240 //_____________________________________________________________________________
00241 Int_t RerootExodus::NumberOfPlanes(const Bool_t isactv, const Int_t supermodule)
00242 {
00243    // count the number of FLS or B planes in the geometry
00244 
00245    if (!gMINFast) {
00246       MSG("Exodus",Msg::kFatal) 
00247          << "NumberOfPlanes lacked gMINFast" 
00248          << endl;
00249       return 0;
00250    }
00251    
00252    REROOT_Geom  *rgeo = gMINFast->GetREROOTGeom();
00253 //   REROOT_GeomMisc *geommisc = GetGeomMisc();
00254 
00255    const TClonesArray *planeposs    = rgeo->planeposs();
00256    REROOT_PlanePos    *planepos     = 0;
00257 
00258    Int_t nplns = 0;
00259 
00260    for (Int_t rpln=0; rpln<planeposs->GetLast()+1; rpln++) {
00261       planepos = (REROOT_PlanePos*) planeposs->At(rpln);
00262       if (planepos->ISuper() == supermodule || supermodule == -1) {
00263          if (isactv) {
00264             // count only FLS planes
00265             if (planepos->ActvName()[0] == 'F') nplns++;
00266          } else {
00267             // count only Steel planes
00268             if (planepos->PasvName()[0] == 'B') nplns++;
00269          }
00270       }
00271    }
00272 
00273    return nplns;
00274 
00275 }
00276 //_____________________________________________________________________________
00277 Int_t RerootExodus::RerootToSteelPlane(const Int_t rpln,
00278                                        const Bool_t isactv)
00279 {
00280    // Convert from REROOT plane # to Steel Plane #
00281 
00282    if (!gMINFast) {
00283       MSG("Exodus",Msg::kFatal) 
00284          << "RerootToSteelPlane lacked gMINFast" 
00285          << endl;
00286       return 0;
00287    }
00288    
00289    TArrayI *steel = CreateSteelMap();
00290 
00291    Int_t spln;
00292 
00293    if (rpln < 0 || rpln > steel->GetSize()-1 ) {
00294       static Int_t msg = 2;
00295       if (msg>0) {
00296          const Char_t *active = (isactv) ? "active" : "steel";
00297          MSG("Exodus",Msg::kDebug) << endl
00298             << " RerootToSteelPlane  reroot " << active << " plane " << rpln 
00299             << " out of bounds " << endl;
00300          msg--;
00301       }
00302       spln = -1;
00303    } else {
00304       spln = (*steel)[rpln];
00305    }
00306 
00307    // if asking about "active" plane then make adjustment for
00308    // the fact the GMINOS mounts actives on the back of the
00309    // steel while construction will have them on the front
00310    // the lead "blank" steel make this all work out ok
00311    //         B  A B  A B  A B  A   B=steel, A=active
00312    // f77     1  1 2  2 3  3 4  4  
00313    // reroot  0  0 1  1 2  2 3  3
00314    // steel   0  1 1  2 2  3 3  4
00315    //
00316    // For Caldet, construction has active mounted on the front
00317    // of steel. In GMINOS this is hacked as plane 1 being active
00318    // mounted on the back of air (passive), planes 2-60 being
00319    // active on the back of steel, and plane 61 being the "blank"
00320    // steel (air mounted on the back of steel). With the above
00321    // numbering scheme, this works out to steel planes numbering
00322    // from 1-60 rather than 0-59 as desired. To fix, need to
00323    // subtract 1 from the above "steel" number to get the correct
00324    // "caldet" number.
00325    //            A B  A B  A B  A B
00326    // f77        1 2  2 3  3 4  4 5
00327    // reroot     0 1  1 2  2 3  3 4
00328    // steel      1 1  2 2  3 3  4 4
00329    // caldet     0 0  1 1  2 2  3 3
00330 
00331    if (isactv) spln++;
00332    if (FirstPasvAir) spln--;
00333 
00334    return spln;
00335 }
00336 
00337 //_____________________________________________________________________________
00338 Int_t RerootExodus::SteelToRerootPlane(const Int_t spln,
00339                                        const Bool_t isactv)
00340 {
00341    // Convert from Steel Plane # to REROOT plane #
00342 
00343    if (!gMINFast) {
00344       static int nmsg = 10;
00345       if (nmsg) {
00346          MSG("Exodus",Msg::kFatal) 
00347             << "SteelToRerootPlane lacked gMINFast" 
00348             << endl;
00349          nmsg--;
00350          if (!nmsg) MSG("Exodus",Msg::kFatal) 
00351             << " ... last such message" << endl;
00352       }
00353       return 0;
00354    }
00355    
00356    TArrayI *steel = CreateSteelMap();
00357 
00358    // if asking about "active" plane then make adjustment for
00359    // the fact the GMINOS mounts actives on the back of the
00360    // steel while construction will have them on the front
00361    // the lead "blank" steel make this all work out ok
00362    //         B  A B  A B  A B  A   B=steel, A=active
00363    // f77     1  1 2  2 3  3 4  4  
00364    // reroot  0  0 1  1 2  2 3  3
00365    // steel   0  1 1  2 2  3 3  4
00366    //
00367    // For Caldet, construction has active mounted on the front
00368    // of steel. In GMINOS this is hacked as plane 1 being active
00369    // mounted on the back of air (passive), planes 2-60 being
00370    // active on the back of steel, and plane 61 being the "blank"
00371    // steel (air mounted on the back of steel). With the above
00372    // numbering scheme, this works out to steel planes numbering
00373    // from 1-60 rather than 0-59 as desired. To fix, need to
00374    // subtract 1 from the above "steel" number to get the correct
00375    // "caldet" number.
00376    //            A B  A B  A B  A B
00377    // f77        1 2  2 3  3 4  4 5
00378    // reroot     0 1  1 2  2 3  3 4
00379    // steel      1 1  2 2  3 3  4 4
00380    // caldet     0 0  1 1  2 2  3 3
00381 
00382 
00383    Int_t lookfor = (isactv) ? spln-1 : spln;
00384    if (FirstPasvAir) lookfor++;
00385 
00386    Int_t indx = TMath::BinarySearch(steel->GetSize(),steel->GetArray(),lookfor);
00387 
00388    if (indx < 0 || indx > steel->GetSize()-1 || lookfor != (*steel)[indx] ) {
00389       // last test is an artifact of TMath:BinarySearch
00390 
00391       static Int_t msg = 2;
00392       if (msg>0) {
00393          const Char_t *active = (isactv) ? "active" : "steel";
00394          Char_t result[8] = "illegal";
00395          if (indx>0 && indx < steel->GetSize()) 
00396             sprintf(result,"%d",(*steel)[indx]);
00397          MSG("Exodus",Msg::kDebug) 
00398             << "SteelToRerootPlane " << active 
00399             << " plane (spln) " << spln << endl
00400             << " not found in map "
00401             << "    lookfor " << lookfor << " indx " << indx 
00402             << " (*steel)[indx] " 
00403             << result << endl;
00404          msg--;
00405       }
00406       indx = -1;
00407       // don't return here without deleting the map
00408    }
00409 
00410    return indx;
00411 }
00412 
00413 //_____________________________________________________________________________
00414 TArrayI *RerootExodus::CreateSteelMap(void)
00415 {
00416    // Build a map from REROOT Plane # to Steel Plane #
00417    // For near detector it is just a shift of 1
00418    //   (due to the 0-th steel no having any attached scintillator)
00419    // For the far detector there is the shift of 1 plus
00420    //   the extra steel that is missing in the model of the
00421    //   supermodule gaps -- if it used the 2 supermodule setup.
00422    //   If it used the 6 supermodule setup then this is accounted
00423    //   for and we only need the shift by 1
00424    //   6 supermodules = (10BF) (220BF) (10BF+1BT) (10BF) (220BF) (10BF+1BT)
00425 
00426    if (!gMINFast) {
00427       MSG("Exodus",Msg::kFatal) 
00428          << "CreateSteelMap lacked gMINFast" 
00429          << endl;
00430       return 0;
00431    }
00432    
00433    REROOT_Geom  *rgeo = gREROOT_Geom;
00434    
00435    if (rgeo->GetNumberRead() == LastSteelMapGeometry) return SteelMap;
00436 
00437    // delete whatever exists
00438    delete SteelMap;
00439 
00440    // REROOT_GeomMisc *geommisc = GetGeomMisc();
00441 
00442    Detector::Detector_t detector = GetDetector();
00443 
00444    //Int_t nsupmdl = geommisc->NSupmdl();
00445    Int_t nsupdiv = 1;
00446 
00447    // all Far file *now* assume 3 "supermodules" per physical supermodule
00448    // structure (gone are the cases of 1:1 and 2:1)
00449    if (Detector::kFar == detector) nsupdiv = 3;
00450 
00451    const TClonesArray *planeposs    = rgeo->planeposs();
00452 
00453    Int_t nplns = planeposs->GetLast()+1;
00454 
00455    Int_t *array = new Int_t [nplns];
00456 
00457    // work with base array -- we don't need bounds checking here
00458 
00459    for (Int_t rpln = 0; rpln < nplns; rpln++) array[rpln] = rpln;
00460 
00461    // check whether we're leading with a intial "AIR" passive
00462    Char_t ptype = ((REROOT_PlanePos*)planeposs->At(0))->PasvName()[0];
00463    FirstPasvAir = (ptype == 'K');
00464 
00465    // hack for non-standard far detector geometries
00466    if (detector == Detector::kFar) {
00467 
00468       if (RerootPlaneToView(0) == 'U') {
00469         MSG("Exodus",Msg::kWarning) 
00470           << "CreateSteelMap() no longer supports setting "
00471           << "PlexPlaneId::fgFarIsUV=true"
00472           << endl
00473           << "No longer accept FarDet geomtries that start with U plane"
00474           << endl;
00475         assert(0);
00476       }
00477 
00478       const TClonesArray *supermodules = rgeo->supermodules();
00479       Int_t iSM, iSMpart, nplnsInSM = 0;
00480       REROOT_SuperModule *supermodule  = 0;
00481       for (int gsup=0; gsup < supermodules->GetLast()+1; gsup++) {
00482          // assume!! 3 GMINOS supermodules per physical supermodule
00483          iSM     = gsup/3;
00484          iSMpart = gsup%3;
00485          if (iSMpart == 0) nplnsInSM = 0;
00486          supermodule = (REROOT_SuperModule*) supermodules->At(gsup);
00487          nplnsInSM += supermodule->NActvPln();
00488          if (iSM>2) {
00489             MSG("Exodus",Msg::kError)
00490                << "CreateSteelMap saw "
00491                << supermodules->GetLast()+1 
00492                << " GMINOS supermodules " << endl
00493                << "   more than the allowed 2 physical SM (of 3 GMINOS  SM each)" << endl;
00494             break;
00495          }
00496          else {
00497             if (iSMpart == 2) {
00498                MSG("Exodus",Msg::kInfo)
00499                   << "RerootExodus::CreateSteelMap setting # planes in SM "
00500                   << iSM << " to " << nplnsInSM << endl;
00501                //PlexPlaneId::fgNumPlnsInFarSM[iSM] = nplnsInSM;
00502             }
00503          }
00504       }       // loop over GMINOS supermodules
00505    }          // Far
00506    else if (detector == Detector::kCalDet) {
00507       PlexPlaneId::fgCalDetCosmicsAView = (RerootPlaneToView(61) == 'A');
00508    }
00509 
00510    SteelMap = new TArrayI();
00511    SteelMap->Adopt(nplns,array);
00512    LastSteelMapGeometry = rgeo->GetNumberRead();
00513    MSG("Exodus",Msg::kDebug) << "created new SteelMap for " 
00514                              << LastSteelMapGeometry << endl;
00515    return SteelMap;
00516 }
00517 
00518 //_____________________________________________________________________________
00519 Char_t RerootExodus::RerootPlaneToView(const Int_t rpln)
00520 {
00521 
00522    if (!gMINFast) {
00523       MSG("Exodus",Msg::kFatal) 
00524          << "RerootPlaneToView lacked gMINFast" 
00525          << endl;
00526       return 0;
00527    }
00528    
00529    REROOT_Geom  *rgeo = gMINFast->GetREROOTGeom();
00530 
00531    const TClonesArray *planeposs   = rgeo->planeposs();
00532    REROOT_PlanePos    *planepos    = (REROOT_PlanePos*) planeposs->At(rpln);
00533 
00534    return planepos->Rotm()[0];
00535 }
00536 
00537 //_____________________________________________________________________________
00538 PlexPlaneId RerootExodus::RerootPln2PlnId(const Int_t rpln, const Bool_t isactv)
00539 {
00540    // Convert from REROOT numbering to PlexPlaneId object
00541 
00542    if (!gMINFast) {
00543       MSG("Exodus",Msg::kFatal) 
00544          << "RerotoPln2PlnId lacked gMINFast" 
00545          << endl;
00546       return PlexPlaneId();
00547    }
00548    
00549    // the correct plane # for this type of plane
00550    Int_t plnid_spln = RerootToSteelPlane(rpln,isactv);
00551    Int_t rpln_back  = SteelToRerootPlane(plnid_spln,isactv);
00552 
00553    PlaneView::PlaneView_t plnid_view  = PlaneView::kUnknown;
00554    PlaneCoverage::PlaneCoverage_t plnid_cover = PlaneCoverage::kUnknown;
00555    
00556    PlexPlaneId noactive(GetDetector(),plnid_spln,!isactv,plnid_view,plnid_cover);
00557    if (GetDetector() == Detector::kCalDet && plnid_spln == 0) {
00558       // PlexPlaneId takes unknown as request for hardcoded default
00559       // which in this case assumes the CalDet 0 plane *is* instrumented
00560       // ??? noactive.SetPlaneView(PlaneView::kUnknown);
00561       // ??? noactive.SetPlaneCoverage(PlaneCoverage::kUninstrumented);
00562    }
00563 
00564    bool debug_noactive = false;
00565    // if it doesn't map back to itself then it isn't there
00566    if (rpln_back != rpln) {
00567       if (debug_noactive) cout << "  ******** failed to map back *" << endl;
00568       return noactive;
00569    }
00570 
00571    // view & coverage depend on the *active* 
00572    // (so if asked about a steel plane return attached active's view&coverage)
00573    Int_t rpln_active = SteelToRerootPlane(plnid_spln,kTRUE);
00574 
00575    // deal with case of the active plane attached isn't a FLS plane
00576    // or doesn't exist at all
00577    if (rpln_active<0) {
00578       if (debug_noactive) cout << "  ******** rpln_active < 0 *" << endl;
00579       return noactive;
00580    }
00581    if (ActvPlaneName(rpln_active)[0] != 'F') {
00582       if (debug_noactive) cout << "  ******** upstream wasn't active *" << endl;
00583       return noactive;
00584    }
00585 
00586    REROOT_Geom  *rgeo = gMINFast->GetREROOTGeom();
00587 
00588    const TClonesArray *planeposs   = rgeo->planeposs();
00589    REROOT_PlanePos    *planepos    = (REROOT_PlanePos*) planeposs->At(rpln_active);
00590    Int_t ispec = planepos->ActvSpec();
00591    const TClonesArray *planespecs  = rgeo->planespecs();
00592    REROOT_PlaneSpec   *planespec   = (REROOT_PlaneSpec*) planespecs->At(ispec);
00593 
00594    char rotm = planepos->Rotm()[0];
00595    switch (rotm) {
00596    case 'u':
00597    case 'U':
00598       plnid_view = PlaneView::kU;
00599       break;
00600    case 'v':
00601    case 'V':
00602       plnid_view = PlaneView::kV;
00603       break;
00604    case 'x':
00605    case 'X':
00606 // GMINOS "X" view corresponds to PlaneView::kY (strip # increase w/ "y")
00607       plnid_view = PlaneView::kY;
00608 // for CalDet map kY->kV
00609       if (GetDetector() == Detector::kCalDet) plnid_view = PlaneView::kV;
00610       break;
00611    case 'y':
00612    case 'Y':
00613 // GMINOS "Y" view corresponds to PlaneView::kX (strip # increase w/ "x")
00614       plnid_view = PlaneView::kX;
00615 // for CalDet map kX->kU
00616       if (GetDetector() == Detector::kCalDet) plnid_view = PlaneView::kU;
00617       break;
00618    case 'a':
00619    case 'A':
00620       plnid_view = PlaneView::kA;
00621       break;
00622    case 'b':
00623    case 'B':
00624       plnid_view = PlaneView::kB;
00625       break;
00626    default:
00627       MSG("Exodus",Msg::kWarning) << " Rotm '" << rotm 
00628                                   << "' not one of {U,V,X,Y,A,B} " << endl;
00629    }
00630 
00631    // plane names take form:
00632    // F6PL - far detector complete coverage
00633    // FUPL,FVPL - near detector "full" coverage
00634    // FRPL,FVPL - near detector "partial" coverage
00635    // test on *second* character
00636 
00637    switch (planespec->PlnName()[1]) {
00638    case '1':  // std far detector plane
00639    case '2':  // std far detector plane
00640    case '6':  // std far detector plane
00641       plnid_cover = PlaneCoverage::kComplete;
00642       break;
00643    case 'U':
00644    case 'V':
00645       plnid_cover = PlaneCoverage::kNearFull;
00646       break;
00647    case 'R':
00648    case 'S':
00649       plnid_cover = PlaneCoverage::kNearPartial;
00650       break;
00651    case '8':  // CalDet plane
00652    case 'X':  // CalDet plane  X orientation (for .fiberinfo)
00653    case 'Y':  // CalDet plane  Y orientation (for .fiberinfo)
00654    case 'A':  // CalDet plane
00655    case 'B':  // CalDet plane
00656    case 'C':  // CalDet plane  Cosmic counter on floor
00657       plnid_cover = PlaneCoverage::kComplete;
00658       break;
00659    default:
00660       MSG("Exodus",Msg::kWarning) 
00661          << " PlnName Key '" << planespec->PlnName()[1]
00662          << "' not one of {1,2,6,U,V,R,S,8,X,Y,A,B,C} " << endl;
00663    }
00664 
00665    return PlexPlaneId(GetDetector(),plnid_spln,!isactv,plnid_view,plnid_cover);
00666 
00667 }
00668 
00669 //_____________________________________________________________________________
00670 PlexStripEndId RerootExodus::PECAB2SEId(const Int_t rpln, const Int_t extru, const Int_t cell, const Int_t iab)
00671 {
00672    // Convert from GMINOS (Plane,Extrusion,Cell) numbering
00673    // to PlexStripEndId object
00674    // iab:  0=A, 1=B
00675 
00676    if (!gMINFast) {
00677       MSG("Exodus",Msg::kFatal) 
00678          << "PECAB2SEId lacked gMINFast" 
00679          << endl;
00680       return PlexStripEndId();
00681    }
00682    
00683 
00684    PlexPlaneId plnid = RerootPln2PlnId(rpln,kTRUE);
00685 
00686    // if bad plane number return before we do any damage
00687    if (PlaneCoverage::kUninstrumented == plnid.GetPlaneCoverage()) 
00688       return PlexStripEndId(plnid,0x255);
00689 
00690    REROOT_Geom  *rgeo = gMINFast->GetREROOTGeom();
00691 
00692    const TClonesArray *planeposs   = rgeo->planeposs();
00693    REROOT_PlanePos    *planepos    = (REROOT_PlanePos*) planeposs->At(rpln);
00694 
00695    // convert Extrusion+Cell into strip #
00696    // but don't count missing strips
00697 
00698    Int_t ispec = planepos->ActvSpec();
00699 
00700    const TClonesArray *planespecs  = rgeo->planespecs();
00701    REROOT_PlaneSpec   *planespec   = (REROOT_PlaneSpec*) planespecs->At(ispec);
00702 
00703    //   MSG("Exodus",Msg::kInfo) <<
00704    //      " PECAB2SEId pec " << plane << " " << extru << " " << cell <<
00705    //      " in " << planepos->ActvName() << " " << planespec->PlnName() << 
00706    //      endl;
00707 
00708    // determine end as kEast or kWest rather than A or B
00709    StripEnd::StripEnd_t   seid_end     = StripEnd::kUnknown;
00710 
00711    switch (plnid.GetPlaneView()) {
00712    case PlaneView::kU:
00713 //               0=A,1=B  true=B            false=A
00714       if (Detector::kCalDet != plnid.GetDetector()) 
00715          seid_end  = (iab) ? StripEnd::kWest : StripEnd::kEast;
00716       else  // caldet ...
00717          seid_end  = (iab) ? StripEnd::kDown : StripEnd::kUp;
00718       break;
00719    case PlaneView::kV:
00720 //               0=A,1=B  true=B            false=A
00721       if (Detector::kCalDet != plnid.GetDetector())
00722         // 'M' planes using 'W' rotation don't differ from kU mapping
00723         // but 'F' planes using 'V' rotation of funky 
00724        if ( planepos->Rotm()[0] == 'V' ) 
00725            seid_end  = (iab) ? StripEnd::kEast : StripEnd::kWest;
00726         else
00727            seid_end  = (iab) ? StripEnd::kWest : StripEnd::kEast;
00728       else // caldet ...
00729          seid_end  = (iab) ? StripEnd::kWest : StripEnd::kEast;
00730       break;
00731    case PlaneView::kY:
00732 //               0=A,1=B  true=B            false=A
00733       seid_end  = (iab) ? StripEnd::kWest : StripEnd::kEast;
00734       break;
00735    case PlaneView::kX:
00736 //               0=A,1=B  true=B            false=A
00737       seid_end  = (iab) ? StripEnd::kDown : StripEnd::kUp;
00738       break;
00739    case PlaneView::kA:
00740 //               0=A,1=B  true=B            false=A
00741       seid_end  = (iab) ? StripEnd::kWest : StripEnd::kEast;
00742       break;
00743    case PlaneView::kB:
00744 //               0=A,1=B  true=B            false=A
00745       seid_end  = (iab) ? StripEnd::kDown : StripEnd::kUp;
00746       break;
00747    default:
00748       MSG("Exodus",Msg::kWarning) 
00749          << " bad PlaneView '" << plnid.AsString() << endl;
00750    }
00751 
00752    StripEnd::StripEnd_t   seid_subpart = StripEnd::kWhole;
00753 
00754    // loop over the CellPos entries for this plane type
00755    // to determine the SEId strip #
00756    // skip strips that have no length (near detector)
00757    // count from top in the case of V planes so that increasing Y 
00758    // increases strip #
00759    const TClonesArray *cellposs   = rgeo->cellposs();
00760    REROOT_CellPos     *cellpos    = 0;
00761    
00762    Int_t seid_strip = 0;
00763 
00764    Int_t indx_beg, indx_end, indx_inc;
00765    if ( plnid.GetPlaneView() != PlaneView::kV || 
00766         plnid.GetDetector()  == Detector::kCalDet ) {
00767       indx_inc = 1;
00768       indx_beg = planespec->FirstStrip();
00769       indx_end = planespec->LastStrip() + indx_inc;
00770    } else {
00771       if ( planepos->Rotm()[0] == 'V' ) {
00772          // special case: V view flips counting side
00773          indx_inc = -1;
00774          indx_beg = planespec->LastStrip();
00775          indx_end = planespec->FirstStrip() + indx_inc;
00776       }
00777       else {
00778          // 'M' planes with 'W' rotation are regular
00779          indx_inc = 1;
00780          indx_beg = planespec->FirstStrip();
00781          indx_end = planespec->LastStrip() + indx_inc;
00782       }
00783    }
00784 
00785    //   MSG("Exodus",Msg::kInfo) << " cellpos range " << 
00786    //      indx_beg << " to " << indx_end << endl;
00787 
00788    for (Int_t i = indx_beg; i != indx_end; i += indx_inc) {
00789       cellpos = (REROOT_CellPos*) cellposs->At(i);
00790       Float_t length = cellpos->XYZReadout()[0] - 
00791                        cellpos->XYZFarend()[0];
00792       length = TMath::Abs(length);
00793       //      MSG("Exodus",Msg::kInfo) << 
00794       //         " look at " << i << " (" << seid_strip << ") " <<
00795       //         " EC " << cellpos->IExtr() << " " << cellpos->ICell() << 
00796       //         " length " << length << endl;
00797       if ( length > 0.0 ) {
00798          if ( cellpos->IExtr() == extru && cellpos->ICell() == cell ) break;
00799          // only increment if current one had non-zero length
00800          seid_strip++;
00801       }
00802       // not this one, move on to next in list
00803    }
00804    
00805    return PlexStripEndId(plnid,seid_strip,seid_end,seid_subpart);
00806                          
00807 }
00808 
00809 // Adpated from gminos/hits/PEC_pack.F.  bv@bnl.gov.  NOTE: this
00810 // assumes that plane, extru and cell are zero origin (ie, C index) as
00811 // returned by, eg, REROOT_FLSDigit::ID(). !!!
00812 int RerootExodus::PEC_pack(int plane, int extru, int cell)
00813 {
00814     plane += 1;                 // put them 
00815     extru += 1;                 // back in to 
00816     cell  += 1;                 // fortran order
00817 
00818     REROOT_Event *revt = gMINFast->GetREROOTEvent();
00819     const TClonesArray *gafkeys = revt->gafkeys();
00820     REROOT_GAFKey      *gafkey  = (REROOT_GAFKey*) gafkeys->At(0);
00821     int ver = gafkey->Version();
00822     if (ver >= 500) {
00823         return (plane<<16) | (extru<<8) | cell;
00824     }
00825     else {
00826         return cell + 1000*(extru + 1000*plane);
00827     }
00828     
00829 }
00830 void RerootExodus::PEC_unpack(int pec, int& plane, int& extru, int& cell)
00831 {
00832     plane = (pec&0xffff0000)>>16;
00833     extru = (pec&0xff00)>>8;
00834     cell = (pec&0xff);
00835 
00836     plane -= 1;                 // convert from
00837     extru -= 1;                 // fortran to
00838     cell -= 1;                  // C ordering
00839 }
00840 
00841 //_____________________________________________________________________________
00842 Int_t RerootExodus::NStripsNonZero(const Int_t rpln)
00843 {
00844    // Count the number of strips in a given plane
00845    // Exclude phantom strips that have zero length due to squashing
00846 
00847    if (rpln<0) return 0;
00848 
00849    if (!gMINFast) {
00850       MSG("Exodus",Msg::kFatal) 
00851          << "NStripSNonZero lacked gMINFast" 
00852          << endl;
00853       return 0;
00854    }
00855    
00856    REROOT_Geom  *rgeo = gMINFast->GetREROOTGeom();
00857 
00858    const TClonesArray *planeposs   = rgeo->planeposs();
00859    REROOT_PlanePos    *planepos    = (REROOT_PlanePos*) planeposs->At(rpln);
00860 
00861    Int_t ispec = planepos->ActvSpec();
00862 
00863    const TClonesArray *planespecs  = rgeo->planespecs();
00864    REROOT_PlaneSpec   *planespec   = (REROOT_PlaneSpec*) planespecs->At(ispec);
00865 
00866    Int_t indx_beg = planespec->FirstStrip();
00867    Int_t indx_end = planespec->LastStrip() + 1;
00868 
00869    const TClonesArray *cellposs   = rgeo->cellposs();
00870    REROOT_CellPos     *cellpos    = 0;
00871    
00872    Int_t nonzero = 0;
00873 
00874    for (Int_t i = indx_beg; i != indx_end; i++ ) {
00875       cellpos = (REROOT_CellPos*) cellposs->At(i);
00876       Float_t length = cellpos->XYZReadout()[0] - 
00877                        cellpos->XYZFarend()[0];
00878       length = TMath::Abs(length);
00879       if ( length > 0.0 ) nonzero++;
00880    }
00881 
00882    return nonzero;
00883 }
00884 
00885 //_____________________________________________________________________________
00886 REROOT_CellPos * RerootExodus::GetCellPos(const PlexStripEndId seid)
00887 {
00888    // get the CellPos entry corresponding to this PlexStripEndId
00889 
00890    if (!gMINFast) {
00891       MSG("Exodus",Msg::kFatal) 
00892          << "GetCellPos lacked gMINFast" 
00893          << endl;
00894       return 0;
00895    }
00896 
00897    int itry = 0;
00898    PlexStripEndId seid_try = seid;
00899  caldet_restart:
00900    
00901    REROOT_Geom   *rgeo = gMINFast->GetREROOTGeom();
00902 
00903    REROOT_PlanePos  *planepos  = GetPlanePos(seid_try);
00904    REROOT_PlaneSpec *planespec = GetPlaneSpec(seid_try);
00905 
00906    bool noinfo = (!planepos || !planespec);
00907    bool caldet0 =  (noinfo &&  seid.GetPlane() == 0 &&
00908                     seid.GetDetector() == Detector::kCalDet );
00909    // special case for CalDet ... PlexPlaneId expects a plane 0 active
00910    // it might not be there in REROOT
00911    if (caldet0 && itry==0) {
00912       // change the id for a second try
00913       seid_try.SetPlane(2);
00914       MSG("Ugli",Msg::kDebug) 
00915          << " fake CalDet plane 0 CellPos for strip " 
00916          << seid.GetStrip() << endl;
00917       itry++;
00918       goto caldet_restart;
00919    }
00920 
00921    if (noinfo) return 0;
00922 
00923    char rotm = planepos->Rotm()[0];
00924    Bool_t isV = (rotm == 'v') || (rotm == 'V');
00925 
00926    // loop over the CellPos entries for this plane type
00927    // to determine the SEId strip #
00928    // skip strips that have no length (near detector)
00929    // count from top in the case of V planes so that increasing Y 
00930    // increases strip #
00931    const TClonesArray *cellposs   = rgeo->cellposs();
00932    REROOT_CellPos     *cellpos    = 0;
00933    
00934    Int_t seid_strip    = 0;
00935    Int_t lookfor_strip = seid.GetStrip();
00936 
00937    Int_t indx_beg, indx_end, indx_inc;
00938    if ( ! isV ) {
00939       indx_inc = 1;
00940       indx_beg = planespec->FirstStrip();
00941       indx_end = planespec->LastStrip() + indx_inc;
00942    } else {
00943       indx_inc = -1;
00944       indx_beg = planespec->LastStrip();
00945       indx_end = planespec->FirstStrip() + indx_inc;
00946    }
00947 
00948    for (Int_t i = indx_beg; i != indx_end; i += indx_inc) {
00949       cellpos = (REROOT_CellPos*) cellposs->At(i);
00950       Float_t length = cellpos->XYZReadout()[0] - 
00951                        cellpos->XYZFarend()[0];
00952       length = TMath::Abs(length);
00953       //      MSG("Exodus",Msg::kInfo) << 
00954       //         " look at " << i << " (" << seid_strip << ") " <<
00955       //         " EC " << cellpos->IExtr() << " " << cellpos->ICell() << 
00956       //         " length " << length << endl;
00957       if ( length > 0.0 ) {
00958          if ( seid_strip == lookfor_strip) {
00959             return cellpos;
00960          }
00961          // only increment if current one had non-zero length
00962          seid_strip++;
00963       }
00964       // not this one, move on to next in list
00965    }
00966 
00967    MSG("Exodus",Msg::kDebug) <<
00968       "GetCellPos failed to find the strip " << seid.AsString() << endl;
00969    return 0;
00970 
00971 }
00972 
00973 //_____________________________________________________________________________
00974 REROOT_PlanePos * RerootExodus::GetPlanePos(const PlexPlaneId plnid)
00975 {
00976    // get the PlanePos entry corresponding to this PlexPlaneId
00977 
00978    if (!gMINFast) {
00979       MSG("Exodus",Msg::kFatal) 
00980          << "GetPlanePos lacked gMINFast" 
00981          << endl;
00982       return 0;
00983    }
00984    
00985    REROOT_Geom   *rgeo = gMINFast->GetREROOTGeom();
00986    
00987    Int_t rpln = SteelToRerootPlane(plnid.GetPlane(),!plnid.IsSteel());
00988    if (rpln<0) {
00989       MSG("Exodus",Msg::kDebug) 
00990          << "RerootExodus::GetPlanePos bad plnid " << plnid.AsString()
00991          << " ( rpln = " << rpln << " )" << endl;
00992       return 0;
00993    }
00994 
00995    const TClonesArray *planeposs  = rgeo->planeposs();
00996    REROOT_PlanePos    *planepos   = (REROOT_PlanePos*) planeposs->At(rpln);
00997 
00998    return planepos;
00999 }
01000 
01001 //_____________________________________________________________________________
01002 REROOT_PlaneSpec * RerootExodus::GetPlaneSpec(const PlexPlaneId plnid)
01003 {
01004    // get the PlaneSpec entry corresponding to this PlexPlaneId
01005 
01006    if (!gMINFast) {
01007       MSG("Exodus",Msg::kFatal) 
01008          << "GetPlaneSpec lacked gMINFast" 
01009          << endl;
01010       return 0;
01011    }
01012    
01013    REROOT_Geom     *rgeo     = gMINFast->GetREROOTGeom();
01014 
01015    REROOT_PlanePos *planepos = GetPlanePos(plnid);
01016    if (!planepos) return 0;
01017  
01018    Bool_t isactv = !plnid.IsSteel();
01019    Int_t ispec = (isactv) ? planepos->ActvSpec() : planepos->PasvSpec() ;
01020    const TClonesArray *planespecs  = rgeo->planespecs();
01021    REROOT_PlaneSpec   *planespec   = (REROOT_PlaneSpec*) planespecs->At(ispec);
01022 
01023    return planespec;
01024 }
01025 
01026 //_____________________________________________________________________________
01027 REROOT_Rotm * RerootExodus::GetRotm(const PlexPlaneId plnid)
01028 {
01029    // get the Rotm entry corresponding to this PlexPlaneId
01030 
01031    if (!gMINFast) {
01032       MSG("Exodus",Msg::kFatal) 
01033          << "GetRotm lacked gMINFast" 
01034          << endl;
01035       return 0;
01036    }
01037    
01038    REROOT_Geom     *rgeo     = gMINFast->GetREROOTGeom();
01039 
01040    REROOT_PlanePos *planepos = GetPlanePos(plnid);
01041    if (!planepos) return 0;
01042 
01043    Int_t irotm = planepos->RotmID();
01044    const TClonesArray *rotms  = rgeo->rotms();
01045    REROOT_Rotm        *rotm   = (REROOT_Rotm*) rotms->At(irotm);
01046 
01047    // only recorded Rotm is for *active* detector plane
01048    if (plnid.IsSteel()) {
01049       // search for X rotation matrix
01050       for (irotm=0; irotm<rotms->GetEntriesFast(); irotm++) {
01051          rotm   = (REROOT_Rotm*) rotms->At(irotm);
01052          if (!rotm) continue;
01053          if (rotm->Name()[0] == 'X') return rotm;
01054       }
01055       rotm = 0;  // not found?
01056    }
01057 
01058    return rotm;
01059 }
01060 
01061 //_____________________________________________________________________________
01062 TString RerootExodus::PlaneName(PlexPlaneId plnid)
01063 {
01064   // get the string name of the given plane 
01065 
01066    REROOT_PlanePos *planepos = GetPlanePos(plnid);
01067    if (!planepos) return "?Illegal";
01068    
01069    if (plnid.IsSteel()) return planepos->PasvName();
01070    else                 return planepos->ActvName();
01071 
01072 }
01073 
01074 //_____________________________________________________________________________
01075 Float_t RerootExodus::SEIdToTPos(const PlexStripEndId seid)
01076 {
01077    // convert from PlexStripEndId to a new-TPos position
01078    // "new" in the sense that V planes now have TPos going the other way
01079 
01080    if (!gMINFast) {
01081       static int nmsg = 10;
01082       if (nmsg) {
01083          MSG("Exodus",Msg::kFatal) 
01084             << "SEIdToTPos lacked gMINFast" 
01085             << endl;
01086          nmsg--;
01087          if (!nmsg) MSG("Exodus",Msg::kFatal) 
01088             << " ... last such message" << endl;
01089       }
01090       return 0;
01091    }
01092    
01093    REROOT_CellPos *cellpos = GetCellPos(seid);
01094    if (cellpos) {
01095       Float_t tpos = cellpos->XYZReadout()[1]; // tpos = unrotated "y"
01096       // V planes flip old version of tpos
01097       // except CalDet where kX->kU and kY->kV
01098       if (seid.GetDetector() == Detector::kCalDet || 
01099           cellpos->PlnName()[0] != 'F' ) {   // 'M' planes are regular
01100          return tpos;
01101       } else {
01102          return (seid.GetPlaneView() == PlaneView::kV) ? -tpos : tpos;
01103       }
01104    } else
01105       return -9999;
01106 
01107 }
01108 
01109 //_____________________________________________________________________________
01110 Float_t RerootExodus::SEIdToLPos(const PlexStripEndId seid)
01111 {
01112    // convert from PlexStripEndId to a new-LPos position
01113    // "new" in the sense that V planes now have TPos going the other way
01114 
01115    if (!gMINFast) {
01116       static int nmsg = 10;
01117       if (nmsg) {
01118          MSG("Exodus",Msg::kFatal) 
01119             << "SEIdToTPos lacked gMINFast" 
01120             << endl;
01121          nmsg--;
01122          if (!nmsg) MSG("Exodus",Msg::kFatal) 
01123             << " ... last such message" << endl;
01124       }
01125       return 0;
01126    }
01127    
01128    REROOT_CellPos *cellpos = GetCellPos(seid);
01129    if (cellpos) {
01130       Float_t lpos = 0.5 * (cellpos->XYZFarend()[0] + cellpos->XYZReadout()[0]);
01131       // V planes flip old version of tpos
01132       // except CalDet where kX->kU and kY->kV
01133       if (seid.GetDetector() == Detector::kCalDet ||
01134           cellpos->PlnName()[0] != 'F' ) {   // 'M' planes are regular
01135          return lpos;
01136       } else {
01137          return (seid.GetPlaneView() == PlaneView::kV) ? -lpos : lpos;
01138       }
01139    } else
01140       return -9999;
01141 
01142 }
01143 
01144 //_____________________________________________________________________________
01145 Float_t RerootExodus::SEIdHalfLength(const PlexStripEndId seid)
01146 {
01147    // convert from PlexStripEndId to a half length of strip
01148 
01149    if (!gMINFast) {
01150       MSG("Exodus",Msg::kFatal) 
01151          << "SEIdHalfLength lacked gMINFast" 
01152          << endl;
01153       return -1;
01154    }
01155    
01156    REROOT_CellPos *cellpos = GetCellPos(seid);
01157    if (cellpos) {
01158       Float_t length = cellpos->XYZReadout()[0] - 
01159                        cellpos->XYZFarend()[0];
01160       length = TMath::Abs(length);
01161       return length/2.0;
01162    } else
01163       return 0;
01164 
01165 }
01166 
01167 //_____________________________________________________________________________
01168 Float_t RerootExodus::SEIdHalfThickness(const PlexStripEndId seid)
01169 {
01170    // convert from PlexStripEndId to a half thickness of strip
01171 
01172    if (!gMINFast) {
01173       MSG("Exodus",Msg::kFatal) 
01174          << "SEIdHalfThickness lacked gMINFast" 
01175          << endl;
01176       return -1;
01177    }
01178       
01179    REROOT_PlaneSpec   *planespec   = GetPlaneSpec(seid);
01180    return 0.5*planespec->CellThick();
01181 
01182 }
01183 
01184 //_____________________________________________________________________________
01185 Float_t RerootExodus::SEIdHalfWidth(const PlexStripEndId seid)
01186 {
01187    // convert from PlexStripEndId to a half width of strip
01188 
01189    if (!gMINFast) {
01190       MSG("Exodus",Msg::kFatal) 
01191          << "SEIdHalfWidth lacked gMINFast" 
01192          << endl;
01193       return -1;
01194    }
01195    
01196    REROOT_PlaneSpec   *planespec   = GetPlaneSpec(seid);
01197    return 0.5*planespec->CellWidth();
01198 
01199 }
01200 
01201 //_____________________________________________________________________________
01202 TVector3 RerootExodus::SEIdLocalToGlobal(const PlexStripEndId seid,
01203                                          const TVector3& local_in)
01204 {
01205 
01206    if (!gMINFast) {
01207       MSG("Exodus",Msg::kFatal) 
01208          << "SEIdLocalToGlobal lacked gMINFast" 
01209          << endl;
01210       return TVector3(0.,0.,0.);
01211    }
01212 
01213    REROOT_CellPos   *cellpos   = GetCellPos(seid);
01214    REROOT_PlanePos  *planepos  = GetPlanePos(seid);
01215    REROOT_PlaneSpec *planespec = GetPlaneSpec(seid);
01216    REROOT_Rotm      *rotm      = GetRotm(seid);
01217 
01218    if ( !cellpos || !planepos || !planespec || !rotm ) {
01219       MSG("Exodus",Msg::kWarning)
01220          << "SEIdLocalToGlobal missing info: "
01221          << endl << seid.AsString()
01222          << " CellPos " << cellpos
01223          << " PlanePos " << planepos
01224          << " PlaneSpec " << planespec
01225          << " Rotm " << rotm
01226          << endl;
01227       return TVector3(0.,0.,0.);
01228    }
01229 
01230    // Transform local x from strip centered to plane centered
01231    // this is important for the chopped up near detector strips
01232    TVector3 local = local_in;
01233    Float_t xoff = 0.5*(cellpos->XYZFarend()[0]+cellpos->XYZReadout()[0]);
01234    local += TVector3(xoff,0.,0.);
01235 
01236    // "borrowed" from MINFFLS.cxx
01237    // code translated from xyz_cell2mars.F
01238 
01239    Float_t xyz_center[3];
01240    xyz_center[0] = planepos->XYActv()[0];
01241    xyz_center[1] = planepos->XYActv()[1];
01242    xyz_center[2] = planepos->ZFrntActv() + 0.5*planespec->Thickness();
01243 
01244    Float_t xyz_inplane[3];
01245    xyz_inplane[0] = local.X() + (cellpos->XYZCenter()[0]);
01246    xyz_inplane[1] = local.Y() + (cellpos->XYZCenter()[1]);
01247    xyz_inplane[2] = local.Z() + (cellpos->XYZCenter()[2]);
01248 
01249    Float_t XYZGlobal[3];
01250    XYZGlobal[0] = xyz_inplane[0]*rotm->r11() +
01251                   xyz_inplane[1]*rotm->r21() +
01252                   xyz_inplane[2]*rotm->r31() + xyz_center[0];
01253    XYZGlobal[1] = xyz_inplane[0]*rotm->r12() +
01254                   xyz_inplane[1]*rotm->r22() +
01255                   xyz_inplane[2]*rotm->r32() + xyz_center[1];
01256    XYZGlobal[2] = xyz_inplane[0]*rotm->r13() +
01257                   xyz_inplane[1]*rotm->r23() +
01258                   xyz_inplane[2]*rotm->r33() + xyz_center[2];
01259 
01260    return TVector3(XYZGlobal);
01261 }
01262 
01263 //_____________________________________________________________________________
01264 TVector3 RerootExodus::SEIdGlobalToLocal(const PlexStripEndId seid,
01265                                          const TVector3& global)
01266 {
01267 
01268    if (!gMINFast) {
01269       MSG("Exodus",Msg::kFatal) 
01270          << "SEIdGlobalToLocal lacked gMINFast" 
01271          << endl;
01272       return TVector3(0.,0.,0.);
01273    }
01274 
01275    REROOT_CellPos   *cellpos   = GetCellPos(seid);
01276    REROOT_PlanePos  *planepos  = GetPlanePos(seid);
01277    REROOT_PlaneSpec *planespec = GetPlaneSpec(seid);
01278    REROOT_Rotm      *rotm      = GetRotm(seid);
01279 
01280 
01281    // inverse of SEIdLocalToGlobal
01282    // code translated from xyz_mars2cell.F
01283 
01284    Float_t xyz_center[3];
01285    xyz_center[0] = planepos->XYActv()[0];
01286    xyz_center[1] = planepos->XYActv()[1];
01287    xyz_center[2] = planepos->ZFrntActv() + 0.5*planespec->Thickness();
01288 
01289    Float_t xyz_rotpln[3];
01290    xyz_rotpln[0] = global.X() - xyz_center[0];
01291    xyz_rotpln[1] = global.Y() - xyz_center[1];
01292    xyz_rotpln[2] = global.Z() - xyz_center[2];
01293 
01294    Float_t xyz_inpln[3];
01295    xyz_inpln[0] = xyz_rotpln[0]*rotm->r11() +
01296                   xyz_rotpln[1]*rotm->r12() +
01297                   xyz_rotpln[2]*rotm->r13();
01298    xyz_inpln[1] = xyz_rotpln[0]*rotm->r21() +
01299                   xyz_rotpln[1]*rotm->r22() +
01300                   xyz_rotpln[2]*rotm->r23();
01301    xyz_inpln[2] = xyz_rotpln[0]*rotm->r31() +
01302                   xyz_rotpln[1]*rotm->r32() +
01303                   xyz_rotpln[2]*rotm->r33();
01304 
01305    Float_t XYZLocal[3];
01306    XYZLocal[0] = xyz_inpln[0] - (cellpos->XYZCenter()[0]);
01307    XYZLocal[1] = xyz_inpln[1] - (cellpos->XYZCenter()[1]);
01308    XYZLocal[2] = xyz_inpln[2] - (cellpos->XYZCenter()[2]);
01309 
01310    return TVector3(XYZLocal);
01311 }
01312 
01313 //_____________________________________________________________________________
01314 Int_t RerootExodus::GetRunNo()
01315 {
01316    // return the current run #
01317 
01318    if (!gMINFast) {
01319       static int nmsg = 10;
01320       if (nmsg) {
01321          MSG("Exodus",Msg::kFatal) 
01322             << "GetRunNo lacked gMINFast" 
01323             << endl;
01324          nmsg--;
01325          if (!nmsg) MSG("Exodus",Msg::kFatal) 
01326             << " ... last such message" << endl;
01327       }
01328       return -1;
01329    }
01330 
01331    return gMINFast->GetHeader()->GetRun();
01332 
01333    //rwh: REROOT_Event *revt = gMINFast->GetREROOTEvent();
01334    //rwh: const TClonesArray *gafkeys = revt->gafkeys();
01335    //rwh: REROOT_GAFKey      *gafkey  = (REROOT_GAFKey*) gafkeys->At(0);
01336    //rwh: return gafkey->RunNo();
01337 }
01338 
01339 //_____________________________________________________________________________
01340 Int_t RerootExodus::GetEventNo()
01341 {
01342    // return the current event #
01343 
01344    if (!gMINFast) {
01345       static int nmsg = 10;
01346       if (nmsg) {
01347          MSG("Exodus",Msg::kFatal) 
01348             << "GetEventNo lacked gMINFast" 
01349             << endl;
01350          nmsg--;
01351          if (!nmsg) MSG("Exodus",Msg::kFatal) 
01352             << " ... last such message" << endl;
01353       }
01354       return -1;
01355    }
01356 
01357    return gMINFast->GetHeader()->GetEvent();
01358 
01359    //rwh: REROOT_Event *revt = gMINFast->GetREROOTEvent();
01360    //rwh: const TClonesArray *gafkeys = revt->gafkeys();
01361    //rwh: REROOT_GAFKey      *gafkey  = (REROOT_GAFKey*) gafkeys->At(0);
01362    //rwh: return gafkey->EventNo();
01363 }
01364 
01365 
01366 //_____________________________________________________________________________
01367 Int_t RerootExodus::GetEventRecord()
01368 {
01369    // return the current event record #
01370 
01371    if (!gMINFast) {
01372       MSG("Exodus",Msg::kFatal) 
01373          << "GetEventRecord lacked gMINFast" 
01374          << endl;
01375       return -1;
01376    }
01377 
01378    return gMINFast->GetHeader()->GetEventRecord();
01379 
01380 }
01381 
01382 //_____________________________________________________________________________
01383 const char * RerootExodus::GetRerootFileName()
01384 {
01385    // return the current reroot filename
01386 
01387    if (!gMINFast) {
01388       MSG("Exodus",Msg::kFatal) 
01389          << "GetRerootFileName lacked gMINFast" 
01390          << endl;
01391       return "no REROOT file";
01392    }
01393 
01394    const char* urlFile = 
01395      gMINFast->GetMINFile()->gettf()->GetEndpointUrl()->GetFile();
01396    return urlFile;
01397    //return gSystem->BaseName(urlFile);
01398 
01399 }
01400 
01401 //_____________________________________________________________________________
01402 REROOT_GeomMisc* RerootExodus::GetGeomMisc()
01403 {
01404 
01405    if (!gMINFast) {
01406       MSG("Exodus",Msg::kFatal) 
01407          << "GetGeomMisc lacked gMINFast" 
01408          << endl;
01409       return 0;
01410    }
01411 
01412    REROOT_Geom  *rgeo = gMINFast->GetREROOTGeom();
01413    //rwh:   REROOT_Event *revt = gMINFast->GetREROOTEvent();
01414 
01415    // we know that there is only one useful entry so return it not the list
01416    const TClonesArray *geommiscs    = rgeo->geommiscs();
01417    return (REROOT_GeomMisc*) geommiscs->At(0);
01418 
01419 }
01420 
01421 //_____________________________________________________________________________
01422 const TClonesArray* RerootExodus::GetFLSDigitList()
01423 {
01424 
01425    if (!gMINFast) {
01426       static int nmsg = 10;
01427       if (nmsg) {
01428          MSG("Exodus",Msg::kFatal) 
01429             << "GetFLSDigitList lacked gMINFast" 
01430             << endl;
01431          nmsg--;
01432          if (!nmsg) MSG("Exodus",Msg::kFatal) 
01433             << " ... last such message" << endl;
01434       }         
01435       return 0;
01436    }
01437 
01438    REROOT_Event *revt = gMINFast->GetREROOTEvent();
01439    return revt->flsdigits();
01440 
01441 }
01442 
01443 //_____________________________________________________________________________
01444 const TClonesArray* RerootExodus::GetFLSHitList()
01445 {
01446 
01447    if (!gMINFast) {
01448       MSG("Exodus",Msg::kFatal) 
01449          << "GetFLSHitList lacked gMINFast" 
01450          << endl;
01451       return 0;
01452    }
01453 
01454    REROOT_Event *revt = gMINFast->GetREROOTEvent();
01455    return revt->flshits();
01456 
01457 }
01458 
01459 //_____________________________________________________________________________
01460 const TClonesArray* RerootExodus::GetStdHepList()
01461 {
01462    if (!gMINFast) {
01463       MSG("Exodus",Msg::kFatal) 
01464          << "GetStdHepList lacked gMINFast" 
01465          << endl;
01466       return 0;
01467    }
01468 
01469    REROOT_Event *revt = gMINFast->GetREROOTEvent();
01470    return revt->stdheps();
01471 
01472 }
01473 
01474 //_____________________________________________________________________________
01475 const TClonesArray* RerootExodus::GetStdHepHeadList()
01476 {
01477    if (!gMINFast) {
01478       MSG("Exodus",Msg::kFatal) 
01479          << "GetStdHepHeadList lacked gMINFast" 
01480          << endl;
01481       return 0;
01482    }
01483 
01484    REROOT_Event *revt = gMINFast->GetREROOTEvent();
01485    return revt->stdhepheads();
01486 
01487 }
01488 
01489 //_____________________________________________________________________________
01490 const TClonesArray* RerootExodus::GetNeuKinList()
01491 {
01492 
01493    if (!gMINFast) {
01494       MSG("Exodus",Msg::kFatal) 
01495          << "GetNeuKinList lacked gMINFast" 
01496          << endl;
01497       return 0;
01498    }
01499 
01500    REROOT_Event *revt = gMINFast->GetREROOTEvent();
01501    return revt->neukins();
01502 
01503 }
01504 
01505 //_____________________________________________________________________________
01506 const TClonesArray* RerootExodus::GetNeuVtxList()
01507 {
01508    if (!gMINFast) {
01509       MSG("Exodus",Msg::kFatal) 
01510          << "GetNeuVtxList lacked gMINFast" 
01511          << endl;
01512       return 0;
01513    }
01514 
01515    REROOT_Event *revt = gMINFast->GetREROOTEvent();
01516    return revt->neuvtxs();
01517 
01518 }
01519 
01520 //_____________________________________________________________________________
01521 const TClonesArray* RerootExodus::GetFluxInfoList()
01522 {
01523    if (!gMINFast) {
01524       MSG("Exodus",Msg::kFatal) 
01525          << "GetFluxInfoList lacked gMINFast" 
01526          << endl;
01527       return 0;
01528    }
01529 
01530    REROOT_Event *revt = gMINFast->GetREROOTEvent();
01531    return revt->fluxinfos();
01532 
01533 }
01534 
01535 //_____________________________________________________________________________
01536 const TClonesArray* RerootExodus::GetFluxWgtList()
01537 {
01538    if (!gMINFast) {
01539       MSG("Exodus",Msg::kFatal) 
01540          << "GetFluxWgtList lacked gMINFast" 
01541          << endl;
01542       return 0;
01543    }
01544 
01545    REROOT_Event *revt = gMINFast->GetREROOTEvent();
01546    return revt->fluxwgts();
01547 
01548 }
01549 
01550 //_____________________________________________________________________________
01551 TString RerootExodus::ActvPlaneName(const Int_t rpln)
01552 {
01553    if (rpln<0) return TString("#nosuchplane");
01554 
01555    if (!gMINFast) {
01556       MSG("Exodus",Msg::kFatal) 
01557          << "GetActvPlaneName lacked gMINFast" 
01558          << endl;
01559       return TString("#nosuchplane");
01560    }
01561 
01562    REROOT_Geom  *rgeo = gMINFast->GetREROOTGeom();
01563 
01564    const TClonesArray *planeposs   = rgeo->planeposs();
01565    REROOT_PlanePos    *planepos    = (REROOT_PlanePos*) planeposs->At(rpln);
01566 
01567    return TString(planepos->ActvName());
01568 
01569 }
01570 
01571 //_____________________________________________________________________________
01572 TString RerootExodus::PasvPlaneName(const Int_t rpln)
01573 {
01574    if (rpln<0) return TString("#nosuchplane");
01575 
01576    if (!gMINFast) {
01577       MSG("Exodus",Msg::kFatal) 
01578          << "GetPasvPlaneName lacked gMINFast" 
01579          << endl;
01580       return TString("#nosuchplane");
01581    }
01582 
01583    REROOT_Geom  *rgeo = gMINFast->GetREROOTGeom();
01584 
01585    const TClonesArray *planeposs   = rgeo->planeposs();
01586    REROOT_PlanePos    *planepos    = (REROOT_PlanePos*) planeposs->At(rpln);
01587 
01588    return TString(planepos->PasvName());
01589 
01590 }
01591 
01592 //_____________________________________________________________________________
01593 Float_t RerootExodus::RerootPlaneZ0(PlexPlaneId plnid)
01594 {
01595    // return "z" of *center* of plane
01596 
01597    Float_t xyz[3];
01598    RerootPlaneXYZ0(plnid,xyz);
01599    return xyz[2];
01600 }
01601 
01602 //_____________________________________________________________________________
01603 void RerootExodus::RerootPlaneXYZ0(PlexPlaneId plnid, Float_t* xyz)
01604 {
01605    // return "xyz" of *center* of plane
01606 
01607    Bool_t isactv = ! plnid.IsSteel();
01608    Int_t rpln = SteelToRerootPlane(plnid.GetPlane(),isactv);
01609    RerootPlaneXYZ0(rpln,isactv,xyz);
01610 }
01611 
01612 //_____________________________________________________________________________
01613 void RerootExodus::RerootPlaneXYZ0(const Int_t rpln, const Bool_t isactv,
01614                                    Float_t* xyz)
01615 {
01616    // return "xyz" of *center* of plane
01617 
01618    if (rpln<0) {xyz[0]=xyz[1]=xyz[2]=0; return;}
01619 
01620    if (!gMINFast) {
01621       static int nmsg = 10;
01622       if (nmsg) {
01623          MSG("Exodus",Msg::kFatal) 
01624             << "GetRerootPlaneXYZ0 lacked gMINFast" 
01625             << endl;
01626          nmsg--;
01627          if (!nmsg) MSG("Exodus",Msg::kFatal) 
01628             << " ... last such message" << endl;
01629       }
01630       xyz[0]=xyz[1]=xyz[2]=0;
01631       return;
01632    }
01633 
01634    REROOT_Geom  *rgeo = gMINFast->GetREROOTGeom();
01635 
01636    const TClonesArray *planeposs   = rgeo->planeposs();
01637    REROOT_PlanePos    *planepos    = (REROOT_PlanePos*) planeposs->At(rpln);
01638 
01639    Int_t indx_spec = 0;
01640    const TClonesArray *planespecs  = rgeo->planespecs();
01641    REROOT_PlaneSpec   *planespec   = 0;
01642 
01643    if (isactv) {
01644       indx_spec = planepos->ActvSpec();
01645       planespec = (REROOT_PlaneSpec*) planespecs->At(indx_spec);
01646       xyz[0] = planepos->XYActv()[0];
01647       xyz[1] = planepos->XYActv()[1];
01648       xyz[2] = planepos->ZFrntActv() + 0.5*planespec->Thickness();
01649    } else {
01650       indx_spec = planepos->PasvSpec();
01651       planespec = (REROOT_PlaneSpec*) planespecs->At(indx_spec);
01652       xyz[0] = planepos->XYPasv()[0];
01653       xyz[1] = planepos->XYPasv()[1];
01654       xyz[2] = planepos->ZFrntPasv() + 0.5*planespec->Thickness();
01655    }
01656 
01657 }
01658 
01659 //_____________________________________________________________________________
01660 Int_t RerootExodus::RerootPlaneNo(const Float_t z)
01661 {
01662 
01663    // return Plane No. given a Z value
01664    // This is rather brute force
01665    // Returns the plane pair most downstream with zmin<z
01666    // (except in case of supermodule gaps)
01667 
01668    if (!gMINFast) {
01669       MSG("Exodus",Msg::kFatal) 
01670          << "GetRerootPlaneNo lacked gMINFast" 
01671          << endl;
01672       return 0;
01673    }
01674 
01675    REROOT_Geom  *rgeo = gMINFast->GetREROOTGeom();
01676 
01677    const TClonesArray *planeposs   = rgeo->planeposs();
01678 
01679    Int_t num_plns = rgeo->n_planeposs();
01680 
01681    //Int_t ipln = num_plns;
01682 
01683 //rwh:   for (Int_t i=0; i < num_plns; i++) {
01684    for (Int_t i=num_plns-1; i >= 0; i--) {
01685 
01686         REROOT_PlanePos *planepos = (REROOT_PlanePos*) planeposs->At(i);
01687 
01688 // ignore floor planes for CalDet (ROTM = A or B)
01689         if (planepos->Rotm()[0] == 'A' ||
01690             planepos->Rotm()[0] == 'B'    ) continue;
01691 
01692         Float_t zmin = planepos->PairZmin();
01693         Float_t zmax = planepos->PairZmax();
01694 //        Float_t zpasv = planepos->ZFrntPasv();
01695 //        Float_t zactv = planepos->ZFrntActv();
01696 
01697 //rwh: returns 9999 for supermodule gaps:
01698 //      if(z >= zmin && z < zmax ) ipln = i;
01699 
01700 //      assume list in ascending order in orginal array
01701 //      first one with z>=zmin
01702 
01703         // deal with supermodule gaps
01704         if (z >  zmax && i<num_plns-1) return i+1; 
01705 
01706         // normal pair
01707         if (z >= zmin) return i;
01708    }
01709 
01710 //rwh:   return ipln
01711    return 0;
01712 }
01713 
01714 //_____________________________________________________________________________
01715 VldTimeStamp RerootExodus::GetLastEventHistoryTimeStamp(bool dateonly)
01716 {
01717 
01718     // Determine when the event was created/modified
01719     // While this was a good idea it turns out that GMINOS used the
01720     // fortran "datime" routine and it appears my attempt to turn
01721     // it into a string munged with a Y2K problem
01722     // returning strings like "20  . 1.06  3:17" instead of "1999.11.08 13:42"
01723     // This is further compounded by REROOT_EventHistory's misguided
01724     // attempt to truncate the string by looking for the _first_ blank
01725     // (rather than noting the last non-blank place).
01726     
01727     // use run # to encode the "time" as a fake way of doing the
01728     // reverse of what one would usually do ( time --> run # )
01729     // stick it in the nanoseconds part
01730     
01731     Char_t  lastdate[17];
01732     const Char_t* origdate = "1970.01.01 00:00";
01733     Int_t   i;
01734     for (i=0; i<16; i++) lastdate[i] = ' '; lastdate[16] = '\0';
01735     
01736     REROOT_Event *revt = gMINFast->GetREROOTEvent();
01737     const TClonesArray  *eventhistorys  = revt->eventhistorys();
01738     REROOT_EventHistory *eh;
01739     TIter hiter(eventhistorys);
01740     while ( (eh = (REROOT_EventHistory*) hiter.Next() ) ) {
01741         //      strncpy(lastdate,eh->DateFilled(),16);
01742         origdate = eh->DateFilled();
01743         for (i=0; i<16; i++) {
01744             if (eh->DateFilled()[i] == '\0') break;
01745             lastdate[i] = eh->DateFilled()[i];
01746         }
01747     }
01748     
01749     // hack for mucked up date/time in REROOT_EventHistory
01750     if (lastdate[0]  == ' ') lastdate[0]  = '2';
01751     if (lastdate[1]  == ' ') lastdate[1]  = '0';
01752     if (lastdate[2]  == ' ') lastdate[2]  = '0';
01753     if (lastdate[3]  == ' ') lastdate[3]  = '0';
01754     if (lastdate[5]  == ' ') lastdate[4]  = '.';
01755     if (lastdate[5]  == ' ') lastdate[5]  = '0';
01756     if (lastdate[6]  == ' ') lastdate[6]  = '1';
01757     if (lastdate[7]  == ' ') lastdate[7]  = '.';
01758     if (lastdate[8]  == ' ') lastdate[8]  = '0';
01759     if (lastdate[9]  == ' ') lastdate[9]  = '1';
01760     if (lastdate[10] != ' ') lastdate[10] = ' ';
01761     if (lastdate[11] == ' ') lastdate[11] = '0';
01762     if (lastdate[12] == ' ') lastdate[12] = '0';
01763     if (lastdate[13] == ' ') lastdate[13] = ':';
01764     if (lastdate[14] == ' ') lastdate[14] = '0';
01765     if (lastdate[15] == ' ') lastdate[15] = '1';
01766     
01767     // attempt to interpret what's there ...
01768     Int_t year, month, day, hour, min, sec=0;
01769     sscanf(lastdate,"%4d.%2d.%2d %2d:%2d",&year,&month,&day,&hour,&min);
01770     
01771     // tests for mucked up date/time in REROOT_EventHistory
01772     Bool_t sensible = kTRUE;
01773     if ( month>12 || month<1 ) sensible = kFALSE;
01774     if (   day>31 ||   day<1 ) sensible = kFALSE;
01775     if (  hour>24 ||  hour<0 ) sensible = kFALSE;
01776     if (   min>60 ||   min<0 ) sensible = kFALSE;
01777     if (!sensible) {
01778         printf(" Report the following 3 lines to rhatcher@fnal.gov\n");
01779         printf(" eh->DateFilled() = \"%s\"\n",origdate);
01780         printf(" lastdate         = \"%s\"\n",lastdate);
01781         printf(" year %4d month %2d day %2d hour %2d min %2d sec %2d\n",
01782                year,month,day,hour,min,sec);
01783         if ( month>12 || month<1 ) month = 1;
01784         if (   day>31 ||   day<1 )   day = 1;
01785         if (  hour>24 ||  hour<0 )  hour = 0;
01786         if (   min>60 ||   min<0 )   min = 0;
01787     }
01788     
01789     if (dateonly) { hour = min = sec = 0; }
01790     
01791     return VldTimeStamp(year,month,day,hour,min,sec,0);
01792 }
01793 
01794 //_____________________________________________________________________________
01795 
01796 TString RerootExodus::GetGminosCodeName()
01797 {
01798     // The EventHistory table *might* have an entry signifying what
01799     // codename was given to a tagged version of GMINOS.
01800 
01801     TString codename("<<no-codename>>");
01802     
01803     REROOT_Event *revt = gMINFast->GetREROOTEvent();
01804     const TClonesArray  *eventhistorys  = revt->eventhistorys();
01805     REROOT_EventHistory *eh;
01806     TIter hiter(eventhistorys);
01807     while ( (eh = (REROOT_EventHistory*) hiter.Next() ) ) {
01808         TString keyname(eh->VersionString());
01809         if (keyname == "codename") {
01810           TString value(eh->Routine());
01811           codename = value;
01812           break;
01813         }
01814     }
01815 
01816     return codename;
01817 
01818 }
01819 
01820 //_____________________________________________________________________________
01821 
01822 TString RerootExodus::GetGminosHostName()
01823 {
01824     // The EventHistory table *might* have an entry signifying what
01825     // machine name (host) GMINOS was run on.
01826 
01827     TString hostname("<<no-hostname>>");
01828     
01829     REROOT_Event *revt = gMINFast->GetREROOTEvent();
01830     const TClonesArray  *eventhistorys  = revt->eventhistorys();
01831     REROOT_EventHistory *eh;
01832     TIter hiter(eventhistorys);
01833     while ( (eh = (REROOT_EventHistory*) hiter.Next() ) ) {
01834         TString keyname(eh->VersionString());
01835         if (keyname == "hostname") {
01836           TString value(eh->Routine());
01837           hostname = value;
01838           break;
01839         }
01840     }
01841 
01842     return hostname;
01843 
01844 }
01845 
01846 //_____________________________________________________________________________

Generated on Mon Feb 15 11:07:31 2010 for loon by  doxygen 1.3.9.1