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" 20 #include "marlin/Exceptions.h" 24 #include <gear/TPCParameters.h> 25 #include <gear/TPCModule.h> 26 #include <gear/BField.h> 27 #include <gearimpl/Vector3D.h> 39 return ((one.second) < (two.second));
46 SimpleHelixGeneralBrokenLineInterfaceProcessor::SimpleHelixGeneralBrokenLineInterfaceProcessor() :
47 Processor(
"SimpleHelixGeneralBrokenLineInterfaceProcessor") {
50 "SimpleHelixGeneralBrokenLineInterfaceProcessor is the interface between MarlinTPC and the General Broken Lines track (re-)fitting package.";
52 registerInputCollection(LCIO::TRACK,
"InputSeedTracks",
53 "The name of the input collection of track candidates (default: TPCSeedTracks)",
_inputCollectionName,
54 std::string(
"TPCSeedTracks"));
56 registerOutputCollection(LCIO::TRACK,
"OutputTracks",
58 std::string(
"TPCTracks"));
60 registerProcessorParameter(
"WriteOutputToStorage",
"If true the output collection is written to file",
_outputIsPersistent,
true);
62 registerProcessorParameter(
"BFieldScaleFactor",
63 "Scales magnetic field (map), use 1.0 (default) for field ON or 0.0 for field OFF",
_bfieldScaleFactor,
double(1.0));
65 registerProcessorParameter(
"FitOptions",
66 "Set wether multiple passes with h huber, t tukey or c cauchy downweighting should be performed",
_fitOptions,
69 registerProcessorParameter(
"WriteMillepedeBinary",
70 "Set to true if you want a Millepede binary file (default:false); remember to also set MillePedeMinHits and MillepedeFilename",
73 registerProcessorParameter(
"MillePedeCalcMethod",
74 "Defines which parameters should be calculated for Millepede: 0: module alignment, 1: track distortions, 2: hit charge dependence (default:0)",
77 registerProcessorParameter(
"MillePedeMinHits",
78 "Minimum number of hits on track for output to Millepede binary file; has no effect if WriteMillepedeBinary set to false (default: 42)",
81 registerProcessorParameter(
"MillepedeFilename",
82 "Set the name of the Millepede binary file; is ignored if WriteMillepedeBinary is set to false (default: \"MillepedeBinary.dat\")",
85 registerProcessorParameter(
"EncodedModuleID",
"Module ID encoded in CellID0 (default: true)",
_encodedModuleID,
bool(
true));
87 registerProcessorParameter(
"X0PerUnitLength",
"X0 per unit length (TPC gas as homogeneous scatterer)",
_x0PerUnitLength,
90 registerProcessorParameter(
"ThickScatterer",
"Selects thick (otherwise thin) scatterers for multiple scattering",
_thickScatterer,
93 registerProcessorParameter(
"DefaultMomentum",
"Default momentum for multiple scattering (for Bfield off)",
_defaultMomentum,
104 const gear::TPCParameters& tpcParameters = Global::GEAR->getTPCParameters();
106 _Xcenter = tpcParameters.getDoubleVal(
"TPC_cylinder_centre_c0");
107 _Ycenter = tpcParameters.getDoubleVal(
"TPC_cylinder_centre_c1");
116 LCCollectionVec* seedTrackCollectionVector = NULL;
120 seedTrackCollectionVector =
dynamic_cast<LCCollectionVec *
>(evt->getCollection(
_inputCollectionName));
121 }
catch (DataNotAvailableException &e) {
126 streamlog_out(DEBUG) <<
"in event " << evt->getEventNumber() <<
" there are " << seedTrackCollectionVector->size() <<
" tracks. " 130 Vector3D bfield = marlin::Global::GEAR->getBField().at(theTPCCenter);
134 streamlog_out(DEBUG) <<
"BField(GEAR) is OFF" << std::endl;
136 streamlog_out(DEBUG) <<
"BField(GEAR) is ON" << std::endl;
142 IMPL::LCCollectionVec* outputTrackCollection =
new IMPL::LCCollectionVec(EVENT::LCIO::TRACK);
145 LCFlagImpl trkFlag(0);
146 trkFlag.setBit(LCIO::TRBIT_HITS);
147 outputTrackCollection->setFlag(trkFlag.getFlag());
150 for (LCCollectionVec::iterator inputIter = seedTrackCollectionVector->begin(), endIter = seedTrackCollectionVector->end();
151 inputIter < endIter; ++inputIter) {
153 Track* seedTrack =
dynamic_cast<Track *
>(*inputIter);
155 double seedD0 = seedTrack->getD0();
156 double seedPhi = seedTrack->getPhi();
157 double seedOmega = seedTrack->getOmega();
158 double seedZ0 = seedTrack->getZ0();
159 double seedTanLambda = seedTrack->getTanLambda();
160 vector<TrackerHit*> hitList = seedTrack->getTrackerHits();
162 const float* refPoint = seedTrack->getReferencePoint();
163 double refPos[] = { refPoint[0], refPoint[1], refPoint[2] };
165 float rInner = seedTrack->getRadiusOfInnermostHit();
167 streamlog_out(DEBUG) <<
" ++ track number " << endIter - inputIter <<
" with " << seedTrack->getTrackerHits().size()
168 <<
" hits on the track has the parameters: [omega, tanLambda, phi0, d0, z0] = [" << seedOmega <<
"," << seedTanLambda <<
"," 169 << seedPhi <<
"," << seedD0 <<
"," << seedZ0 <<
"] at the reference position [" << refPoint[0] <<
"," << refPoint[1] <<
"," 170 << refPoint[2] <<
"]." << endl;
176 if (seedOmega != 0.)
calcLineSeed(hitList, refPos, seedOmega, seedPhi, seedD0, seedTanLambda, seedZ0);
181 const double seedLambda = atan(seedTanLambda);
184 simpleHelix hlx(-seedOmega, seedPhi, -seedD0, seedTanLambda, seedZ0, refPos, Bz * 0.0002998);
189 vector<indexArcPair> hitWithArcList;
190 for (
unsigned int i = 0; i < hitList.size(); ++i) {
191 double position[] = { hitList[i]->getPosition()[0], hitList[i]->getPosition()[1] };
193 hitWithArcList.push_back(make_pair(i, sArc));
196 indexArcPair closest(hitWithArcList.front()), first(closest), last(closest);
197 for (vector<indexArcPair>::const_iterator thePair = hitWithArcList.begin() + 1; thePair < hitWithArcList.end(); ++thePair) {
198 if (abs(thePair->second) < abs(closest.second)) closest = *thePair;
199 if (thePair->second < first.second) first = *thePair;
200 if (thePair->second > last.second) last = *thePair;
203 const double averageStep = (last.second - first.second) / (hitWithArcList.size() - 1);
204 if (abs(closest.second / averageStep) > 1.0E-5) {
205 closest = make_pair(-1, 0.);
206 hitWithArcList.push_back(closest);
208 sort(hitWithArcList.begin(), hitWithArcList.end(), compare);
212 vector<arcVarPair> arcWithVarList;
215 if (!bOff) ptot = Bz * 0.0002998 / (seedOmega * cos(seedLambda));
216 double XbyX0 =
_x0PerUnitLength * (last.second - first.second) / cos(seedLambda);
218 double MultScatVar = pow(0.0136 / ptot * (1. + 0.038 * std::log(XbyX0)), 2) *
_x0PerUnitLength / cos(seedLambda);
220 arcWithVarList.push_back(make_pair(0.21132, 0.5 * MultScatVar));
221 arcWithVarList.push_back(make_pair(0.78868, 0.5 * MultScatVar));
223 arcWithVarList.push_back(make_pair(0.5, MultScatVar));
228 vector<GblPoint> theListOfPoints;
230 unsigned int numValid = 0;
232 TMatrixD point2pointJacobian(5, 5);
234 bool makeScatterers =
false;
236 vector<double> eLossEstimators;
238 unsigned int numLow = 0;
239 for (vector<indexArcPair>::const_iterator thePair = hitWithArcList.begin(); thePair < hitWithArcList.end(); ++thePair) {
241 int index = thePair->first;
242 double phiTrack = seedPhi - seedOmega * thePair->second;
248 double sNew = aHit.
getS();
250 if (makeScatterers) {
252 double step = sNew - sOld;
253 for (vector<arcVarPair>::const_iterator theScat = arcWithVarList.begin(); theScat < arcWithVarList.end(); ++theScat) {
255 double sScat = sNew + (theScat->first - 1.0) * step;
256 double deltaW = (sScat - sOld) / cos(seedLambda);
257 double phi1 = seedPhi - seedOmega * sScat;
261 GblPoint point(point2pointJacobian);
265 TVectorD scatPrec(2);
266 scatPrec[0] = scatPrec[1] = 1.0 / (theScat->second * step);
267 point.addScatterer(scat, scatPrec);
269 theListOfPoints.push_back(point);
273 if (index == first.first) makeScatterers =
true;
274 if (index == last.first) makeScatterers =
false;
278 double deltaW = (sNew - sOld) / cos(seedLambda);
279 double phi1 = aHit.
getPhi();
283 GblPoint point(point2pointJacobian);
290 eLossEstimators.push_back(1. / sqrt(aHit.
getEScaled()));
295 theListOfPoints.push_back(point);
297 if (index == closest.first)
_refPointIndex = theListOfPoints.size();
299 streamlog_out(DEBUG) <<
" invalid hit: " << thePair->first <<
", " << thePair->second << endl;
302 streamlog_out(DEBUG) <<
" ++ track number " << endIter - inputIter <<
" skipped - too few valid hits " << endl;
314 TVectorD trackparameters(5);
315 TMatrixDSym trackcovariance(5);
323 TVectorD correctionVec = jacCL2LCIO * trackparameters;
324 TMatrixDSym covarianceMatrix = trackcovariance.Similarity(jacCL2LCIO);
332 TrackImpl* theTrack =
new TrackImpl();
333 theTrack->setOmega(seedOmega + correctionVec[2]);
334 theTrack->setTanLambda(seedTanLambda + correctionVec[4]);
335 theTrack->setPhi(seedPhi + correctionVec[1]);
336 theTrack->setD0(seedD0 + correctionVec[0]);
337 theTrack->setZ0(seedZ0 + correctionVec[3]);
338 theTrack->setReferencePoint(refPoint);
339 theTrack->setRadiusOfInnermostHit(rInner);
341 float compressedCovariance[15];
343 for (
int i = 0; i < 5; ++i)
344 for (
int j = 0; j <= i; ++j)
345 compressedCovariance[ind++] = covarianceMatrix[i][j];
346 theTrack->setCovMatrix(compressedCovariance);
349 theTrack->setNdf(
_ndf);
352 const unsigned int numEstimators = eLossEstimators.size();
353 if (numEstimators > numLow) {
354 sort(eLossEstimators.begin(), eLossEstimators.end());
355 const int nTot = numEstimators + numLow;
356 const int indMed = nTot / 2;
358 (nTot % 2 == 0) ? 0.5 * (eLossEstimators[indMed - 1] + eLossEstimators[indMed]) : eLossEstimators[indMed];
359 vector<double> absDev;
360 for (
unsigned int i = 0; i < numEstimators; ++i)
361 absDev.push_back(abs(eLossEstimators[i] - eMed));
362 sort(absDev.begin(), absDev.end());
363 const double eMAD = (nTot % 2 == 0) ? 0.5 * (absDev[indMed - 1] + absDev[indMed]) : absDev[indMed];
364 const float ndEdx = nTot;
365 const float dEdx = 1.0 / (eMed * eMed);
366 const float dEdxError = 2. * 1.4826 * eMAD * dEdx / eMed / sqrt(ndEdx);
367 streamlog_out(DEBUG) <<
" dEdx " << ndEdx <<
" " << dEdx <<
" " << dEdxError << endl;
368 theTrack->setdEdx(dEdx);
369 theTrack->setdEdxError(dEdxError);
372 for (vector<TrackerHit*>::const_iterator theHit = seedTrack->getTrackerHits().begin(), hitEnd =
373 seedTrack->getTrackerHits().end(); theHit < hitEnd; ++theHit)
374 theTrack->addHit(*theHit);
376 streamlog_out(DEBUG) <<
" +++ the fitted track has a chi^2 value of " <<
_chisquare <<
" for ndf = " <<
_ndf 377 <<
" and the parameters [omega, tanLambda, phi0, d0, z0] = [" << theTrack->getOmega() <<
"," << theTrack->getTanLambda()
378 <<
"," << theTrack->getPhi() <<
"," << theTrack->getD0() <<
"," << theTrack->getZ0() <<
"]." << endl;
380 outputTrackCollection->addElement(theTrack);
411 double & omega,
double & phi,
double & d0,
double & tanLambda,
double & z0)
const {
414 for (vector<TrackerHit*>::const_iterator theHit = hitList.begin(), hitEnd = hitList.end(); theHit < hitEnd; ++theHit) {
415 const EVENT::TrackerHit& aHit = **theHit;
416 const double x = aHit.getPosition()[0];
417 const double y = aHit.getPosition()[1];
418 const double z = aHit.getPosition()[2];
419 const double r = sqrt(pow(x, 2) + pow(y, 2));
420 if (xyzr[0][3] == 0.)
446 const double dx = xyzr[1][0] - xyzr[0][0];
447 const double dy = xyzr[1][1] - xyzr[0][1];
448 const double dz = xyzr[1][2] - xyzr[0][2];
449 const double dr = sqrt(pow(dx, 2) + pow(dy, 2));
450 const double x1 = xyzr[0][0] - refPos[0];
451 const double y1 = xyzr[0][1] - refPos[1];
452 const double z1 = xyzr[0][2] - refPos[2];
456 d0 = y1 * cos(phi) - x1 * sin(phi);
458 z0 = z1 - tanLambda * (x1 * cos(phi) + y1 * sin(phi));
463 #endif // conditional compilation if GBL program package is available on the system TVectorD getResiduals() const
Get residuals.
gbl::GblTrajectory * _trajectory
GBL trajectory.
bool _encodedModuleID
Module ID is encoded in CellID0.
double _lostweight
weight lost by down-weighting
TMatrixD analyticalHelixJacobian(const double, const double) const
Get analytical helix propagator (in constant solenoidal magnetic field)
const bool isSelected() const
Get selection flag.
int _milleMinHits
defines minimum number of hits on track for output to Millepede binary file
unsigned int getNumGlobals() const
Get number of global derivatives.
bool isMeasurement() const
Get measurement flag.
TMatrixD perigeeToLCIOJacobian() const
Get transformation from helix to LCIO track parameters (at reference point)
bool isValid() const
Get flag for valid prediction.
TMatrixDSym getPrecision() const
Get precision.
bool _writeMillepedeOut
selects output to Millepede-II binary file
SimpleHelixGeneralBrokenLineInterfaceProcessor aSimpleHelixGeneralBrokenLineInterfaceProcessor
virtual void processRunHeader(EVENT::LCRunHeader *run)
int _milleCalcMethod
defines which parameter should be calculated for Millepede-II binary file
int _ndf
number of degrees of freedom in GBL fit
std::pair< int, double > indexArcPair
virtual void init()
Initialize processor.
double _defaultMomentum
default momentum for multiple scattering (for Bfield off, GeV) (default: 10.)
bool _outputIsPersistent
whether the output is to be stored or not (default: true)
void calcLineSeed(const std::vector< TrackerHit *>, const double *, double &, double &, double &, double &, double &) const
Simple seed for straight line.
double getS() const
Get arc-length.
unsigned int _refPointIndex
label of reference point
TMatrixD curvilinearToPerigeeJacobian() const
Get transformation from curivilinear to perigee track parameters (at reference point) ...
double _x0PerUnitLength
X0 per unit length (TPC gas as homogeneous scatterer) (default: 0.)
User defined class to select tracks for Millepede-II.
double getPhi() const
Get phi (direction )of seed track.
double getEScaled() const
Get scaled Edep.
std::vector< int > getGlobalLabels() const
Get labels for global derivatives.
double _Xcenter
TPC center, X coordinate.
virtual void processEvent(EVENT::LCEvent *evt)
Process event.
TMatrixD getLocalToMeasurementProjection() const
Get projection from local to measurement system.
double _Ycenter
TPC center, Y coordinate.
std::string _outputTrackCollectionName
Name of the output track collection.
bool _curvature
flag for curved track (helix, else straight line)
double _bfieldScaleFactor
scale factor for magnetic field (default: 1.0)
std::string _fitOptions
list of iterations with 'h' Huber, 't' Tukey or 'c' Cauchy down-weighting
std::string _inputCollectionName
Name of the input collection – track seeds.
bool _thickScatterer
selects thick (otherwise thin) scatterers for multiple scattering (default: false) ...
const TMatrixD & getGlobalDerivatives() const
Get global derivatives.
double getArcLengthXY(const double *) const
Get (2D) arc length for given point.
virtual void check(EVENT::LCEvent *evt)
std::string _fileNameMillepedeFile
name of Millepede-II binary file
Using GBL with a simple helix.
double _chisquare
chi2 from GBL fit
gbl::MilleBinary * _milleBinary
Millepede-II binary file.