]> git.uio.no Git - u/mrichter/AliRoot.git/blame - STEER/AOD/AliAODVertex.cxx
Corrected initialisation of
[u/mrichter/AliRoot.git] / STEER / AOD / AliAODVertex.cxx
CommitLineData
df9db588 1/**************************************************************************
2 * Copyright(c) 1998-2007, ALICE Experiment at CERN, All rights reserved. *
3 * *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
6 * *
7 * Permission to use, copy, modify and distribute this software and its *
8 * documentation strictly for non-commercial purposes is hereby granted *
9 * without fee, provided that the above copyright notice appears in all *
10 * copies and that both the copyright notice and this permission notice *
11 * appear in the supporting documentation. The authors make no claims *
12 * about the suitability of this software for any purpose. It is *
13 * provided "as is" without express or implied warranty. *
14 **************************************************************************/
15
16/* $Id$ */
17
18//-------------------------------------------------------------------------
19// AOD track base class
20// Base class for Analysis Object Data
21// Generic version
22// Author: Markus Oldenburg, CERN
bdd011d6 23// Inheritance from AliVVertex: A. Dainese
df9db588 24//-------------------------------------------------------------------------
25
26#include "AliAODVertex.h"
0657f082 27#include "AliAODTrack.h"
28
df9db588 29ClassImp(AliAODVertex)
30
31//______________________________________________________________________________
32AliAODVertex::AliAODVertex() :
bdd011d6 33 AliVVertex(),
0657f082 34 fChi2perNDF(-999.),
02153d58 35 fID(-1),
0e7f6e3e 36 fBCID(AliVTrack::kTOFBCNA),
9333290e 37 fType(kUndef),
bca58dd7 38 fNprong(0),
39 fIprong(0),
d999f2e6 40 fNContributors(0),
9f7c531f 41 fCovMatrix(NULL),
0f09edc3 42 fParent(),
bca58dd7 43 fDaughters(),
44 fProngs(NULL)
9333290e 45 {
df9db588 46 // default constructor
47
48 fPosition[0] = fPosition[1] = fPosition[2] = -999.;
49}
50
51//______________________________________________________________________________
52AliAODVertex::AliAODVertex(const Double_t position[3],
31fd97b2 53 const Double_t covMatrix[6],
0657f082 54 Double_t chi2perNDF,
df9db588 55 TObject *parent,
02153d58 56 Short_t id,
bca58dd7 57 Char_t vtype,
58 Int_t nprong) :
bdd011d6 59 AliVVertex(),
0657f082 60 fChi2perNDF(chi2perNDF),
02153d58 61 fID(id),
0e7f6e3e 62 fBCID(AliVTrack::kTOFBCNA),
9333290e 63 fType(vtype),
bca58dd7 64 fNprong(nprong),
65 fIprong(0),
d999f2e6 66 fNContributors(0),
9f7c531f 67 fCovMatrix(NULL),
df9db588 68 fParent(parent),
bca58dd7 69 fDaughters(),
70 fProngs(0)
df9db588 71{
72 // constructor
73
74 SetPosition(position);
75 if (covMatrix) SetCovMatrix(covMatrix);
bca58dd7 76 MakeProngs();
df9db588 77}
78
79//______________________________________________________________________________
80AliAODVertex::AliAODVertex(const Float_t position[3],
81 const Float_t covMatrix[6],
0657f082 82 Double_t chi2perNDF,
df9db588 83 TObject *parent,
02153d58 84 Short_t id,
bca58dd7 85 Char_t vtype,
86 Int_t nprong) :
4d209fca 87
bdd011d6 88 AliVVertex(),
0657f082 89 fChi2perNDF(chi2perNDF),
02153d58 90 fID(id),
0e7f6e3e 91 fBCID(AliVTrack::kTOFBCNA),
9333290e 92 fType(vtype),
bca58dd7 93 fNprong(nprong),
94 fIprong(0),
d999f2e6 95 fNContributors(0),
9f7c531f 96 fCovMatrix(NULL),
df9db588 97 fParent(parent),
bca58dd7 98 fDaughters(),
99 fProngs(0)
df9db588 100{
101 // constructor
102
103 SetPosition(position);
104 if (covMatrix) SetCovMatrix(covMatrix);
bca58dd7 105 MakeProngs();
df9db588 106}
107
108//______________________________________________________________________________
109AliAODVertex::AliAODVertex(const Double_t position[3],
0657f082 110 Double_t chi2perNDF,
bca58dd7 111 Char_t vtype,
112 Int_t nprong) :
bdd011d6 113 AliVVertex(),
0657f082 114 fChi2perNDF(chi2perNDF),
02153d58 115 fID(-1),
0e7f6e3e 116 fBCID(AliVTrack::kTOFBCNA),
9333290e 117 fType(vtype),
bca58dd7 118 fNprong(nprong),
119 fIprong(0),
d999f2e6 120 fNContributors(0),
9f7c531f 121 fCovMatrix(NULL),
0f09edc3 122 fParent(),
bca58dd7 123 fDaughters(),
124 fProngs(0)
df9db588 125{
126 // constructor without covariance matrix
127
128 SetPosition(position);
bca58dd7 129 MakeProngs();
df9db588 130}
131
132//______________________________________________________________________________
133AliAODVertex::AliAODVertex(const Float_t position[3],
0657f082 134 Double_t chi2perNDF,
bca58dd7 135 Char_t vtype, Int_t nprong) :
bdd011d6 136 AliVVertex(),
0657f082 137 fChi2perNDF(chi2perNDF),
02153d58 138 fID(-1),
0e7f6e3e 139 fBCID(AliVTrack::kTOFBCNA),
9333290e 140 fType(vtype),
bca58dd7 141 fNprong(nprong),
142 fIprong(0),
d999f2e6 143 fNContributors(0),
9f7c531f 144 fCovMatrix(NULL),
0f09edc3 145 fParent(),
bca58dd7 146 fDaughters(),
147 fProngs(0)
df9db588 148{
149 // constructor without covariance matrix
150
151 SetPosition(position);
bca58dd7 152 MakeProngs();
df9db588 153}
154
155//______________________________________________________________________________
156AliAODVertex::~AliAODVertex()
157{
158 // Destructor
159
160 delete fCovMatrix;
bca58dd7 161 if (fNprong > 0) delete[] fProngs;
df9db588 162}
163
164//______________________________________________________________________________
165AliAODVertex::AliAODVertex(const AliAODVertex& vtx) :
bdd011d6 166 AliVVertex(vtx),
0657f082 167 fChi2perNDF(vtx.fChi2perNDF),
02153d58 168 fID(vtx.fID),
0249e9b8 169 fBCID(vtx.fBCID),
9333290e 170 fType(vtx.fType),
bca58dd7 171 fNprong(vtx.fNprong),
172 fIprong(vtx.fIprong),
d999f2e6 173 fNContributors(vtx.fNContributors),
9f7c531f 174 fCovMatrix(NULL),
df9db588 175 fParent(vtx.fParent),
bca58dd7 176 fDaughters(vtx.fDaughters),
177 fProngs(0)
df9db588 178{
179 // Copy constructor.
180
181 for (int i = 0; i < 3; i++)
182 fPosition[i] = vtx.fPosition[i];
183
5d62ce04 184 if (vtx.fCovMatrix) fCovMatrix=new AliAODRedCov<3>(*vtx.fCovMatrix);
bca58dd7 185 MakeProngs();
186 for (int i = 0; i < fNprong; i++) {
187 fProngs[i] = vtx.fProngs[i];
188 }
df9db588 189}
190
26ba01d4 191//______________________________________________________________________________
192AliAODVertex* AliAODVertex::CloneWithoutRefs() const
193{
194 // Special method to copy all but the refs
195
196 Double_t cov[6] = { 0.0 };
197
198 if (fCovMatrix) fCovMatrix->GetCovMatrix(cov);
199
200 AliAODVertex* v = new AliAODVertex(fPosition,
201 cov,
202 fChi2perNDF,
203 0x0,
204 fID,
205 fType,
206 0);
207
208 v->SetNContributors(fNContributors);
209
210 return v;
211}
212
df9db588 213//______________________________________________________________________________
214AliAODVertex& AliAODVertex::operator=(const AliAODVertex& vtx)
215{
216 // Assignment operator
217 if (this != &vtx) {
218
219 // name and type
bdd011d6 220 AliVVertex::operator=(vtx);
df9db588 221
222 //momentum
223 for (int i = 0; i < 3; i++)
224 fPosition[i] = vtx.fPosition[i];
225
0657f082 226 fChi2perNDF = vtx.fChi2perNDF;
02153d58 227 fID = vtx.fID;
9333290e 228 fType = vtx.fType;
9f7c531f 229
df9db588 230 //covariance matrix
231 delete fCovMatrix;
9f7c531f 232 fCovMatrix = NULL;
5d62ce04 233 if (vtx.fCovMatrix) fCovMatrix=new AliAODRedCov<3>(*vtx.fCovMatrix);
df9db588 234
235 //other stuff
df9db588 236 fParent = vtx.fParent;
237 fDaughters = vtx.fDaughters;
bca58dd7 238 fNprong = vtx.fNprong;
239 fIprong = vtx.fIprong;
240
241 MakeProngs();
242 for (int i = 0; i < fNprong; i++) {
243 fProngs[i] = vtx.fProngs[i];
244 }
df9db588 245 }
246
247 return *this;
248}
249
cfa5b70c 250//______________________________________________________________________________
251void AliAODVertex::AddDaughter(TObject *daughter)
252{
253 // Add reference to daughter track
bca58dd7 254 if (!fProngs) {
255 if (fDaughters.GetEntries()==0) {
256 TRefArray* arr = &fDaughters;
257 new(arr)TRefArray(TProcessID::GetProcessWithUID(daughter));
258 }
259 fDaughters.Add(daughter);
260 } else {
261 if (fIprong < fNprong) {
262 fProngs[fIprong++] = daughter;
263 } else {
264 AliWarning("Number of daughters out of range !\n");
265 }
266 }
cfa5b70c 267 return;
268}
269
bca58dd7 270
df9db588 271//______________________________________________________________________________
272template <class T> void AliAODVertex::GetSigmaXYZ(T sigma[3]) const
273{
274 // Return errors on vertex position in thrust frame
275
276 if(fCovMatrix) {
277 sigma[0]=fCovMatrix[3]; //GetCovXZ
278 sigma[1]=fCovMatrix[4]; //GetCovYZ
279 sigma[2]=fCovMatrix[5]; //GetCovZZ
280 } else
281 sigma[0]=sigma[1]=sigma[2]=-999.;
282
283 /*
284 for (int i = 0, j = 6; i < 3; i++) {
285 j -= i+1;
286 sigma[2-i] = fCovMatrix ? TMath::Sqrt(fCovMatrix[j]) : -999.;
287 }
288 */
289}
290
0657f082 291//______________________________________________________________________________
292Int_t AliAODVertex::GetNContributors() const
293{
294 // Returns the number of tracks used to fit this vertex.
8b5318b9 295 Int_t cont = 0;
0657f082 296
1c1c7167 297 TString vtitle = GetTitle();
298 if (!vtitle.Contains("VertexerTracks")) {
91bad62d 299 cont = fNContributors;
19d55689 300 } else {
301 for (Int_t iDaug = 0; iDaug < GetNDaughters(); iDaug++) {
8b5318b9 302 AliAODTrack* aodT = dynamic_cast<AliAODTrack*>(fDaughters.At(iDaug));
303 if (!aodT) continue;
304 if (aodT->GetUsedForPrimVtxFit()) cont++;
305 }
bee8cd19 306 // the constraint adds another DOF
307 if(vtitle.Contains("VertexerTracksWithConstraint"))cont++;
308 }
0657f082 309 return cont;
310}
311
df9db588 312//______________________________________________________________________________
313Bool_t AliAODVertex::HasDaughter(TObject *daughter) const
314{
315 // Checks if the given daughter (particle) is part of this vertex.
bca58dd7 316 if (!fProngs) {
317 TRefArrayIter iter(&fDaughters);
318 while (TObject *daugh = iter.Next()) {
319 if (daugh == daughter) return kTRUE;
320 }
321 return kFALSE;
322 } else {
323 Bool_t has = kFALSE;
5c2137c1 324 for (int i = 0; i < fNprong; i++) {
bca58dd7 325 if (fProngs[i].GetObject() == daughter) has = kTRUE;
326 }
327 return has;
328 }
df9db588 329}
330
331//______________________________________________________________________________
332Double_t AliAODVertex::RotatedCovMatrixXX(Double_t phi, Double_t theta) const
333{
334 // XX term of covariance matrix after rotation by phi around z-axis
335 // and, then, by theta around new y-axis
336
337 if (!fCovMatrix) {
338 //AliFatal("Covariance matrix not set");
339 return -999.;
340 }
341
342 Double_t covMatrix[6];
343
344 GetCovMatrix(covMatrix);
345
346 Double_t cp = TMath::Cos(phi);
347 Double_t sp = TMath::Sin(phi);
348 Double_t ct = TMath::Cos(theta);
349 Double_t st = TMath::Sin(theta);
350 return
351 covMatrix[0]*cp*cp*ct*ct // GetCovXX
352 +covMatrix[1]*2.*cp*sp*ct*ct // GetCovXY
353 +covMatrix[3]*2.*cp*ct*st // GetCovXZ
354 +covMatrix[2]*sp*sp*ct*ct // GetCovYY
355 +covMatrix[4]*2.*sp*ct*st // GetCovYZ
356 +covMatrix[5]*st*st; // GetCovZZ
357}
358
359//______________________________________________________________________________
360Double_t AliAODVertex::RotatedCovMatrixXY(Double_t phi, Double_t theta) const
361{
362 // XY term of covariance matrix after rotation by phi around z-axis
363 // and, then, by theta around new y-axis
364
365 if (!fCovMatrix) {
366 //AliFatal("Covariance matrix not set");
367 return -999.;
368 }
369
370 Double_t covMatrix[6];
371
372 GetCovMatrix(covMatrix);
373
374 Double_t cp = TMath::Cos(phi);
375 Double_t sp = TMath::Sin(phi);
376 Double_t ct = TMath::Cos(theta);
377 Double_t st = TMath::Sin(theta);
378 return
379 -covMatrix[0]*cp*sp*ct // GetCovXX
380 +covMatrix[1]*ct*(cp*cp-sp*sp) // GetCovXY
381 -covMatrix[3]*sp*st // GetCovXZ
382 +covMatrix[2]*cp*sp*ct // GetCovYY
383 +covMatrix[4]*cp*st; // GetCovYZ
384}
385
386//______________________________________________________________________________
387Double_t AliAODVertex::RotatedCovMatrixXZ(Double_t phi, Double_t theta) const
388{
389 // XZ term of covariance matrix after rotation by phi around z-axis
390 // and, then, by theta around new y-axis
391
392 if (!fCovMatrix) {
393 //AliFatal("Covariance matrix not set");
394 return -999.;
395 }
396
397 Double_t covMatrix[6];
398
399 GetCovMatrix(covMatrix);
400
401 Double_t cp = TMath::Cos(phi);
402 Double_t sp = TMath::Sin(phi);
403 Double_t ct = TMath::Cos(theta);
404 Double_t st = TMath::Sin(theta);
405 return
406 -covMatrix[0]*cp*cp*ct*st // GetCovXX
407 -covMatrix[1]*2.*cp*sp*ct*st // GetCovXY
408 +covMatrix[3]*cp*(ct*ct-st*st) // GetCovXZ
409 -covMatrix[2]*sp*sp*ct*st // GetCovYY
410 +covMatrix[4]*sp*(ct*ct-st*st) // GetCovYZ
411 +covMatrix[5]*ct*st; // GetCovZZ
412}
413
414//______________________________________________________________________________
415Double_t AliAODVertex::RotatedCovMatrixYY(Double_t phi) const
416{
417 // YY term of covariance matrix after rotation by phi around z-axis
418 // and, then, by theta around new y-axis
419
420 if (!fCovMatrix) {
421 //AliFatal("Covariance matrix not set");
422 return -999.;
423 }
424
425 Double_t covMatrix[6];
426
427 GetCovMatrix(covMatrix);
428
429 Double_t cp = TMath::Cos(phi);
430 Double_t sp = TMath::Sin(phi);
431 return
432 covMatrix[0]*sp*sp // GetCovXX
433 -covMatrix[1]*2.*cp*sp // GetCovXY
434 +covMatrix[2]*cp*cp; // GetCovYY
435}
436
437//______________________________________________________________________________
438Double_t AliAODVertex::RotatedCovMatrixYZ(Double_t phi, Double_t theta) const
439{
440 // YZ term of covariance matrix after rotation by phi around z-axis
441 // and, then, by theta around new y-axis
442
443 if (!fCovMatrix) {
444 //AliFatal("Covariance matrix not set");
445 return -999.;
446 }
447
448 Double_t covMatrix[6];
449
450 GetCovMatrix(covMatrix);
451
452 Double_t cp = TMath::Cos(phi);
453 Double_t sp = TMath::Sin(phi);
454 Double_t ct = TMath::Cos(theta);
455 Double_t st = TMath::Sin(theta);
456 return
457 covMatrix[0]*cp*sp*st // GetCovXX
458 +covMatrix[1]*st*(sp*sp-cp*cp) // GetCovXY
459 -covMatrix[3]*sp*ct // GetCovXZ
460 -covMatrix[2]*cp*sp*st // GetCovYY
461 +covMatrix[4]*cp*ct; // GetCovYZ
462}
463
464//______________________________________________________________________________
465Double_t AliAODVertex::RotatedCovMatrixZZ(Double_t phi, Double_t theta) const
466{
467 // ZZ term of covariance matrix after rotation by phi around z-axis
468 // and, then, by theta around new y-axis
469
470 if (!fCovMatrix) {
471 //AliFatal("Covariance matrix not set");
472 return -999.;
473 }
474
475 Double_t covMatrix[6];
476
477 GetCovMatrix(covMatrix);
478
479 Double_t cp = TMath::Cos(phi);
480 Double_t sp = TMath::Sin(phi);
481 Double_t ct = TMath::Cos(theta);
482 Double_t st = TMath::Sin(theta);
483 return
484 covMatrix[0]*cp*cp*st*st // GetCovXX
485 +covMatrix[1]*2.*cp*sp*st*st // GetCovXY
486 -covMatrix[3]*2.*cp*ct*st // GetCovXZ
487 +covMatrix[2]*sp*sp*st*st // GetCovYY
488 -covMatrix[4]*2.*sp*sp*ct*st // GetCovYZ
489 +covMatrix[5]*ct*ct; // GetCovZZ
490}
491
492//______________________________________________________________________________
5e6a3170 493Double_t AliAODVertex::Distance2ToVertex(const AliAODVertex *vtx) const
df9db588 494{
495 // distance in 3D to another AliAODVertex
496
497 Double_t dx = GetX()-vtx->GetX();
498 Double_t dy = GetY()-vtx->GetY();
499 Double_t dz = GetZ()-vtx->GetZ();
500
6766c805 501 return dx*dx+dy*dy+dz*dz;
df9db588 502}
503
504//______________________________________________________________________________
5e6a3170 505Double_t AliAODVertex::DistanceXY2ToVertex(const AliAODVertex *vtx) const
df9db588 506{
507 // distance in XY to another AliAODVertex
508
509 Double_t dx = GetX()-vtx->GetX();
510 Double_t dy = GetY()-vtx->GetY();
511
6766c805 512 return dx*dx+dy*dy;
df9db588 513}
514
515//______________________________________________________________________________
6766c805 516Double_t AliAODVertex::Error2DistanceToVertex(AliAODVertex *vtx) const
df9db588 517{
518 // error on the distance in 3D to another AliAODVertex
519
520 Double_t phi,theta;
521 PhiAndThetaToVertex(vtx,phi,theta);
522 // error2 due to this vertex
523 Double_t error2 = RotatedCovMatrixXX(phi,theta);
524 // error2 due to vtx vertex
525 Double_t error2vtx = vtx->RotatedCovMatrixXX(phi,theta);
526
6766c805 527 return error2+error2vtx;
df9db588 528}
529
530//______________________________________________________________________________
6766c805 531Double_t AliAODVertex::Error2DistanceXYToVertex(AliAODVertex *vtx) const
df9db588 532{
533 // error on the distance in XY to another AliAODVertex
534
535 Double_t phi,theta;
536 PhiAndThetaToVertex(vtx,phi,theta);
537 // error2 due to this vertex
538 Double_t error2 = RotatedCovMatrixXX(phi);
539 // error2 due to vtx vertex
540 Double_t error2vtx = vtx->RotatedCovMatrixXX(phi);
541
6766c805 542 return error2+error2vtx;
df9db588 543}
544
545//______________________________________________________________________________
546template <class T, class P>
547void AliAODVertex::PhiAndThetaToVertex(AliAODVertex *vtx, P &phi, T &theta) const
548{
549 // rotation angles around z-axis (phi) and around new y-axis (theta)
550 // with which vtx is seen (used by RotatedCovMatrix... methods)
551
b1a9edc8 552 phi = TMath::Pi()+TMath::ATan2(-vtx->GetY()+GetY(),-vtx->GetX()+GetX());
df9db588 553 Double_t vtxxphi = vtx->GetX()*TMath::Cos(phi)+vtx->GetY()*TMath::Sin(phi);
554 Double_t xphi = GetX()*TMath::Cos(phi)+GetY()*TMath::Sin(phi);
555 theta = TMath::ATan2(vtx->GetZ()-GetZ(),vtxxphi-xphi);
556}
557
558//______________________________________________________________________________
559void AliAODVertex::PrintIndices() const
560{
561 // Print indices of particles originating form this vertex
562
563 TRefArrayIter iter(&fDaughters);
564 while (TObject *daugh = iter.Next()) {
f12d42ce 565 printf("Particle %p originates from this vertex.\n", static_cast<void*>(daugh));
df9db588 566 }
567}
568
26ba01d4 569//______________________________________________________________________________
570const char* AliAODVertex::AsString() const
571{
572 // Make a string describing this object
573
574 TString tmp(Form("%10s pos(%7.2f,%7.2f,%7.2f)",GetTypeName((AODVtx_t)GetType()),GetX(),GetY(),GetZ()));
575
576 if (GetType()==kPrimary || GetType()==kMainSPD || GetType()==kPileupSPD )
577 {
578 tmp += Form(" ncontrib %d chi2/ndf %4.1f",GetNContributors(),GetChi2perNDF());
579
580 }
581
582 if ( !fParent.GetObject() )
583 {
584 tmp += " no parent";
585 }
586 if ( fDaughters.GetEntriesFast() > 0 )
587 {
588 if ( fDaughters.GetEntriesFast() == 1 )
589 {
590 tmp += " origin of 1 particle";
591 }
592 else
593 {
594 tmp += Form(" origin of %2d particles",fDaughters.GetEntriesFast());
595 }
596 }
597
598 return tmp.Data();
599}
600
601//______________________________________________________________________________
602const char* AliAODVertex::GetTypeName(AODVtx_t type)
603{
604 // Return an ASCII version of type
605
606 switch (type)
607 {
608 case kPrimary:
609 return "primary";
610 break;
611 case kKink:
612 return "kink";
613 break;
614 case kV0:
615 return "v0";
616 break;
617 case kCascade:
618 return "cascade";
619 break;
620 case kMainSPD:
621 return "mainSPD";
622 break;
623 case kPileupSPD:
624 return "pileupSPD";
625 break;
626 case kPileupTracks:
627 return "pileupTRK";
628 break;
629 case kMainTPC:
630 return "mainTPC";
631 break;
632 default:
633 return "unknown";
634 break;
635 };
636}
637
df9db588 638//______________________________________________________________________________
639void AliAODVertex::Print(Option_t* /*option*/) const
640{
641 // Print information of all data members
642
643 printf("Vertex position:\n");
644 printf(" x = %f\n", fPosition[0]);
645 printf(" y = %f\n", fPosition[1]);
646 printf(" z = %f\n", fPosition[2]);
f12d42ce 647 printf(" parent particle: %p\n", static_cast<void*>(fParent.GetObject()));
df9db588 648 printf(" origin of %d particles\n", fDaughters.GetEntriesFast());
649 printf(" vertex type %d\n", fType);
650
651 /*
652 if (fCovMatrix) {
653 printf("Covariance matrix:\n");
654 printf(" %12.10f %12.10f %12.10f\n %12.10f %12.10f %12.10f\n %12.10f %12.10f %12.10f\n",
655 fCovMatrix[0],
656 fCovMatrix[1],
657 fCovMatrix[3],
658 fCovMatrix[1],
659 fCovMatrix[2],
660 fCovMatrix[4],
661 fCovMatrix[3],
662 fCovMatrix[4],
663 fCovMatrix[5]);
664 } */
0657f082 665 printf(" Chi^2/NDF = %f\n", fChi2perNDF);
df9db588 666}
667