Main Page | Namespace List | Class Hierarchy | Compound List | File List | Compound Members | File Members | Related Pages

TkrValsTool.cxx

Go to the documentation of this file.
00001 
00007 //#define PRE_CALMOD 1
00008 
00009 // To Do:
00010 // implement better code to check if in tower
00011 // Don't forget to remove the "1.5"s!! Done
00012 // xEdge and yEdge... Done
00013 
00014 // Include files
00015 
00016 
00017 #include "AnalysisNtuple/IValsTool.h"
00018 #include "ValBase.h"
00019 
00020 #include "GaudiKernel/MsgStream.h"
00021 #include "GaudiKernel/IDataProviderSvc.h"
00022 #include "GaudiKernel/SmartDataPtr.h"
00023 #include "GaudiKernel/AlgTool.h"
00024 #include "GaudiKernel/ToolFactory.h"
00025 
00026 #include "Event/TopLevel/EventModel.h"
00027 #include "Event/TopLevel/Event.h"
00028 
00029 #include "Event/Recon/TkrRecon/TkrCluster.h"
00030 #include "Event/Recon/TkrRecon/TkrTrack.h"
00031 #include "Event/Recon/TkrRecon/TkrVertex.h"
00032 #include "Event/Recon/CalRecon/CalEventEnergy.h"
00033 #include "geometry/Ray.h" 
00034 
00035 #include "GlastSvc/GlastDetSvc/IGlastDetSvc.h"
00036 #include "TkrUtil/ITkrGeometrySvc.h"
00037 #include "TkrUtil/ITkrQueryClustersTool.h"
00038 #include "TkrUtil/ITkrFlagHitsTool.h"
00039 
00040 #include "GlastSvc/Reco/IPropagatorSvc.h"
00041 #include "GaudiKernel/IToolSvc.h"
00042 #include "Doca.h"
00043 
00044 #include <cstring>
00045 
00046 
00047 // M_PI defined in ValBase.h
00048 
00055 class TkrValsTool :  public ValBase 
00056 {
00057 public:
00058 
00059     TkrValsTool( const std::string& type, 
00060         const std::string& name, 
00061         const IInterface* parent);
00062 
00063     virtual ~TkrValsTool() { }
00064 
00065     StatusCode initialize();
00066 
00067     StatusCode calculate();
00068 
00069 private:
00070 
00071     double towerEdge(Point pos) const;
00072     double containedFraction(Point pos, double gap, double r, 
00073         double costh, double phi) const;
00074     float SSDEvaluation(const Event::TkrTrack* track); 
00075 
00076     // some local constants
00077     double m_towerPitch;
00078     int    m_xNum;
00079     int    m_yNum;
00080     double m_activeWidth;
00081     bool   m_useNew;
00082     bool   m_enableVetoDiagnostics;
00083     int    m_messageCount;
00084 
00085     // Local variables to transfer results of SSD calculation
00086     float m_VetoPlaneCrossed; 
00087     float m_VetoTrials;
00088     float m_SSDVeto;
00089     float m_VetoUnknown;
00090     float m_VetoDeadPlane;
00091     float m_VetoTruncated; 
00092     float m_VetoTower;   
00093     float m_VetoGapCorner;
00094     float m_VetoGapEdge;   
00095     float m_VetoBadCluster;
00096     float m_VetoHitFound;
00097 
00098     // some pointers to services
00099 
00101     ITkrGeometrySvc*       m_tkrGeom;
00103     IGlastDetSvc*         m_detSvc; 
00105     ITkrQueryClustersTool* pQueryClusters;
00107     ITkrFlagHitsTool* pFlagHits;
00109     IPropagatorSvc* m_propSvc;
00110 
00111     IPropagator* m_G4PropTool; 
00113     IValsTool* m_pAcdTool;
00114 
00115     // properties
00116     double m_minVetoError;
00117     double m_maxVetoError;
00118     double m_vetoNSigma;
00119     bool   m_testExceptions;
00120 
00121 
00122     //Global Track Tuple Items
00123     float Tkr_Num_Tracks;
00124     float Tkr_Sum_KalEne; 
00125     float Tkr_Sum_ConEne;
00126     float Tkr_Energy;
00127     float Tkr_Energy_Corr;
00128     float Tkr_HDCount; 
00129     float Tkr_Total_Hits;
00130     float Tkr_Thin_Hits;
00131     float Tkr_Thick_Hits;
00132     float Tkr_Blank_Hits;  
00133     float Tkr_RadLength; 
00134     float Tkr_TwrEdge; 
00135     float Tkr_TrackLength;
00136     float Tkr_SurplusHitRatio;
00137     float Tkr_SurplusHCInside;
00138     float Tkr_UpstreamHC;
00139     float TkrDispersion;
00140 
00141     //First Track Specifics
00142     float Tkr_1_Chisq;
00143     float Tkr_1_FirstChisq;
00144     float Tkr_1_Gaps;
00145     float Tkr_1_FirstGapPlane; 
00146     float Tkr_1_GapX;
00147     float Tkr_1_GapY;
00148     float Tkr_1_FirstGaps; 
00149     float Tkr_1_Hits;
00150     float Tkr_1_FirstHits;
00151     float Tkr_1_FirstLayer; 
00152     float Tkr_1_LastLayer; 
00153 
00154     float Tkr_1_Qual;
00155     float Tkr_1_Type;
00156 
00157     float Tkr_1_DifHits;
00158     float Tkr_1_KalEne;
00159     float Tkr_1_ConEne;
00160     float Tkr_1_KalThetaMS;
00161     float Tkr_1_TwrEdge;
00162     float Tkr_1_PrjTwrEdge;
00163     float Tkr_1_DieEdge;
00164     float Tkr_1_TwrGap;
00165     float Tkr_1_xdir;
00166     float Tkr_1_ydir;
00167     float Tkr_1_zdir;
00168     float Tkr_1_Phi;
00169     float Tkr_1_Theta;
00170     float Tkr_1_x0;
00171     float Tkr_1_y0;
00172     float Tkr_1_z0;
00173     float Tkr_1_Sxx;
00174     float Tkr_1_Sxy;
00175     float Tkr_1_Syy;
00176     float Tkr_1_ThetaErr;
00177     float Tkr_1_PhiErr;
00178     float Tkr_1_ErrAsym;
00179     float Tkr_1_CovDet;
00180     float Tkr_1_ToTFirst;
00181     float Tkr_1_ToTAve;
00182     float Tkr_1_ToTTrAve;
00183     float Tkr_1_ToTAsym;
00184     float Tkr_1_ChisqAsym;
00185     float Tkr_1_SSDVeto; 
00186 
00187     // for SSDVeto Diagnostics
00188     int   Tkr_1_VetoTrials;
00189     int   Tkr_1_VetoHitFound;
00190     int   Tkr_1_VetoUnknown;
00191     int   Tkr_1_VetoPlaneCrossed;
00192     int   Tkr_1_VetoTower;
00193     int   Tkr_1_VetoGapCorner;
00194     //double Tkr_1_MinGapDistance;
00195     //double Tkr_1_MaxGapDistance;
00196     int   Tkr_1_VetoGapEdge;
00197     int   Tkr_1_VetoBadCluster;
00198     int   Tkr_1_VetoDeadPlane;
00199     int   Tkr_1_VetoTruncated;
00200 
00201     float Tkr_1_CoreHC;
00202     float Tkr_1_LATEdge;
00203 
00204     //Second Track Specifics
00205     float Tkr_2_Chisq;
00206     float Tkr_2_FirstChisq;
00207     float Tkr_2_FirstGaps; 
00208     float Tkr_2_Qual;
00209     float Tkr_2_Type;
00210     float Tkr_2_Hits;
00211     float Tkr_2_FirstHits;
00212     float Tkr_2_FirstLayer; 
00213     float Tkr_2_LastLayer; 
00214 
00215     float Tkr_2_Gaps;
00216     float Tkr_2_DifHits;
00217     float Tkr_2_KalEne;
00218     float Tkr_2_ConEne;
00219     float Tkr_2_KalThetaMS;
00220     float Tkr_2_TwrEdge;
00221     float Tkr_2_PrjTwrEdge;
00222     float Tkr_2_DieEdge;
00223     float Tkr_2_xdir;
00224     float Tkr_2_ydir;
00225     float Tkr_2_zdir;
00226     float Tkr_2_Phi;
00227     float Tkr_2_Theta;
00228     float Tkr_2_x0;
00229     float Tkr_2_y0;
00230     float Tkr_2_z0;
00231 
00232     float Tkr_2TkrAngle;
00233     float Tkr_2TkrHDoca;
00234 
00235     float Tkr_Veto_SSDVeto; 
00236     float Tkr_Veto_Chisq;
00237 
00238     float Tkr_Veto_Hits;
00239     float Tkr_Veto_FirstLayer;
00240 
00241     float Tkr_Veto_KalEne; 
00242     float Tkr_Veto_ConEne; 
00243 
00244     // here's some test stuff... if it works for a couple it will work for all
00245 
00246     /*
00247     float Tkr_float;
00248     int   Tkr_int;
00249     float    Tkr_1Pos[3];
00250     double   Tkr_doubles[2];
00251     int      Tkr_ints[5];
00252     unsigned int Tkr_uInts[7];
00253     char Tkr_string[20];
00254     */
00255 };
00256 
00257 namespace 
00258 {
00259     double interpolate ( double xi, double xmin, double xmax, 
00260         double ymin, double ymax) 
00261     {
00262         double step = (xi-xmin)/(xmax-xmin);
00263         return ymin + (ymax-ymin)*step;
00264     }
00265 
00266     int xPosIdx = Event::TkrTrackParams::xPosIdx;
00267     int yPosIdx = Event::TkrTrackParams::yPosIdx;
00268     int xSlpIdx = Event::TkrTrackParams::xSlpIdx;
00269     int ySlpIdx = Event::TkrTrackParams::ySlpIdx;
00270 
00271     const int    _badInt  =   -1;
00272     const float _badFloat = -2.0; 
00273 }
00274 
00275 // Static factory for instantiation of algtool objects
00276 static ToolFactory<TkrValsTool> s_factory;
00277 const IToolFactory& TkrValsToolFactory = s_factory;
00278 
00279 // Standard Constructor
00280 TkrValsTool::TkrValsTool(const std::string& type, 
00281                          const std::string& name, 
00282                          const IInterface* parent)
00283                          : ValBase( type, name, parent )
00284 {    
00285     // Declare additional interface
00286     declareInterface<IValsTool>(this);
00287 
00288     //declareProperty("useNew", m_useNew=true);
00289     // Old SSDVeto variable has been removed; always use "new" code
00290     m_useNew = true;
00291     declareProperty("enableVetoDiagnostics", m_enableVetoDiagnostics=false);
00292     declareProperty("minVetoError", m_minVetoError=1.0);
00293     declareProperty("maxVetoError", m_maxVetoError=100000.0);
00294     declareProperty("vetoNSigma", m_vetoNSigma=2.0);
00295     declareProperty("testExceptions", m_testExceptions=false);
00296 }
00297 
00593 StatusCode TkrValsTool::initialize()
00594 {
00595     StatusCode sc   = StatusCode::SUCCESS;
00596     StatusCode fail = StatusCode::FAILURE;
00597 
00598     MsgStream log(msgSvc(), name());
00599 
00600     log << MSG::INFO  << "#################" << endreq << "# ";
00601     log << (m_useNew ? "New " : "Old ");
00602     log << "version" << endreq << "#################" << endreq;
00603 
00604     if((ValBase::initialize()).isFailure()) return StatusCode::FAILURE;
00605 
00606     m_messageCount = 0;
00607 
00608     // get the services
00609 
00610     if( serviceLocator()) {
00611 
00612         if(service( "TkrGeometrySvc", m_tkrGeom, true ).isFailure()) {
00613             log << MSG::ERROR << "Could not find TkrGeometrySvc" << endreq;
00614             return fail;
00615         }
00616 
00617         m_towerPitch = m_tkrGeom->towerPitch();
00618         m_xNum       = m_tkrGeom->numXTowers();
00619         m_yNum       = m_tkrGeom->numYTowers();
00620         m_activeWidth = m_tkrGeom->nWaferAcross()*m_tkrGeom->waferPitch() + 
00621             (m_tkrGeom->nWaferAcross()-1)*m_tkrGeom->ladderGap();
00622 
00623         // find GlastDevSvc service
00624         if (service("GlastDetSvc", m_detSvc, true).isFailure()){
00625             log << MSG::ERROR << "Couldn't find the GlastDetSvc!" << endreq;
00626             return StatusCode::FAILURE;
00627         }
00628 
00629         IToolSvc* toolSvc = 0;
00630         if(service("ToolSvc", toolSvc, true).isFailure()) {
00631             log << MSG::ERROR << "Couldn't find the ToolSvc!" << endreq;
00632             return StatusCode::FAILURE;
00633         }
00634         if(!toolSvc->retrieveTool("G4PropagationTool", m_G4PropTool)) {
00635             log << MSG::ERROR << "Couldn't find the ToolSvc!" << endreq;
00636             return StatusCode::FAILURE;
00637         }
00638         m_pAcdTool = 0;
00639         sc = toolSvc->retrieveTool("AcdValsTool", m_pAcdTool);
00640         if( sc.isFailure() ) {
00641             log << MSG::ERROR << "Unable to find tool: " "AcdValsTool" << endreq;
00642             return sc;
00643         }
00644 
00645     } else {
00646         return fail;
00647     }
00648 
00649     if (toolSvc()->retrieveTool("TkrQueryClustersTool", pQueryClusters).isFailure()) {
00650         log << MSG::ERROR << "Couldn't retrieve TkrQueryClusterTool" << endreq;
00651         return fail;
00652     }
00653 
00654     if (toolSvc()->retrieveTool("TkrFlagHitsTool", pFlagHits).isFailure()) {
00655         log << MSG::ERROR << "Couldn't retrieve TkrFlagHitsTool" << endreq;
00656         return fail;
00657     }
00658 
00659     // load up the map
00660 
00661     addItem("TkrNumTracks",   &Tkr_Num_Tracks);
00662     addItem("TkrSumKalEne",   &Tkr_Sum_KalEne);
00663     addItem("TkrSumConEne",   &Tkr_Sum_ConEne);
00664     addItem("TkrEnergy",      &Tkr_Energy);
00665     addItem("TkrEnergyCorr",  &Tkr_Energy_Corr);
00666     addItem("TkrHDCount",     &Tkr_HDCount); 
00667     addItem("TkrTotalHits",   &Tkr_Total_Hits);
00668     addItem("TkrThinHits",    &Tkr_Thin_Hits);
00669     addItem("TkrThickHits",   &Tkr_Thick_Hits);
00670     addItem("TkrBlankHits",   &Tkr_Blank_Hits);
00671 
00672     addItem("TkrRadLength",   &Tkr_RadLength);
00673     addItem("TkrTwrEdge",     &Tkr_TwrEdge);
00674     addItem("TkrTrackLength", &Tkr_TrackLength);
00675     addItem("TkrSurplusHCInside", &Tkr_SurplusHCInside);
00676     addItem("TkrSurplusHitRatio", &Tkr_SurplusHitRatio);
00677     addItem("TkrUpstreamHC",  &Tkr_UpstreamHC);
00678     addItem("TkrDispersion", &TkrDispersion);
00679 
00680     addItem("Tkr1Chisq",      &Tkr_1_Chisq);
00681     addItem("Tkr1FirstChisq", &Tkr_1_FirstChisq);
00682     addItem("Tkr1Hits",       &Tkr_1_Hits);
00683     addItem("Tkr1FirstHits",  &Tkr_1_FirstHits);
00684     addItem("Tkr1FirstLayer", &Tkr_1_FirstLayer);
00685     addItem("Tkr1LastLayer",  &Tkr_1_LastLayer);
00686     addItem("Tkr1DifHits",    &Tkr_1_DifHits);
00687 
00688     addItem("Tkr1Gaps",       &Tkr_1_Gaps);
00689     addItem("Tkr1FirstGapPlane",&Tkr_1_FirstGapPlane);
00690     addItem("Tkr1XGap",       &Tkr_1_GapX);
00691     addItem("Tkr1YGap",       &Tkr_1_GapY);
00692     addItem("Tkr1FirstGaps",  &Tkr_1_FirstGaps);
00693 
00694     addItem("Tkr1Qual",       &Tkr_1_Qual);
00695     addItem("Tkr1Type",       &Tkr_1_Type);
00696     addItem("Tkr1TwrEdge",    &Tkr_1_TwrEdge);
00697     addItem("Tkr1PrjTwrEdge", &Tkr_1_PrjTwrEdge);
00698     addItem("Tkr1DieEdge",    &Tkr_1_DieEdge);
00699     addItem("Tkr1TwrGap",     &Tkr_1_TwrGap);
00700 
00701     addItem("Tkr1KalEne",     &Tkr_1_KalEne);
00702     addItem("Tkr1ConEne",     &Tkr_1_ConEne);
00703     addItem("Tkr1KalThetaMS", &Tkr_1_KalThetaMS);
00704 
00705     addItem("Tkr1XDir",       &Tkr_1_xdir);
00706     addItem("Tkr1YDir",       &Tkr_1_ydir);
00707     addItem("Tkr1ZDir",       &Tkr_1_zdir);
00708     addItem("Tkr1Phi",        &Tkr_1_Phi);
00709     addItem("Tkr1Theta",      &Tkr_1_Theta);
00710     addItem("Tkr1X0",         &Tkr_1_x0);
00711     addItem("Tkr1Y0",         &Tkr_1_y0);
00712     addItem("Tkr1Z0",         &Tkr_1_z0);
00713 
00714     addItem("Tkr1ThetaErr",   &Tkr_1_ThetaErr);
00715     addItem("Tkr1PhiErr",     &Tkr_1_PhiErr);
00716     addItem("Tkr1ErrAsym",    &Tkr_1_ErrAsym);
00717     addItem("Tkr1CovDet",     &Tkr_1_CovDet);
00718     addItem("Tkr1SXX",        &Tkr_1_Sxx);
00719     addItem("Tkr1SXY",        &Tkr_1_Sxy);
00720     addItem("Tkr1SYY",        &Tkr_1_Syy);
00721 
00722     addItem("Tkr1ToTFirst",   &Tkr_1_ToTFirst);
00723     addItem("Tkr1ToTAve",     &Tkr_1_ToTAve);
00724     addItem("Tkr1ToTTrAve",   &Tkr_1_ToTTrAve);
00725     addItem("Tkr1ToTAsym",    &Tkr_1_ToTAsym);
00726     addItem("Tkr1ChisqAsym",  &Tkr_1_ChisqAsym);
00727     addItem("Tkr1SSDVeto",    &Tkr_1_SSDVeto);
00728     addItem("TkrPlaneCrossed",  &Tkr_1_VetoPlaneCrossed);
00729 
00730     if(m_enableVetoDiagnostics) {
00731         addItem("TkrVetoHitFound",   &Tkr_1_VetoHitFound);
00732         addItem("TkrVetoTrials",     &Tkr_1_VetoTrials);
00733         addItem("TkrVetoUnknown",    &Tkr_1_VetoUnknown);
00734         addItem("TkrVetoTower",      &Tkr_1_VetoTower);
00735         addItem("TkrVetoGapCorner",  &Tkr_1_VetoGapCorner);
00736         //addItem("TkrMinGapDistance",  &Tkr_1_MinGapDistance);
00737         //addItem("TkrMaxGapDistance",  &Tkr_1_MaxGapDistance);
00738         addItem("TkrVetoGapEdge",    &Tkr_1_VetoGapEdge);
00739         addItem("TkrVetoBadCluster", &Tkr_1_VetoBadCluster);
00740         addItem("TkrVetoDeadPlane",  &Tkr_1_VetoDeadPlane);
00741         addItem("TkrVetoTruncated",  &Tkr_1_VetoTruncated);
00742     }
00743 
00744     addItem("Tkr1CoreHC",     &Tkr_1_CoreHC);
00745     addItem("Tkr1LATEdge",    &Tkr_1_LATEdge);
00746 
00747     addItem("Tkr2Chisq",      &Tkr_2_Chisq);
00748     addItem("Tkr2FirstChisq", &Tkr_2_FirstChisq);
00749 
00750     addItem("Tkr2Hits",       &Tkr_2_Hits);
00751     //    addItem("Tkr2FirstHits",  &Tkr_2_FirstHits);
00752     addItem("Tkr2FirstLayer", &Tkr_2_FirstLayer);
00753     addItem("Tkr2LastLayer",  &Tkr_2_LastLayer);
00754     //   addItem("Tkr2DifHits",    &Tkr_2_DifHits);
00755 
00756     //  addItem("Tkr2Gaps",       &Tkr_2_Gaps);
00757     //  addItem("Tkr2FirstGaps",  &Tkr_2_FirstGaps);
00758 
00759     addItem("Tkr2Qual",       &Tkr_2_Qual);
00760     addItem("Tkr2Type",       &Tkr_2_Type);
00761     addItem("Tkr2TwrEdge",    &Tkr_2_TwrEdge);
00762     addItem("Tkr2PrjTwrEdge", &Tkr_2_PrjTwrEdge);
00763     //  addItem("Tkr2DieEdge",    &Tkr_2_DieEdge);
00764 
00765     addItem("Tkr2KalEne",     &Tkr_2_KalEne);
00766     addItem("Tkr2ConEne",     &Tkr_2_ConEne);
00767     //  addItem("Tkr2KalThetaMS", &Tkr_2_KalThetaMS);
00768 
00769     //  addItem("Tkr2XDir",       &Tkr_2_xdir);
00770     //  addItem("Tkr2YDir",       &Tkr_2_ydir);
00771     //  addItem("Tkr2ZDir",       &Tkr_2_zdir);
00772     //  addItem("Tkr2Phi",        &Tkr_2_Phi);
00773     //  addItem("Tkr2Theta",      &Tkr_2_Theta);
00774     //  addItem("Tkr2X0",         &Tkr_2_x0);
00775     //  addItem("Tkr2Y0",         &Tkr_2_y0);
00776     //  addItem("Tkr2Z0",         &Tkr_2_z0);    
00777 
00778     addItem("Tkr2TkrAngle",   &Tkr_2TkrAngle); 
00779     addItem("Tkr2TkrHDoca",   &Tkr_2TkrHDoca); 
00780 
00781     addItem("TkrVSSDVeto",    &Tkr_Veto_SSDVeto); 
00782     addItem("TkrVChisq",      &Tkr_Veto_Chisq); 
00783 
00784     addItem("TkrVHits",       &Tkr_Veto_Hits); 
00785     addItem("TkrVFirstLayer", &Tkr_Veto_FirstLayer); 
00786     addItem("TkrVKalEne",     &Tkr_Veto_KalEne); 
00787     addItem("TkrVConEne",     &Tkr_Veto_ConEne); 
00788 
00789     // for test, uncomment these statements:
00790     /*
00791     addItem("TkrFloat", &Tkr_float);
00792     addItem("TkrInt",   &Tkr_int);
00793     //try just aliasing it to the first of the three items
00794     //  is it guaranteed to work?
00795     addItem("Tkr1Pos[3]",        &Tkr_1_x0);
00796     addItem("TkrIntArray[5]",    Tkr_ints);
00797     addItem("TkrDoubleArray[2]", Tkr_doubles);
00798     addItem("TkrUIntArray[7]",   Tkr_uInts);
00799     addItem("TkrString",           Tkr_string);
00800     */
00801 
00802     zeroVals();
00803 
00804     return sc;
00805 }
00806 
00807 namespace {
00808 
00809     // coefs from Miner
00810     double cfThin    = 0.68;  //Set overall value by slope at 1 GeV Verticle vs 1stLayerNumber
00811     double cfThick   = 2.93; // Set relative value to ratio of radiation lenghts 1 : 4.33.
00812     // cfThin is close to that derived via linear regression
00813     double rm_hard   = 30.; 
00814     double rm_soft   = 130;
00815     double gap       = 18.; 
00816     double hard_frac = .7; 
00817 
00818     double maxToTVal =  250.;  // won't be needed after new tag of TkrDigi
00819     double maxPath   = 2500.;  // limit the upward propagator
00820 
00821     // params for cone model
00822     double _eConeMin   = 30.;
00823     double _eConeBreak = 100.;
00824     double _eConeMax   = 1000.;
00825     double _coneAngleEMax= 2.65;
00826     double _coneAngleEBreak = 8.8;
00827     double _coneAngleEMin = 12.9;
00828     double _coneOffset    = 2.0;
00829     double _layerFactor   = 1.0;
00830     double _expCosth  = 1.5;
00831 
00832     //regions for various hit counts
00833     double _nearRegion     = 30.0;   // for TkrHDCount
00834     double _upstreamRegion = 150.0;  // for TkrUpstreamHC
00835     int    _nUpstream      = 4;      // max number of layers to look upstream
00836     double _coreRegion     = 10.0;   // for Tkr1CoreHC
00837     double _vetoRegion     = 10.0;   // for Tkr1SSDVeto
00838 }
00839 
00840 StatusCode TkrValsTool::calculate()
00841 {
00842     StatusCode sc = StatusCode::SUCCESS;
00843 
00844     MsgStream log(msgSvc(), name());
00845 
00846     //Tkr_float = 5.5;
00847     //Tkr_int   = 123;
00848 
00849     //offset comes from Geometry
00850     double z0 = m_tkrGeom->gettkrZBot();
00851 
00852     //special stuff here
00853     Tkr_1_FirstGapPlane = -1;
00854 
00855     double radThin  = m_tkrGeom->getAveConv(STANDARD); 
00856     double radThick = m_tkrGeom->getAveConv(SUPER); 
00857     double radTray  = m_tkrGeom->getAveRest(ALL);
00858 
00859     //Recover EventHeader Pointer
00860     //SmartDataPtr<Event::EventHeader> pEvent(m_pEventSvc, EventModel::EventHeader);
00861 
00862     // Recover Track associated info. 
00863     // NOTE: If no tracks are found ALL TKR variables are zero!  
00864     SmartDataPtr<Event::TkrTrackCol>   
00865         pTracks(m_pEventSvc,EventModel::TkrRecon::TkrTrackCol);
00866     if(!pTracks) return sc;
00867 
00868     SmartDataPtr<Event::TkrVertexCol>  
00869         pVerts(m_pEventSvc,EventModel::TkrRecon::TkrVertexCol);
00870     SmartDataPtr<Event::TkrClusterCol> 
00871         pClusters(m_pEventSvc,EventModel::TkrRecon::TkrClusterCol);
00872 
00873 
00874     // all variable values are preset to zero. 
00875     // Be sure to re-initialize the ones you care about  
00876 
00877     double die_width = m_tkrGeom->ladderPitch();
00878     int nDies = m_tkrGeom->nWaferAcross();
00879 
00880     if (pTracks){   
00881         // Count number of tracks
00882         int nTracks = pTracks->size();
00883         Tkr_Num_Tracks   = nTracks;
00884 
00885         if(nTracks < 1) return sc;
00886 
00887         // Get the first Track - it should be the "Best Track"
00888         Event::TkrTrackColConPtr pTrack = pTracks->begin();
00889 
00890         const Event::TkrTrack* track_1 = *pTrack;
00891 
00892         Tkr_1_Chisq        = track_1->getChiSquareSmooth();
00893         Tkr_1_FirstChisq   = track_1->chiSquareSegment();
00894         Tkr_1_FirstGaps    = track_1->getNumXFirstGaps() + track_1->getNumYFirstGaps();
00895         Tkr_1_Qual         = track_1->getQuality();
00896         Tkr_1_Type         = track_1->getStatusBits();
00897         Tkr_1_Hits         = track_1->getNumFitHits();
00898         Tkr_1_FirstHits    = track_1->getNumSegmentPoints();
00899         Tkr_1_FirstLayer   = m_tkrGeom->getLayer(track_1->front()->getTkrId());
00900         Tkr_1_LastLayer    = m_tkrGeom->getLayer(track_1->back()->getTkrId());
00901         Tkr_1_Gaps         = track_1->getNumGaps();
00902         Tkr_1_KalEne       = track_1->getKalEnergy(); 
00903         Tkr_1_ConEne       = track_1->getInitialEnergy(); 
00904         Tkr_1_KalThetaMS   = track_1->getKalThetaMS(); 
00905         Tkr_1_DifHits      = track_1->getNumXHits()-track_1->getNumYHits();
00906 
00907         Point  x1 = track_1->getInitialPosition();
00908         Vector t1 = track_1->getInitialDirection();
00909 
00910         Tkr_1_xdir        = t1.x();
00911         Tkr_1_ydir        = t1.y();
00912         Tkr_1_zdir        = t1.z();
00913 
00914         Tkr_1_x0          = x1.x();
00915         Tkr_1_y0          = x1.y();
00916         Tkr_1_z0          = x1.z();
00917 
00918         // theta and phi are of direction of source, hence the minus sign
00919         // this code replaces atan and acos used before
00920         Tkr_1_Phi         = (-t1).phi();
00921         if (Tkr_1_Phi<0.0f) Tkr_1_Phi += static_cast<float>(2*M_PI);
00922         Tkr_1_Theta       = (-t1).theta();
00923 
00924         const Event::TkrTrackParams& Tkr_1_Cov 
00925             = track_1->front()->getTrackParams(Event::TkrTrackHit::SMOOTHED);
00926         Tkr_1_Sxx         = Tkr_1_Cov.getxSlpxSlp();
00927         Tkr_1_Sxy         = Tkr_1_Cov.getxSlpySlp();
00928         Tkr_1_Syy         = Tkr_1_Cov.getySlpySlp();
00929         double sinPhi     = sin(Tkr_1_Phi);
00930         double cosPhi     = cos(Tkr_1_Phi);
00931         Tkr_1_ThetaErr    = t1.z()*t1.z()*sqrt(std::max(0.0, cosPhi*cosPhi*Tkr_1_Sxx + 
00932             2.*sinPhi*cosPhi*Tkr_1_Sxy + sinPhi*sinPhi*Tkr_1_Syy)); 
00933         Tkr_1_PhiErr        = (-t1.z())*sqrt(std::max(0.0, sinPhi*sinPhi*Tkr_1_Sxx - 
00934             2.*sinPhi*cosPhi*Tkr_1_Sxy + cosPhi*cosPhi*Tkr_1_Syy));
00935         Tkr_1_ErrAsym     = fabs(Tkr_1_Sxy/(Tkr_1_Sxx + Tkr_1_Syy));
00936         Tkr_1_CovDet = 
00937             sqrt(std::max(0.0f,Tkr_1_Sxx*Tkr_1_Syy-Tkr_1_Sxy*Tkr_1_Sxy))*
00938             Tkr_1_zdir*Tkr_1_zdir;
00939 
00940         Tkr_TrackLength = -(Tkr_1_z0-z0)/Tkr_1_zdir;
00941 
00942         double z_dist    = fabs((m_tkrGeom->trayHeight()+3.)/t1.z()); 
00943         double x_twr = globalToLocal(x1.x(), m_towerPitch, m_xNum);
00944         double y_twr = globalToLocal(x1.y(), m_towerPitch, m_yNum);
00945 
00946         double x_prj = x_twr - t1.x()*z_dist;
00947         double y_prj = y_twr - t1.y()*z_dist; 
00948 
00949         Tkr_1_TwrEdge    = (fabs(x_twr) > fabs(y_twr)) ? fabs(x_twr) : fabs(y_twr);
00950         Tkr_1_PrjTwrEdge = (fabs(x_prj) > fabs(y_prj)) ? fabs(x_prj) : fabs(y_prj);
00951         Tkr_1_TwrEdge    = m_towerPitch/2. - Tkr_1_TwrEdge;
00952         Tkr_1_PrjTwrEdge = m_towerPitch/2. - Tkr_1_PrjTwrEdge;
00953 
00954         // New section go compute gap lengths in tracker and cal
00955         double x_slope   = (fabs(t1.x()) > .0001)? t1.x():.00001;
00956         double s_x       = (sign(t1.x())*m_towerPitch/2. - x_twr)/x_slope; 
00957         double y_slope   = (fabs(t1.y()) > .0001)? t1.y():.00001;
00958         double s_y       = (sign(t1.y())*m_towerPitch/2. - y_twr)/y_slope;
00959 
00960         Tkr_1_TwrGap = 0.; 
00961         if(s_x < s_y) { // Goes out x side of CAL Module
00962             if(x1.z() - z0 + s_x*t1.z() > 0) {
00963                 double s_max = fabs((x1.z()-z0)/t1.z());
00964                 Tkr_1_TwrGap = gap/fabs(x_slope);
00965                 if((Tkr_1_TwrGap + s_x)> s_max ) Tkr_1_TwrGap = s_max-s_x;
00966             }
00967         }
00968         else {          // Goes out y side
00969             if(x1.z() - z0 + s_y*t1.z() > 0) {
00970                 double s_max = fabs((x1.z()-z0)/t1.z());
00971                 Tkr_1_TwrGap = gap/fabs(y_slope);
00972                 if((Tkr_1_TwrGap + s_y)> s_max ) Tkr_1_TwrGap = s_max-s_y;
00973             }
00974         }
00975 
00976         // SSD Die loaction and edge... 
00977         double x_die = globalToLocal(x_twr, die_width, nDies);
00978         double y_die = globalToLocal(y_twr, die_width, nDies);
00979 
00980 
00981         Tkr_1_DieEdge  = (fabs(x_die) > fabs(y_die)) ? fabs(x_die) : fabs(y_die);
00982         Tkr_1_DieEdge  = die_width/2. - Tkr_1_DieEdge; 
00983 
00984         // Section to dig out the TOT information
00985         double first_ToTs = 0.; 
00986         double last_ToTs  = 0.;
00987         double min_ToT   = 1000.; 
00988         double max_ToT   = -1000.;  
00989         int    hit_counter = 0; 
00990         double chisq_first = 0.;
00991         double chisq_last  = 0.; 
00992 
00993         Event::TkrTrackHitVecConItr pHit = track_1->begin();
00994 
00995         // loop over the hits to calculate various numbers
00996         double tkrTrackEnergy1 = 0, tkrTrackEnergy2 = 0;
00997         int plane = m_tkrGeom->getPlane((*pHit)->getTkrId());
00998         int gapId = -1;
00999         bool gapFound = false;
01000 
01001 
01002         // count the number of real hits... may not be necessary but I'm nervous!
01003         int clustersOnTrack = 0;
01004         while(pHit != track_1->end()) {
01005             const Event::TkrTrackHit* hit = *pHit++;
01006             unsigned int bits = hit->getStatusBits();
01007             if((bits & Event::TkrTrackHit::HITISSSD)==0) continue;
01008             const Event::TkrCluster* cluster = hit->getClusterPtr();
01009             double mips = cluster->getMips();
01010             if (mips<0.0 || mips>10.0) continue;
01011             clustersOnTrack++;
01012         }
01013 
01014         pHit = track_1->begin();
01015         const Event::TkrTrackParams params((*pHit)->getTrackParams(Event::TkrTrackHit::SMOOTHED));
01016         while(pHit != track_1->end()) {
01017             const Event::TkrTrackHit* hit = *pHit++;
01018             unsigned int bits = hit->getStatusBits();
01019 
01020             int layer = m_tkrGeom->getLayer(hit->getTkrId());
01021             convType type = m_tkrGeom->getLayerType(layer);
01022             if (type==STANDARD)   {tkrTrackEnergy1 += cfThin;}
01023             else if (type==SUPER) {tkrTrackEnergy1 += cfThick;}
01024 
01025             // check if hit is in an ssd
01026             if ( !gapFound && (bits & Event::TkrTrackHit::HITISSSD)==0) {
01027                 Point  gapPos = hit->getPoint(Event::TkrTrackHit::PREDICTED);
01028                 Tkr_1_GapX = gapPos.x();
01029                 Tkr_1_GapY = gapPos.y();
01030                 idents::TkrId tkrId = hit->getTkrId();
01031                 if(tkrId.hasTray()) {
01032                     gapId = m_tkrGeom->getPlane(hit->getTkrId());
01033                 } else {
01034                     gapId = plane;
01035                 }
01036                 gapFound = true;
01037             } else {
01038             }
01039             plane--;
01040             if ((bits & Event::TkrTrackHit::HITISSSD)==0) continue;
01041             const Event::TkrCluster* cluster = hit->getClusterPtr();
01042             int size =  (int) (const_cast<Event::TkrCluster*>(cluster))->size();
01043             // get the local slopes
01044             double slope  = fabs(hit->getMeasuredSlope(Event::TkrTrackHit::SMOOTHED));
01045             double slope1 = fabs(hit->getNonMeasuredSlope(Event::TkrTrackHit::SMOOTHED));
01046 
01047             // theta1 is the projected angle across the strip
01048             double theta1       = atan(slope1);
01049 
01050             double aspectRatio = 0.228/0.400;
01051             double totMax      =  250.;   // counts
01052             double threshold   =  0.25;   // Mips
01053             double countThreshold = 15; // counts
01054             double normFactor  =  1./53.;
01055 
01056             double mips = cluster->getMips();
01057             if(mips<0.0 || mips>10.0) continue;
01058 
01059             double tot = cluster->ToT();
01060             if(tot>=totMax) tot = totMax;
01061             double path1 = 1.0;
01062 
01063             // get the path length for the hit
01064             // tries to get the average
01065             // the calculation is part analytic, part approximation and part fudge.
01066             //   more work is definitely in order!
01067 
01068             // theta1 first
01069             if (tot>=totMax) { tot = normFactor*(totMax+countThreshold); }
01070             else {
01071                 double costh1 = cos(theta1);
01072                 if (size==1) {
01073                     double sinth1 = sin(theta1);
01074                     if (slope1< aspectRatio) {
01075                         path1 = (1./costh1*(aspectRatio-slope1) + 
01076                             (1/costh1 - 0.5*threshold)*(2*threshold*sinth1))
01077                             /(aspectRatio - slope1 + 2*threshold*sinth1);
01078                     } else if (slope1<aspectRatio/(1-2.*threshold*costh1)) {
01079                         path1 = 1; //1/costh1 - threshold*costh1;
01080                     } else { 
01081                         path1 = 1;
01082                     }
01083                 }
01084                 else if (size==2) {
01085                     if (slope1<aspectRatio/(1.-threshold*costh1)) {
01086                         path1 = 0.75/costh1 -0.5*threshold;
01087                     } else if (slope1<2.*aspectRatio/(1.-2*threshold*costh1)) { 
01088                         path1 = aspectRatio/sin(theta1);
01089                     } else {
01090                         path1 = 1.0;
01091                     }
01092                 } else {
01093                     if(slope1>aspectRatio/(1.- 2.*threshold*costh1)) {
01094                         path1 = aspectRatio/sin(theta1);
01095                     } else {
01096                         path1 = 1.0;
01097                     }
01098                 }
01099                 double factor = path1*costh1*slope;
01100                 double path2 = sqrt(path1*path1 + factor*factor);
01101                 mips /= path2;
01102             }
01103 
01104             if(mips > max_ToT) max_ToT = mips; 
01105             if(mips < min_ToT) min_ToT = mips; 
01106             hit_counter++;  
01107             if (hit_counter==1) Tkr_1_ToTFirst = mips;
01108             Tkr_1_ToTAve += mips;
01109             // first 2 valid clusters
01110             if(hit_counter < 3) {
01111                 first_ToTs += mips;
01112                 chisq_first += hit->getChiSquareSmooth();
01113             }
01114             // last 2 valid clusters
01115             if(hit_counter > clustersOnTrack-2){
01116                 last_ToTs += mips;
01117                 chisq_last += hit->getChiSquareSmooth();
01118             }
01119         }
01120 
01121         if(clustersOnTrack>3) {
01122             Tkr_1_ToTTrAve = (Tkr_1_ToTAve - max_ToT - min_ToT)/(clustersOnTrack-2.);
01123             Tkr_1_ToTAve /= clustersOnTrack;
01124             if(first_ToTs+last_ToTs>0) {
01125                 Tkr_1_ToTAsym = (last_ToTs - first_ToTs)/(first_ToTs + last_ToTs);
01126             }
01127         }
01128 
01129         tkrTrackEnergy1 /= fabs(Tkr_1_zdir);
01130 
01131 
01132         Tkr_1_FirstGapPlane = gapId; 
01133 
01134         // Chisq Asymmetry - Front vs Back ends of tracks
01135         if (chisq_last+chisq_first>0) Tkr_1_ChisqAsym = 
01136             (chisq_last - chisq_first)/(chisq_last + chisq_first);
01137 
01138 
01139         int firstPlane = m_tkrGeom->getPlane(track_1->front()->getTkrId()); 
01140         int firstLayer = m_tkrGeom->getLayer(firstPlane);
01141         double zFirstLayer = m_tkrGeom->getLayerZ(firstLayer);
01142 
01143         double costh = fabs(t1.z());
01144         double secth = 1./costh;
01145 
01146         // for the footprints
01147         double secthX = 1./sqrt(1.0 - t1.x()*t1.x());
01148         double secthY = 1./sqrt(1.0 - t1.y()*t1.y());
01149 
01150         double xVetoRgn = _vetoRegion*secthX;
01151         double yVetoRgn = _vetoRegion*secthY;
01152 
01153         // SSD Veto stuff here:
01154         // First Track stuff as before
01155         Tkr_1_SSDVeto = SSDEvaluation(track_1); 
01156 
01157         Tkr_1_VetoPlaneCrossed = m_VetoPlaneCrossed; 
01158         Tkr_1_VetoTrials = m_VetoTrials;
01159         Tkr_1_VetoUnknown = m_VetoUnknown;
01160         Tkr_1_VetoDeadPlane = m_VetoDeadPlane;
01161         Tkr_1_VetoTruncated = m_VetoTruncated; 
01162         Tkr_1_VetoTower = m_VetoTower;   
01163         Tkr_1_VetoGapCorner = m_VetoGapCorner;
01164         Tkr_1_VetoGapEdge = m_VetoGapEdge;   
01165         Tkr_1_VetoBadCluster = m_VetoBadCluster;
01166 
01167         int veto_track_num = -1;
01168         // Most likely track from AcdValsTool
01169         if(m_pAcdTool) {
01170             // check that Acd executes before Tkr
01171             if(m_loadOrder<m_pAcdTool->getLoadOrder()) {
01172                 if(m_messageCount<10) {
01173                     //std::cout << "TkrValsTool   WARNING "
01174                     log << MSG::WARNING
01175                         << "AcdValsTool needs to be loaded before TkrValsTool"
01176                         << endreq << " to calculate Veto Track quantities" 
01177                         << endreq;
01178                     m_messageCount++;
01179                     if(m_messageCount>=10) {
01180                         log << MSG::WARNING
01181                             << "Message suppressed after 10 warnings" << endreq;
01182                     }
01183                 }
01184             } else {
01185                 int firstCheck = m_check; 
01186                 if(m_pAcdTool->getVal("AcdActDistTrackNum", veto_track_num, 
01187                     firstCheck).isSuccess()) {
01188                         if(veto_track_num >= 0 && veto_track_num < Tkr_Num_Tracks) {
01189                             int n = veto_track_num;
01190                             const Event::TkrTrack* veto_track =  *(pTracks->begin()+n);
01191                             Tkr_Veto_SSDVeto    = SSDEvaluation(veto_track); 
01192                             Tkr_Veto_Chisq      = veto_track->getChiSquareSmooth();
01193 
01194                             Tkr_Veto_Hits       = veto_track->getNumFitHits();
01195                             Tkr_Veto_FirstLayer = 
01196                                 m_tkrGeom->getLayer(veto_track->front()->getTkrId());
01197 
01198                             Tkr_Veto_KalEne     = veto_track->getKalEnergy(); 
01199                             Tkr_Veto_ConEne     = veto_track->getInitialEnergy(); 
01200                         }
01201                     }
01202             }
01203         }
01204 
01205         // minimum distance from any edge, measured from the edge of the active area
01206         double deltaEdge = 0.5*(m_towerPitch - m_tkrGeom->trayWidth()) 
01207             - m_tkrGeom->siDeadDistance() ;
01208         double tkrXLo = m_tkrGeom->getLATLimit(0,LOW)  + deltaEdge;
01209         double tkrXHi = m_tkrGeom->getLATLimit(0,HIGH) - deltaEdge;
01210         double tkrYLo = m_tkrGeom->getLATLimit(1,LOW)  + deltaEdge;
01211         double tkrYHi = m_tkrGeom->getLATLimit(1,HIGH) - deltaEdge;
01212 
01213         double xEdge = std::min(Tkr_1_x0-tkrXLo, tkrXHi- Tkr_1_x0);
01214         double yEdge = std::min(Tkr_1_y0-tkrYLo, tkrYHi- Tkr_1_y0);
01215 
01216         Tkr_1_LATEdge = (float) std::min(xEdge, yEdge);
01217 
01218         if(nTracks > 1) {
01219             pTrack++;
01220 
01221             // try Bill's dispersion variable here
01222 
01223             Doca trk1Doca(x1, t1);
01224 
01225             Event::TkrTrackColConPtr trkIter;
01226 
01227             for(trkIter=pTrack; trkIter!=pTracks->end(); ++trkIter) {
01228                 Event::TkrTrack* trk = *trkIter;
01229                 double docaTrk = trk1Doca.docaOfPoint(trk->getInitialPosition());
01230                 TkrDispersion += (float) docaTrk*docaTrk;
01231                 double s = trk1Doca.arcLenRay1();
01232                 if (s<0) {
01233                     TkrDispersion += (float) s*s;
01234                 }
01235             }
01236             TkrDispersion = sqrt(TkrDispersion/(nTracks-1));
01237 
01238 
01239             const Event::TkrTrack* track_2 = *pTrack;
01240             Tkr_2_Chisq        = track_2->getChiSquareSmooth();
01241             Tkr_2_FirstChisq   = track_2->chiSquareSegment();
01242             Tkr_2_FirstGaps    = track_2->getNumXFirstGaps() + track_2->getNumYFirstGaps();
01243             Tkr_2_Qual         = track_2->getQuality();
01244             Tkr_2_Type         = track_2->getStatusBits();
01245             Tkr_2_Hits         = track_2->getNumFitHits();
01246             Tkr_2_FirstHits    = track_2->getNumSegmentPoints();
01247             Tkr_2_FirstLayer   = m_tkrGeom->getLayer(track_2->front()->getTkrId());
01248             Tkr_2_LastLayer    = m_tkrGeom->getLayer(track_2->back()->getTkrId());
01249             Tkr_2_Gaps         = track_2->getNumGaps();
01250             Tkr_2_KalEne       = track_2->getKalEnergy(); 
01251             Tkr_2_ConEne       = track_2->getInitialEnergy(); 
01252             Tkr_2_KalThetaMS   = track_2->getKalThetaMS(); 
01253             Tkr_2_DifHits      = track_2->getNumXHits()-track_2->getNumYHits();
01254 
01255             Point  x2 = track_2->getInitialPosition();
01256             Vector t2 = track_2->getInitialDirection();
01257             Tkr_2_xdir       = t2.x();
01258             Tkr_2_ydir       = t2.y();
01259             Tkr_2_zdir       = t2.z();
01260 
01261             // this replaces atan used before
01262             Tkr_2_Phi         = (-t2).phi();
01263             if (Tkr_2_Phi<0.0) Tkr_2_Phi += static_cast<float>(2*M_PI);
01264             Tkr_2_Theta       = (-t2).theta();
01265 
01266             Tkr_2_x0         = x2.x();
01267             Tkr_2_y0         = x2.y();
01268             Tkr_2_z0         = x2.z();
01269 
01270             double x_twr = globalToLocal(x2.x(), m_towerPitch, m_xNum);
01271             double y_twr = globalToLocal(x2.y(), m_towerPitch, m_yNum);
01272             double x_prj = x_twr - t2.x()*z_dist;
01273             double y_prj = y_twr - t2.y()*z_dist; 
01274 
01275             Tkr_2_TwrEdge    = (fabs(x_twr) > fabs(y_twr)) ? fabs(x_twr) : fabs(y_twr);
01276             Tkr_2_PrjTwrEdge = (fabs(x_prj) > fabs(y_prj)) ? fabs(x_prj) : fabs(y_prj);
01277             Tkr_2_TwrEdge    = m_towerPitch/2. - Tkr_2_TwrEdge;
01278             Tkr_2_PrjTwrEdge = m_towerPitch/2. - Tkr_2_PrjTwrEdge;
01279 
01280             double x_die = globalToLocal(x_twr, die_width, nDies);
01281             double y_die = globalToLocal(y_twr, die_width, nDies);
01282 
01283             Tkr_2_DieEdge  = (fabs(x_die) > fabs(y_die)) ? fabs(x_die) : fabs(y_die);
01284             Tkr_2_DieEdge  = die_width/2. - Tkr_2_DieEdge; 
01285 
01286             Tkr_2TkrAngle = acos(t1*t2);  
01287             Point x2p  = x2 + ((x1.z()-x2.z())/t2.z())*t2;
01288             Point x20  = x2 - (x2.z()/t2.z())*t2;
01289             Point x10  = x1 - (x1.z()/t1.z())*t1;
01290             double doca_plane = (x2p-x1).mag();
01291             double doca_0     = (x20-x10).mag();
01292             if(doca_plane > doca_0) Tkr_2TkrAngle *= -1.; 
01293             Tkr_2TkrHDoca = -doca_plane*t1.z();
01294 
01295             Event::TkrTrackHitVecConItr pHit = track_2->begin();
01296 
01297             // count up the hits for track energy
01298             while(pHit != track_2->end()) {
01299                 const Event::TkrTrackHit* hit = *pHit++;
01300 
01301                 int layer = m_tkrGeom->getLayer(hit->getTkrId());
01302                 convType type = m_tkrGeom->getLayerType(layer);
01303                 if (type==STANDARD)   {tkrTrackEnergy2 += cfThin;}
01304                 else if (type==SUPER) {tkrTrackEnergy2 += cfThick;}
01305             }
01306             tkrTrackEnergy2 /= fabs(Tkr_2_zdir);
01307         }
01308 
01309         Tkr_Sum_KalEne    = Tkr_1_KalEne+Tkr_2_KalEne; 
01310         Tkr_Sum_ConEne    = Tkr_1_ConEne+Tkr_2_ConEne;      
01311 
01312         double tkrTrackEnergy = tkrTrackEnergy1 + tkrTrackEnergy2;
01313 
01314         // Computation of the tracker contribution to the total energy 
01315         double arc_min = (x1.z() - m_tkrGeom->calZTop())*secth; 
01316 
01317 
01318         double z_present = x1.z();
01319 
01320         // Compute the sum-of radiation_lengths x Hits in each layer
01321         //double tracker_ene_corr = 0.; 
01322         double rad_len_sum  = 0.; 
01323         double radlen       = 0.;
01324         double radlen_old   = 0.; 
01325         double arc_len      = 0.; 
01326         int    total_hits   = 0; 
01327         int    thin_hits    = 0;
01328         int    thick_hits   = 0; 
01329         int    blank_hits   = 0; 
01330         double ave_edge     = 0.; 
01331 
01332         //float surplus_in = 0;
01333         //float total_layer_hits = 0;
01334         int numTowers = m_xNum*m_yNum;
01335         std::vector<float> layerInCount(numTowers,0.0);
01336         std::vector<float> layerOutCount(numTowers,0.0);
01337 
01338         // do the hit counts
01339         // Tkr_HDCount
01340 
01341         double xNearRgn = _nearRegion*secthX;
01342         double yNearRgn = _nearRegion*secthY;
01343 
01344         Tkr_HDCount = pQueryClusters->numberOfUUHitsNear((int) Tkr_1_FirstLayer, 
01345             xNearRgn, yNearRgn, x1);
01346 
01347         // Tkr1CoreHC:
01348 
01349         double xCoreRgn = _coreRegion*secthX;
01350         double yCoreRgn = _coreRegion*secthY;
01351 
01352         int numLayers = m_tkrGeom->numLayers();
01353 
01354         Event::TkrTrackHitVecConItr hitIter = track_1->begin();
01355         for(;hitIter!=track_1->end(); ++hitIter) {
01356             const Event::TkrTrackHit* thisHit = *hitIter;
01357             idents::TkrId thisId = thisHit->getTkrId();
01358             int thisPlane = m_tkrGeom->getPlane(thisId);
01359             int thisLayer = m_tkrGeom->getLayer(thisPlane);
01360             int thisView  = thisId.getView();
01361             Point pos;
01362             if(thisHit->validMeasuredHit()) {
01363                 pos  = thisHit->getPoint(Event::TkrTrackHit::MEASURED);
01364             } else if(thisHit->validFilteredHit()) {
01365                 pos  = thisHit->getPoint(Event::TkrTrackHit::FILTERED);
01366             } else { continue; }
01367 
01368             double distance = (thisView==0 ? xCoreRgn : yCoreRgn);
01369             int coreHits = pQueryClusters->numberOfHitsNear(thisView, thisLayer,
01370                 distance, pos);
01371             if (thisHit->validCluster()) coreHits--;
01372             Tkr_1_CoreHC += coreHits;
01373         }
01374 
01375         //TkrUpstreamHC
01376 
01377         int topLayer  = numLayers - 1;
01378         int layer    = firstLayer+1;
01379         int upperLayer = std::min(firstLayer+_nUpstream, topLayer);
01380         double xUpstreamRgn = _upstreamRegion*secthX;
01381         double yUpstreamRgn = _upstreamRegion*secthY;
01382 
01383         for(; layer<=upperLayer; ++layer) {
01384             double zLayer = m_tkrGeom->getLayerZ(layer);
01385             double deltaZ = zFirstLayer - zLayer;
01386             double arcLength = deltaZ*secth;
01387             Point x_hit = x1 + arcLength*t1;
01388             Tkr_UpstreamHC += pQueryClusters->numberOfHitsNear(layer, 
01389                 xUpstreamRgn, yUpstreamRgn, x_hit, t1);       
01390         }
01391 
01392         // Surplus hits
01393 
01394         double tanth = (1.0-costh*costh)*secth;
01395         double spread0 = _coneOffset + _layerFactor*tanth;
01396         double cosFactor = pow(secth, _expCosth);
01397 
01398         float Tkr_SurplusHCOutside = 0.0f;
01399         //float Tkr_SurplusHCInside  = 0.0f;
01400         //float Tkr_Total_Hits = 0.0f;
01401 
01402         // hate to do this, but we need ERecon
01403         // Recover pointer to CalEventEnergy info 
01404         double CAL_EnergyCorr = 0.0;
01405 #ifdef PRE_CALMOD
01406         Event::CalEventEnergy* calEventEnergy = 
01407             SmartDataPtr<Event::CalEventEnergy>(m_pEventSvc, EventModel::CalRecon::CalEventEnergy);
01408 #else
01409         Event::CalEventEnergyCol * calEventEnergyCol = 
01410             SmartDataPtr<Event::CalEventEnergyCol>(m_pEventSvc, EventModel::CalRecon::CalEventEnergyCol);
01411         Event::CalEventEnergy * calEventEnergy = 0 ;
01412         if ((calEventEnergyCol!=0)&&(!calEventEnergyCol->empty()))
01413             calEventEnergy = calEventEnergyCol->front() ;
01414 #endif
01415         if (calEventEnergy != 0) {
01416             // Extraction of results from CalValCorrTool in CalRecon... 
01417             Event::CalCorToolResultCol::iterator corIter = calEventEnergy->begin();
01418             for(;corIter != calEventEnergy->end(); corIter++){
01419                 Event::CalCorToolResult corResult = **corIter;
01420                 if (corResult.getCorrectionName() == "CalValsCorrTool") {
01421                     CAL_EnergyCorr   = corResult["CorrectedEnergy"];
01422                 }
01423             }
01424         }
01425 
01426         double eRecon = CAL_EnergyCorr + tkrTrackEnergy;
01427         double eCone = std::min(_eConeMax, std::max(eRecon, _eConeMin));
01428         // Get the basic cone angle for this Energy
01429         double coneAngle;
01430         if (eCone<_eConeBreak) {
01431             coneAngle = interpolate(1.0/eCone, 1.0/_eConeMin, 1.0/_eConeBreak, 
01432                 _coneAngleEMin, _coneAngleEBreak);
01433         } else {
01434             coneAngle = interpolate(1./eCone, 1./_eConeBreak, 1.0/_eConeMax, 
01435                 _coneAngleEBreak, _coneAngleEMax);
01436         }
01437 
01438         double xSprd0 = coneAngle*secthX*cosFactor;
01439         double ySprd0 = coneAngle*secthY*cosFactor;
01440 
01441         bool goodProp = true;
01442 
01443         try {
01444             m_G4PropTool->setStepStart(x1, t1);
01445             m_G4PropTool->step(arc_min);
01446         } catch( std::exception& /*e*/) {
01447             printHeader(log);
01448             setAnaTupBit();
01449             log << "See previous exception message." << endreq;
01450             log << " Skipping the TKR total-energy calculations" << endreq;
01451             goodProp = false;
01452         } catch (...) {
01453             printHeader(log);
01454             setAnaTupBit();
01455             log << "Unknown exception, see previous exception message, if any" << endreq;
01456             log << "Skipping the TKR total-energy calculations" << endreq;
01457             log << "Initial track parameters: pos: " << x1 << endreq 
01458                 << "dir: " << t1 << " arclen: " << arc_min << endreq;
01459             goodProp = false;
01460         }
01461 
01462 
01463         if(goodProp) {
01464             for(layer = firstLayer; layer>=0; --layer) {
01465 
01466                 if(layer <firstLayer) {
01467                     radlen = m_G4PropTool->getRadLength(arc_len); 
01468                 }
01469 
01470                 // Assume location of shower center is given by 1st track
01471 
01472                 // try to get actual x and y (accounting for the differences in z)
01473                 double zX = m_tkrGeom->getLayerZ(layer, 0);
01474                 double zY = m_tkrGeom->getLayerZ(layer, 1);
01475                 double zAve = 0.5*(zX + zY);
01476                 double arcLenX = (x1.z() - zX)*secth;
01477                 double arcLenY = (x1.z() - zY)*secth;
01478 
01479                 double x_hitX = x1.x() + arcLenX*t1.x();
01480                 double x_hitY = x1.y() + arcLenY*t1.y();
01481                 Point x_hit1(x_hitX, x_hitY, zAve);
01482                 // whew!!
01483 
01484                 int hitXTower, hitYTower;
01485                 m_tkrGeom->truncateCoord(x_hit1.x(), m_towerPitch, m_xNum, hitXTower);
01486                 m_tkrGeom->truncateCoord(x_hit1.y(), m_towerPitch, m_yNum, hitYTower);
01487                 int thisTower = idents::TowerId(hitXTower, hitYTower).id();
01488 
01489                 Point x_hit = x1 + arc_len*t1;
01490 
01491                 // trial code for Surplus hits
01492 
01493                 layerInCount.assign(numTowers,0);
01494                 layerOutCount.assign(numTowers, 0);
01495 
01496                 Event::TkrClusterVec clusVec[2];
01497                 int tower;
01498                 std::vector<int> clusCount[2];
01499                 clusCount[0].assign(numTowers,0);
01500                 clusCount[1].assign(numTowers,0);
01501                 int view;
01502                 // fpr each layer, count the clusters in each tower, view
01503                 for (view=0; view<2; ++view) {
01504                     clusVec[view] = pQueryClusters->getClusters(view, layer);
01505                     //std::cout << clusVec[view].size() << std::endl;
01506                     Event::TkrClusterVecConItr iter = clusVec[view].begin();
01507                     for(;iter!=clusVec[view].end(); ++iter) {
01508                         idents::TkrId id = (*iter)->getTkrId();
01509                         tower = idents::TowerId(id.getTowerX(), id.getTowerY()).id();
01510                         clusCount[view][tower]++;
01511                         //std::cout << "count, " << tower << " " << view << ": " 
01512                         //    << clusCount[view][tower] << std::endl;
01513                     }
01514                 }
01515 
01516                 // form the x-y coincidence
01517                 std::vector<bool> isXY(numTowers, false);
01518                 for (tower=0;tower<numTowers; ++ tower) {
01519                     isXY[tower] = (clusCount[0][tower]>0 && clusCount[1][tower]>0);
01520                     //std::cout << "tower " << tower << ", " << clusCount[0][tower] 
01521                     //    << " " << clusCount[1][tower] << ", " << isXY[tower] << std::endl;
01522                 }
01523                 // make sure *this* tower is included!
01524                 isXY[thisTower] = true;
01525 
01526                 float factor;
01527 
01528                 double xSprd = spread0 + xSprd0*(firstLayer-layer);
01529                 double ySprd = spread0 + ySprd0*(firstLayer-layer);
01530 
01531                 // test each cluster in surviving towers
01532                 int mode = 0;
01533                 if (mode==0) {
01534                     factor = 1.0;
01535                     for (view=0; view<2; ++view) {
01536                         Event::TkrClusterVecConItr iter = clusVec[view].begin();
01537                         for(;iter!=clusVec[view].end(); ++iter) {
01538                             idents::TkrId id = (*iter)->getTkrId();
01539                             tower = idents::TowerId(id.getTowerX(), id.getTowerY()).id();
01540                             if(!isXY[tower]) continue;
01541                             Vector diff = x_hit1 - (*iter)->position();
01542                             bool in;
01543                             // replace with current definition of "in"
01544                             if(view==0) {
01545                                 in = (fabs(diff.x())<=xSprd && (fabs(diff.y())-ySprd<0.5*m_activeWidth));
01546                             } else { 
01547                                 in = (fabs(diff.y())<=ySprd && (fabs(diff.x())-xSprd<0.5*m_activeWidth));
01548                             }
01549                             if (in) {layerInCount[tower]  += 1.0f;}
01550                             else    {layerOutCount[tower] += 1.0f;}
01551                         }
01552                     }
01553                 } 
01554                 /*
01555                 // first attempt at code that uses TkrPoint-like objects... needs lots more work!!
01556                 else if (mode==1) {
01557                 double xDenom = 1./xSprd/xSprd;
01558                 double yDenom = 1./ySprd/ySprd;
01559                 Event::TkrClusterVecConItr iterX = clusVec[0].begin();
01560                 for(;iterX!=clusVec[0].end(); ++iterX) {
01561                 idents::TkrId idX = (*iterX)->getTkrId();
01562                 int towerX = idents::TowerId(idX.getTowerX(), idX.getTowerY()).id();
01563                 if(!isXY[tower]) continue;
01564                 Event::TkrClusterVecConItr iterY = clusVec[1].begin();
01565                 for(;iterY!=clusVec[1].end(); ++iterY) {
01566                 idents::TkrId idY = (*iterY)->getTkrId();
01567                 int towerY = idents::TowerId(idY.getTowerX(), idY.getTowerY()).id();
01568                 if(towerX!=towerY) continue;
01569                 layerOutCount[tower] += 1.0f;
01570                 double dx = fabs(x_hit.x() - (*iterX)->position().x());
01571                 double dy = fabs(x_hit.y() - (*iterY)->position().y());
01572                 if (dx>xSprd || dy>ySprd) continue;
01573                 // could be inside!
01574                 if(dx*dx/xDenom + dy*dy/yDenom < 1.) layerInCount[tower] += 1.0f;
01575                 }
01576                 }
01577                 //    factor = ((float)clusCount[0][tower]+clusCount[1][tower])/
01578                 //    std::max(clusCount[0][tower]*clusCount[1][tower], 1);
01579                 } */        
01580 
01581                 int numHits = 0, numHitsOut = 0;
01582                 for(tower=0;tower<numTowers;++tower) {
01583                     numHitsOut += (int)layerOutCount[tower];
01584                     numHits    += (int)(layerInCount[tower]*factor);
01585                 }
01586                 Tkr_SurplusHCOutside += numHitsOut;
01587                 Tkr_SurplusHCInside  += numHits;
01588 
01589                 double layer_edge = towerEdge(x_hit);
01590 
01591                 double delta_rad= radlen-radlen_old;
01592                 double thisRad;
01593                 //A bit cleaner
01594                 switch (m_tkrGeom->getLayerType(layer)) 
01595                 {
01596                 case STANDARD:
01597                     thisRad = radThin;
01598                     thin_hits += numHits;
01599                     break;
01600                 case SUPER:
01601                     thisRad = radThick;
01602                     thick_hits += numHits;
01603                     break;
01604                 case NOCONV:
01605                     thisRad = 0.0;
01606                     blank_hits += numHits;
01607                     br