9 #include <EVENT/LCEvent.h> 10 #include <IMPL/LCCollectionVec.h> 11 #include <EVENT/Track.h> 12 #include <EVENT/TrackerHit.h> 13 #include "IMPL/TrackImpl.h" 14 #include "IMPL/LCFlagImpl.h" 15 #include <Exceptions.h> 16 #include <UTIL/BitField64.h> 17 #include <UTIL/ILDConf.h> 19 #include "marlin/Global.h" 23 #include <gear/TPCParameters.h> 24 #include <gear/TPCModule.h> 25 #include <gear/BField.h> 26 #include <gearimpl/Vector3D.h> 40 return ((one.second) < (two.second));
47 StepWiseHelixGeneralBrokenLineInterfaceProcessor::StepWiseHelixGeneralBrokenLineInterfaceProcessor() :
48 Processor(
"StepWiseHelixGeneralBrokenLineInterfaceProcessor") {
51 "StepWiseHelixGeneralBrokenLineInterfaceProcessor is the interface between MarlinTPC and the General Broken Lines track (re-)fitting package.";
53 registerInputCollection(LCIO::TRACK,
"InputSeedTracks",
54 "The name of the input collection of track candidates (default: TPCSeedTracks)",
_inputCollectionName,
55 std::string(
"TPCSeedTracks"));
57 registerOutputCollection(LCIO::TRACK,
"OutputTracks",
59 std::string(
"TPCTracks"));
61 registerProcessorParameter(
"WriteOutputToStorage",
"If true the output collection is written to file",
_outputIsPersistent,
true);
63 registerOptionalParameter(
"BFieldScaleFactor",
"Scales magnetic field (map), use 1.0 (default) for field ON or 0.0 for field OFF",
66 registerOptionalParameter(
"FitOptions",
67 "Set wether multiple passes with h huber, t tukey or c cauchy downweighting should be performed",
_fitOptions,
70 registerOptionalParameter(
"WriteMillepedeBinary",
"Set to true if you want a Millepede binary file (default:false)",
73 registerOptionalParameter(
"MillePedeCalcMethod",
74 "Defines which parameters should be calculates for Millepede: 0: module alignment, 1: track distortions, 2: hit charge dependence (has yet to be implemented) (default:0)",
77 registerOptionalParameter(
"MillePedeMinHits",
"Minimum number of hits on track for output to Millepede binary file (default: 42)",
80 registerOptionalParameter(
"MillepedeFilename",
"Set the name of the Millepede binary file ",
_fileNameMillepedeFile,
82 registerOptionalParameter(
"EncodedModuleID",
"Module ID encoded in CellID0",
_encodedModuleID,
bool(
true));
84 registerOptionalParameter(
"MaxStep",
"Maximal step size (with constant magnetic field)",
_maxStep,
double(10.0));
86 registerProcessorParameter(
"X0PerUnitLength",
"X0 per unit length (TPC gas as homogeneous scatterer)",
_x0PerUnitLength,
89 registerProcessorParameter(
"ThickScatterer",
"Selects thick (otherwise thin) scatterers for multiple scattering",
_thickScatterer,
92 registerProcessorParameter(
"DefaultMomentum",
"Default momentum for multiple scattering (for Bfield off)",
_defaultMomentum,
103 const gear::TPCParameters& tpcParameters = Global::GEAR->getTPCParameters();
105 _Xcenter = tpcParameters.getDoubleVal(
"TPC_cylinder_centre_c0");
106 _Ycenter = tpcParameters.getDoubleVal(
"TPC_cylinder_centre_c1");
115 LCCollectionVec* seedTrackCollectionVector = NULL;
119 seedTrackCollectionVector =
dynamic_cast<LCCollectionVec *
>(evt->getCollection(
_inputCollectionName));
120 }
catch (DataNotAvailableException &e) {
125 streamlog_out(DEBUG) <<
"in event " << evt->getEventNumber() <<
" there are " << seedTrackCollectionVector->size() <<
" tracks. " 129 Vector3D bfield = marlin::Global::GEAR->getBField().at(theTPCCenter);
133 streamlog_out(DEBUG) <<
"BField(GEAR) is OFF" << std::endl;
135 streamlog_out(DEBUG) <<
"BField(GEAR) is ON" << std::endl;
141 IMPL::LCCollectionVec* outputTrackCollection =
new IMPL::LCCollectionVec(EVENT::LCIO::TRACK);
144 LCFlagImpl trkFlag(0);
145 trkFlag.setBit(LCIO::TRBIT_HITS);
146 outputTrackCollection->setFlag(trkFlag.getFlag());
149 for (LCCollectionVec::iterator inputIter = seedTrackCollectionVector->begin(), endIter = seedTrackCollectionVector->end();
150 inputIter < endIter; ++inputIter) {
152 Track* seedTrack =
dynamic_cast<Track *
>(*inputIter);
154 double seedD0 = seedTrack->getD0();
155 double seedPhi = seedTrack->getPhi();
156 double seedOmega = seedTrack->getOmega();
157 double seedZ0 = seedTrack->getZ0();
158 double seedTanLambda = seedTrack->getTanLambda();
159 vector<TrackerHit*> hitList = seedTrack->getTrackerHits();
161 const float* refPoint = seedTrack->getReferencePoint();
162 const double refPos[] = { refPoint[0], refPoint[1], refPoint[2] };
164 float rInner = seedTrack->getRadiusOfInnermostHit();
166 streamlog_out(DEBUG) <<
" ++ track number " << endIter - inputIter <<
" with " << seedTrack->getTrackerHits().size()
167 <<
" hits on the track has the parameters: [omega, tanLambda, phi0, d0, z0] = [" << seedOmega <<
"," << seedTanLambda <<
"," 168 << seedPhi <<
"," << seedD0 <<
"," << seedZ0 <<
"]." << endl;
174 if (seedOmega != 0.)
calcLineSeed(hitList, refPos, seedOmega, seedPhi, seedD0, seedTanLambda, seedZ0);
179 const double seedLambda = atan(seedTanLambda);
182 double seedPar[] = { -seedOmega, seedPhi, -seedD0, seedTanLambda, seedZ0 };
189 vector<indexArcPair> hitWithArcList;
190 for (
unsigned int i = 0; i < hitList.size(); ++i) {
192 hitWithArcList.push_back(make_pair(i, sArc));
195 indexArcPair closest(hitWithArcList.front()), first(closest), last(closest);
196 for (vector<indexArcPair>::const_iterator thePair = hitWithArcList.begin() + 1; thePair < hitWithArcList.end(); ++thePair) {
197 if (abs(thePair->second) < abs(closest.second)) closest = *thePair;
198 if (thePair->second < first.second) first = *thePair;
199 if (thePair->second > last.second) last = *thePair;
202 const double averageStep = (last.second - first.second) / (hitWithArcList.size() - 1);
203 if (abs(closest.second / averageStep) > 1.0E-5) {
204 closest = make_pair(-1, 0.);
205 hitWithArcList.push_back(closest);
207 sort(hitWithArcList.begin(), hitWithArcList.end(), compare);
211 vector<arcVarPair> arcWithVarList;
214 if (!bOff) ptot = Bz * 0.0002998 / (seedOmega * cos(seedLambda));
215 double XbyX0 =
_x0PerUnitLength * (last.second - first.second) / cos(seedLambda);
217 double MultScatVar = pow(0.0136 / ptot * (1. + 0.038 * std::log(XbyX0)), 2) *
_x0PerUnitLength / cos(seedLambda);
219 arcWithVarList.push_back(make_pair(0.21132, 0.5 * MultScatVar));
220 arcWithVarList.push_back(make_pair(0.78868, 0.5 * MultScatVar));
222 arcWithVarList.push_back(make_pair(0.5, MultScatVar));
227 vector<GblPoint> theListOfPoints;
229 unsigned int numValid = 0;
231 TMatrixD point2pointJacobian(5, 5);
232 point2pointJacobian.UnitMatrix();
233 bool makeScatterers =
false;
235 vector<double> eLossEstimators;
237 unsigned int numLow = 0;
238 for (vector<indexArcPair>::const_iterator thePair = hitWithArcList.begin(); thePair < hitWithArcList.end(); ++thePair) {
240 int index = thePair->first;
241 double phiTrack = seedPhi - seedOmega * thePair->second;
243 const double* position = index >= 0 ? hitList[index]->getPosition() : refPos;
246 if (makeScatterers) {
252 for (vector<arcVarPair>::const_iterator theScat = arcWithVarList.begin(); theScat < arcWithVarList.end(); ++theScat) {
257 GblPoint point(point2pointJacobian);
259 point2pointJacobian.UnitMatrix();
263 TVectorD scatPrec(2);
264 scatPrec[0] = scatPrec[1] = 1.0 / (theScat->second * step);
265 point.addScatterer(scat, scatPrec);
267 theListOfPoints.push_back(point);
271 if (index == first.first) makeScatterers =
true;
272 if (index == last.first) makeScatterers =
false;
285 GblPoint point(point2pointJacobian);
287 point2pointJacobian.UnitMatrix();
293 eLossEstimators.push_back(1. / sqrt(aHit.
getEScaled()));
298 theListOfPoints.push_back(point);
300 if (index == closest.first)
_refPointIndex = theListOfPoints.size();
302 streamlog_out(DEBUG) <<
" invalid hit: " << thePair->first <<
", " << thePair->second << endl;
305 streamlog_out(DEBUG) <<
" ++ track number " << endIter - inputIter <<
" skipped - too few valid hits " << endl;
317 TVectorD trackparameters(5);
318 TMatrixDSym trackcovariance(5);
326 TVectorD correctionVec = jacCL2LCIO * trackparameters;
327 TMatrixDSym covarianceMatrix = trackcovariance.Similarity(jacCL2LCIO);
334 TrackImpl* theTrack =
new TrackImpl();
335 theTrack->setOmega(seedOmega + correctionVec[2]);
336 theTrack->setTanLambda(seedTanLambda + correctionVec[4]);
337 theTrack->setPhi(seedPhi + correctionVec[1]);
338 theTrack->setD0(seedD0 + correctionVec[0]);
339 theTrack->setZ0(seedZ0 + correctionVec[3]);
340 theTrack->setReferencePoint(refPoint);
341 theTrack->setRadiusOfInnermostHit(rInner);
343 float compressedCovariance[15];
345 for (
int i = 0; i < 5; ++i)
346 for (
int j = 0; j <= i; ++j)
347 compressedCovariance[ind++] = covarianceMatrix[i][j];
348 theTrack->setCovMatrix(compressedCovariance);
351 theTrack->setNdf(
_ndf);
354 const unsigned int numEstimators = eLossEstimators.size();
355 if (numEstimators > numLow) {
356 sort(eLossEstimators.begin(), eLossEstimators.end());
357 const int nTot = numEstimators + numLow;
358 const int indMed = nTot / 2;
360 (nTot % 2 == 0) ? 0.5 * (eLossEstimators[indMed - 1] + eLossEstimators[indMed]) : eLossEstimators[indMed];
361 vector<double> absDev;
362 for (
unsigned int i = 0; i < numEstimators; ++i)
363 absDev.push_back(abs(eLossEstimators[i] - eMed));
364 sort(absDev.begin(), absDev.end());
365 const double eMAD = (nTot % 2 == 0) ? 0.5 * (absDev[indMed - 1] + absDev[indMed]) : absDev[indMed];
366 const float ndEdx = nTot;
367 const float dEdx = 1.0 / (eMed * eMed);
368 const float dEdxError = 2. * 1.4826 * eMAD * dEdx / eMed / sqrt(ndEdx);
369 streamlog_out(DEBUG) <<
" dEdx " << ndEdx <<
" " << dEdx <<
" " << dEdxError << endl;
370 theTrack->setdEdx(dEdx);
371 theTrack->setdEdxError(dEdxError);
374 for (vector<TrackerHit*>::const_iterator theHit = seedTrack->getTrackerHits().begin(), hitEnd =
375 seedTrack->getTrackerHits().end(); theHit < hitEnd; ++theHit)
376 theTrack->addHit(*theHit);
378 streamlog_out(DEBUG) <<
" +++ the fitted track has a chi^2 value of " <<
_chisquare <<
" for ndf = " <<
_ndf 379 <<
" and the parameters [omega, tanLambda, phi0, d0, z0] = [" << theTrack->getOmega() <<
"," << theTrack->getTanLambda()
380 <<
"," << theTrack->getPhi() <<
"," << theTrack->getD0() <<
"," << theTrack->getZ0() <<
"]." << endl;
382 outputTrackCollection->addElement(theTrack);
413 double& omega,
double& phi,
double& d0,
double& tanLambda,
double& z0)
const {
416 for (vector<TrackerHit*>::const_iterator theHit = hitList.begin(), hitEnd = hitList.end(); theHit < hitEnd; ++theHit) {
417 const EVENT::TrackerHit& aHit = **theHit;
418 const double x = aHit.getPosition()[0];
419 const double y = aHit.getPosition()[1];
420 const double z = aHit.getPosition()[2];
421 const double r = sqrt(pow(x, 2) + pow(y, 2));
422 if (xyzr[0][3] == 0.)
448 const double dx = xyzr[1][0] - xyzr[0][0];
449 const double dy = xyzr[1][1] - xyzr[0][1];
450 const double dz = xyzr[1][2] - xyzr[0][2];
451 const double dr = sqrt(pow(dx, 2) + pow(dy, 2));
452 const double x1 = xyzr[0][0] - refPos[0];
453 const double y1 = xyzr[0][1] - refPos[1];
454 const double z1 = xyzr[0][2] - refPos[2];
458 d0 = y1 * cos(phi) - x1 * sin(phi);
460 z0 = z1 - tanLambda * (x1 * cos(phi) + y1 * sin(phi));
465 #endif // conditional compilation if GBL program package is available on the system TVectorD getResiduals() const
Get residuals.
virtual void processEvent(EVENT::LCEvent *evt)
Process event.
simpleHelix getSimpleHelix() const
Get simple helix.
TMatrixD propagateTo(const double *, const double)
Propagate stepwise (close) to point.
double _Ycenter
TPC center, Y coordinate.
const bool isSelected() const
Get selection flag.
unsigned int getNumGlobals() const
Get number of global derivatives.
bool isMeasurement() const
Get measurement flag.
int _milleMinHits
defines minimum number of hits on track for output to Millepede binary file
TMatrixD perigeeToLCIOJacobian() const
Get transformation from helix to LCIO track parameters (at reference point)
bool isValid() const
Get flag for valid prediction.
bool _thickScatterer
selects thick (otherwise thin) scatterers for multiple scattering (default: false) ...
virtual void processRunHeader(EVENT::LCRunHeader *run)
gbl::GblTrajectory * _trajectory
GBL trajectory.
TMatrixDSym getPrecision() const
Get precision.
void getPosAtArcLength(const double, double *) const
Get position (on helix) at arc length.
double _lostweight
weight lost by down-weighting
bool _writeMillepedeOut
selects output to Millepede-II binary file
Using GBL with a step-wise helix.
int _ndf
number of degrees of freedom in GBL fit
gbl::MilleBinary * _milleBinary
Millepede-II binary file.
std::pair< int, double > indexArcPair
std::string _fitOptions
list of iterations with 'h' Huber, 't' Tukey or 'c' Cauchy down-weighting
virtual void init()
Initialize processor.
void calcLineSeed(const std::vector< TrackerHit *>, const double *, double &, double &, double &, double &, double &) const
Simple seed for straight line.
unsigned int _refPointIndex
label of reference point
bool _outputIsPersistent
whether the output is to be stored or not (default: true)
double _defaultMomentum
default momentum for multiple scattering (for Bfield off, GeV) (default: 10.)
double _Xcenter
TPC center, X coordinate.
TMatrixD curvilinearToPerigeeJacobian() const
Get transformation from curivilinear to perigee track parameters (at reference point) ...
std::string _outputTrackCollectionName
Name of the output track collection.
User defined class to select tracks for Millepede-II.
int _milleCalcMethod
defines which parameter should be calculated for Millepede-II binary file
double getEScaled() const
Get scaled Edep.
std::vector< int > getGlobalLabels() const
Get labels for global derivatives.
bool _curvature
flag for curved track (helix, else straight line)
std::string _inputCollectionName
Name of the input collection – track seeds.
TMatrixD getLocalToMeasurementProjection() const
Get projection from local to measurement system.
double _maxStep
maximal step size (default: 10.)
const TMatrixD & getGlobalDerivatives() const
Get global derivatives.
virtual void check(EVENT::LCEvent *evt)
StepWiseHelixGeneralBrokenLineInterfaceProcessor aStepWiseHelixGeneralBrokenLineInterfaceProcessor
double getArcLengthXY(const double *) const
Get (2D) arc length for given point.
double _chisquare
chi2 from GBL fit
double _x0PerUnitLength
X0 per unit length (TPC gas as homogeneous scatterer) (default: 0.)
std::string _fileNameMillepedeFile
name of Millepede-II binary file
double _bfieldScaleFactor
scale factor for magnetic field (default: 1.0)
bool _encodedModuleID
Module ID is encoded in CellID0.