00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00012
00013 #include "DeMux/DmxUtilities.h"
00014 #include "MessageService/MsgService.h"
00015 #include "MessageService/MsgFormat.h"
00016 #include "Navigation/NavKey.h"
00017 #include "Navigation/NavSet.h"
00018 #include "DeMux/DmxHypothesis.h"
00019 #include "DeMux/DmxShowerPlane.h"
00020 #include "DeMux/DmxMuonPlane.h"
00021 #include "DeMux/DmxStatus.h"
00022 #include "TMath.h"
00023 #include "TH2.h"
00024 #include "TMatrix.h"
00025 #include "Conventions/Munits.h"
00026 #include "Conventions/PlaneView.h"
00027 #include "Conventions/StripEnd.h"
00028 #include "Algorithm/AlgConfig.h"
00029 #include "CandDigit/CandDeMuxDigit.h"
00030 #include "CandDigit/CandDeMuxDigitHandle.h"
00031
00032
00033 static NavKey KeyFromPlane( const CandDeMuxDigitHandle *cdh){
00034 return cdh->GetPlexSEIdAltL().GetPlane();}
00035
00036
00037 ClassImp(DmxUtilities)
00038
00039 CVSID("$Id: DmxUtilities.cxx,v 1.36 2004/11/03 22:22:49 brebel Exp $");
00040
00041
00042 DmxUtilities::DmxUtilities()
00043 {
00044 }
00045
00046
00047 void DmxUtilities::FillPlaneArray(DmxStatus *status,
00048 CandDeMuxDigitListHandle &cdlh, AlgConfig &acd)
00049 {
00050
00051 TObjArray *planeArray = new TObjArray();
00052 MSG("DmxUtil", Msg::kDebug) << cdlh.GetNDaughters() << " digits in DmxUtil" << endl;
00053
00054
00055
00056 CandDeMuxDigitHandleItr fCdhit = cdlh.GetDaughterIterator();
00057
00058
00059 CandDeMuxDigitHandleKeyFunc *planeKF = fCdhit.CreateKeyFunc();
00060
00061
00062 planeKF->SetFun(KeyFromPlane);
00063
00064
00065 fCdhit.GetSet()->AdoptSortKeyFunc(planeKF);
00066
00067
00068 planeKF = 0;
00069
00070
00071 Int_t planeNum = 0;
00072
00073
00074
00075 CandDeMuxDigitHandle *currentDigit = 0;
00076 CandDeMuxDigitHandle *digit = 0;
00077
00078
00079 while( (currentDigit = fCdhit()) ){
00080
00081 Int_t plane = 0;
00082
00083
00084 plane = currentDigit->GetPlexSEIdAltL().GetPlane();
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094 if(plane != planeNum && !currentDigit->GetPlexSEIdAltL().IsVetoShield()){
00095
00096 planeNum = plane;
00097
00098
00099
00100
00101 CandDeMuxDigitHandleItr planeCdhit(cdlh.GetDaughterIterator());
00102 CandDeMuxDigitHandleKeyFunc *plane1KF = planeCdhit.CreateKeyFunc();
00103 plane1KF->SetFun(KeyFromPlane);
00104 planeCdhit.GetSet()->AdoptSortKeyFunc(plane1KF,true,false);
00105 plane1KF = 0;
00106
00107
00108 planeCdhit.GetSet()->Slice(planeNum);
00109 planeCdhit.GetSet()->Update();
00110
00111 Int_t numDigits = 0;
00112 if( acd.GetInt("UseCandDigitMask")==1 ){
00113
00114
00115
00116 Float_t eastSet0[] = {0., 0., 0., 0., 0., 0., 0., 0.,
00117 0., 0., 0., 0., 0., 0., 0., 0.};
00118 Float_t westSet0[] = {0., 0., 0., 0., 0., 0., 0., 0.,
00119 0., 0., 0., 0., 0., 0., 0., 0.};
00120 Float_t eastSet1[] = {0., 0., 0., 0., 0., 0., 0., 0.,
00121 0., 0., 0., 0., 0., 0., 0., 0.};
00122 Float_t westSet1[] = {0., 0., 0., 0., 0., 0., 0., 0.,
00123 0., 0., 0., 0., 0., 0., 0., 0.};
00124 Float_t eastSet2[] = {0., 0., 0., 0., 0., 0., 0., 0.,
00125 0., 0., 0., 0., 0., 0., 0., 0.};
00126 Float_t westSet2[] = {0., 0., 0., 0., 0., 0., 0., 0.,
00127 0., 0., 0., 0., 0., 0., 0., 0.};
00128
00129 FillHitPixels(planeCdhit, 0, eastSet0, westSet0);
00130 FillHitPixels(planeCdhit, 1, eastSet1, westSet1);
00131 FillHitPixels(planeCdhit, 2, eastSet2, westSet2);
00132 Int_t pixel = -1;
00133 Float_t crossTalk = 0.;
00134
00135 numDigits = planeCdhit.SizeSelect();
00136
00137
00138
00139
00140
00141 while( (digit = planeCdhit()) ){
00142
00143 pixel = GetDigitPixel(digit->GetChannelId().GetVaChannel());
00144 crossTalk = 0.;
00145
00146 currentDigit->GetPlexSEIdAltLWritable().SetDemuxVetoFlag(1);
00147
00148 if(digit->GetCharge()
00149 <acd.GetDouble("AveragePEGainConversion")*acd.GetDouble("IgnoreSignalLimit")){
00150 digit->SetDeMuxDigitFlagBit(CandDeMuxDigit::kLowSignal);
00151
00152
00153 --numDigits;
00154 }
00155
00156 if( digit->GetPlexSEIdAltL().GetEnd() == StripEnd::kEast
00157 && digit->GetDeMuxDigitFlagWord() == 0){
00158
00159 if(digit->GetChannelId().GetVaChip() == 0)
00160 crossTalk = CheckForXTalk(pixel, eastSet0);
00161 else if(digit->GetChannelId().GetVaChip() == 1)
00162 crossTalk = CheckForXTalk(pixel, eastSet1);
00163 else if(digit->GetChannelId().GetVaChip() == 2)
00164 crossTalk = CheckForXTalk(pixel, eastSet2);
00165
00166
00167 if(digit->GetCharge()<(acd.GetDouble("XTalkFractionLimit")*crossTalk)){
00168 digit->SetDeMuxDigitFlagBit(CandDeMuxDigit::kXTalk);
00169 --numDigits;
00170
00171
00172 }
00173 }
00174 else if( digit->GetPlexSEIdAltL().GetEnd() == StripEnd::kWest &&
00175 digit->GetDeMuxDigitFlagWord() == 0){
00176
00177 if(digit->GetChannelId().GetVaChip() == 0)
00178 crossTalk = CheckForXTalk(pixel, westSet0);
00179 else if(digit->GetChannelId().GetVaChip() == 1)
00180 crossTalk = CheckForXTalk(pixel, westSet1);
00181 else if(digit->GetChannelId().GetVaChip() == 2)
00182 crossTalk = CheckForXTalk(pixel, westSet2);
00183
00184
00185 if(digit->GetCharge()<(acd.GetDouble("XTalkFractionLimit")*crossTalk)){
00186 digit->SetDeMuxDigitFlagBit(CandDeMuxDigit::kXTalk);
00187 --numDigits;
00188
00189
00190 }
00191 }
00192
00193 }
00194 }
00195
00196
00197 else numDigits = planeCdhit.SizeSelect();
00198
00199 planeCdhit.ResetFirst();
00200
00201
00202
00203
00204
00205 if(numDigits > 2 && planeNum>-1){
00206 planeArray->AddLast(new DmxShowerPlane(acd, planeCdhit, planeNum));
00207
00208
00209 }
00210 else if(numDigits<=2 && planeNum>-1){
00211 planeArray->AddLast(new DmxMuonPlane(acd, planeCdhit, planeNum));
00212
00213
00214 }
00215
00216
00217 planeCdhit.GetSet()->ClearSlice(false);
00218
00219 }
00220
00221 }
00222
00223
00224 status->SetPlaneArray(planeArray);
00225
00226
00227
00228 planeArray = 0;
00229
00230
00231 return;
00232 }
00233
00234
00235 DmxUtilities::~DmxUtilities()
00236 {
00237
00238 }
00239
00240
00241 Float_t DmxUtilities::CheckForXTalk(Int_t pixel, Float_t *planeSet)
00242 {
00243
00244
00245 Float_t crossTalk = -1.;
00246
00247 if(pixel == 0){
00248 crossTalk = planeSet[1] + planeSet[4];
00249 }
00250 if(pixel == 1) {
00251 crossTalk = planeSet[0] + planeSet[2] + planeSet[5];
00252 }
00253 if(pixel == 2){
00254 crossTalk = planeSet[1] + planeSet[3] + planeSet[6];
00255 }
00256 if(pixel == 3){
00257 crossTalk = planeSet[2] + planeSet[7];
00258 }
00259 if(pixel == 4){
00260 crossTalk = planeSet[0] + planeSet[5] + planeSet[8];
00261 }
00262 if(pixel == 5){
00263 crossTalk = planeSet[1] + planeSet[4] + planeSet[6] + planeSet[9];
00264 }
00265 if(pixel == 6){
00266 crossTalk = planeSet[2] + planeSet[5] + planeSet[7] + planeSet[10];
00267 }
00268 if(pixel == 7){
00269 crossTalk = planeSet[3] + planeSet[6] + planeSet[11];
00270 }
00271 if(pixel == 8){
00272 crossTalk = planeSet[4] + planeSet[9] + planeSet[12];
00273 }
00274 if(pixel == 9){
00275 crossTalk = planeSet[5] + planeSet[8] + planeSet[10] + planeSet[13];
00276 }
00277 if(pixel == 10){
00278 crossTalk = planeSet[6] + planeSet[9] + planeSet[11] + planeSet[14];
00279 }
00280 if(pixel == 11){
00281 crossTalk = planeSet[7] + planeSet[10] + planeSet[15];
00282
00283
00284
00285
00286
00287 }
00288 if(pixel == 12){
00289 crossTalk = planeSet[8] + planeSet[13];
00290 }
00291 if(pixel == 13){
00292 crossTalk = planeSet[9] + planeSet[12] + planeSet[14];
00293 }
00294 if(pixel == 14){
00295 crossTalk = planeSet[10] + planeSet[13] + planeSet[15];
00296
00297
00298
00299
00300
00301 }
00302 if(pixel == 15){
00303 crossTalk = planeSet[11] + planeSet[14];
00304 }
00305
00306 return crossTalk;
00307 }
00308
00309
00310 Int_t DmxUtilities::GetDigitPixel(Int_t channel)
00311 {
00312
00313
00314
00315
00316 Int_t vaChip0[] = {-1, -1, 14, 0, 15, 1, 10, 4, 11,
00317 5, 6, 8, 7, 9, 2, 13, 3, 12};
00318
00319
00320
00321
00322
00323 Int_t pixel = vaChip0[channel];
00324
00325
00326
00327
00328
00329 return pixel;
00330 }
00331
00332
00333 void DmxUtilities::FillHitPixels(CandDeMuxDigitHandleItr crdhi, Int_t chip,
00334 Float_t *eastSet, Float_t *westSet)
00335 {
00336 Int_t pixel = -1;
00337
00338 while( crdhi.IsValid() ){
00339
00340
00341 CandDeMuxDigitHandle *digit = crdhi.Ptr();
00342 Int_t digitChip = digit->GetChannelId().GetVaChip();
00343 Int_t channel = digit->GetChannelId().GetVaChannel();
00344 pixel = GetDigitPixel(channel);
00345 Float_t charge = digit->GetCharge();
00346
00347 if( digitChip == chip){
00348 if(digit->GetPlexSEIdAltL().GetEnd() == StripEnd::kEast){
00349 eastSet[pixel] += charge;
00350 }
00351 if(digit->GetPlexSEIdAltL().GetEnd() == StripEnd::kWest){
00352 westSet[pixel] += charge;
00353 }
00354 }
00355
00356
00357
00358 crdhi.Next();
00359 }
00360
00361 crdhi.ResetFirst();
00362 return;
00363 }
00364
00365
00366
00367 Int_t DmxUtilities::FindVertexPlane(DmxPlaneItr &planeItr)
00368 {
00369 MSG("DmxUtil", Msg::kDebug) << "In FindVertexPlane" << endl;
00370
00371 planeItr.ResetFirst();
00372
00373 Int_t vertexPlaneNumber = -1;
00374 Int_t firstPlaneNumber = 0;
00375 if( planeItr.IsValid() )
00376 firstPlaneNumber = planeItr.Ptr()->GetPlaneNumber();
00377
00378 planeItr.ResetFirst();
00379
00380
00381
00382
00383 Int_t beginPlaneNumber = 0;
00384 Int_t endPlaneNumber = 0;
00385 Int_t validCtr = 0;
00386 Int_t cnt = 0;
00387
00388 while( planeItr.IsValid() ){
00389
00390 beginPlaneNumber = planeItr.Ptr()->GetPlaneNumber();
00391 endPlaneNumber = 0;
00392 validCtr = 0;
00393
00394 cnt = 0;
00395 while( planeItr.IsValid() && cnt < 5 && validCtr < 3){
00396 if( planeItr.Ptr()->IsValid() ){ ++validCtr;}
00397 ++cnt;
00398 endPlaneNumber = planeItr.Ptr()->GetPlaneNumber();
00399 MSG("DmxUtil", Msg::kDebug)<<"Start Plane = " << beginPlaneNumber
00400 << "\tThis Plane = "
00401 << endPlaneNumber << "\tValid = "
00402 << (Int_t)planeItr.Ptr()->IsValid()
00403 << "\tValidCtr = " << validCtr << endl;
00404 planeItr.Next();
00405 }
00406
00407 if( validCtr >= 3 && (endPlaneNumber-beginPlaneNumber) <= 5 ){
00408 vertexPlaneNumber = beginPlaneNumber;
00409 MSG("DmxUtil", Msg::kDebug)<<"\tVertex Plane = " << vertexPlaneNumber << endl;
00410 break;
00411 }
00412 else{
00413 for(Int_t a = 0; a < cnt-1; a++){
00414 planeItr.Prev();
00415 }
00416 }
00417 }
00418
00419
00420
00421
00422
00423 planeItr.Reset();
00424 planeItr.GetSet()->ClearSlice(false);
00425
00426 Int_t nextPlane = 0;
00427
00428 if( vertexPlaneNumber > -1 && firstPlaneNumber < vertexPlaneNumber){
00429 planeItr.GetSet()->Slice(firstPlaneNumber, vertexPlaneNumber);
00430 planeItr.GetSet()->Update();
00431
00432 planeItr.ResetLast();
00433
00434 while( planeItr.IsValid() ){
00435
00436 Int_t currentPlane = planeItr.Ptr()->GetPlaneNumber();
00437 MSG("DmxUtil", Msg::kDebug) << "\tcurrentPlaneNumber = " << currentPlane;
00438 planeItr.Prev();
00439 nextPlane = 0;
00440 if(planeItr.IsValid()){
00441 nextPlane = planeItr.Ptr()->GetPlaneNumber();
00442 MSG("DmxUtil", Msg::kDebug) << "\tnextPlaneNumber = " << nextPlane << endl;
00443
00444 if( vertexPlaneNumber - nextPlane < 3)
00445 vertexPlaneNumber = nextPlane;
00446 else break;
00447 }
00448
00449 }
00450
00451 planeItr.GetSet()->ClearSlice(false);
00452 planeItr.ResetFirst();
00453 }
00454
00455 planeItr.GetSet()->ClearSlice(false);
00456 planeItr.ResetFirst();
00457
00458 MSG("DmxUtil", Msg::kDebug) << "\tvertexPlaneNumber = " << vertexPlaneNumber << endl;
00459 return vertexPlaneNumber;
00460 }
00461
00462
00463 Int_t DmxUtilities::FindEndPlane(DmxPlaneItr &planeItr)
00464 {
00465 Int_t endPlaneNumber = 500;
00466
00467 while( planeItr.IsValid() && endPlaneNumber == 500){
00468 Int_t planeNumber = planeItr.Ptr()->GetPlaneNumber();
00469
00470 planeItr.Next();
00471 if( planeItr.IsValid() ){
00472
00473
00474 if( TMath::Abs(planeItr.Ptr()->GetPlaneNumber()
00475 - planeNumber) >= 5 ){ endPlaneNumber = planeNumber; }
00476 }
00477 else{
00478
00479 endPlaneNumber = planeNumber;
00480 }
00481 }
00482
00483 return endPlaneNumber;
00484 }
00485
00486
00487 Int_t DmxUtilities::FindMuonStartPlane(DmxPlaneItr &planeItr, Float_t peGainConversion)
00488 {
00489
00490
00491
00492
00493
00494
00495
00496 Int_t fMuonStartPlaneNumber = -1;
00497
00498 Int_t ctr = 0;
00499 Int_t muonCtr = 0;
00500 Int_t startPlane = 0;
00501 Int_t endPlane = 0;
00502 Int_t peCtr = 0;
00503
00504 DmxPlane *currentPlane = 0;
00505
00506 while( (currentPlane = planeItr()) ){
00507
00508 MSG("DmxUtilities", Msg::kDebug) << "plane " << currentPlane->GetPlaneNumber()
00509 << " type " << DmxPlaneTypes::GetPlaneTypeString(currentPlane->GetPlaneType())
00510 << " charge " << currentPlane->GetPlaneCharge()
00511 << " strips " << currentPlane->GetNumberOfStrips()
00512 << " is valid " << (Int_t)currentPlane->IsValid() << endl;
00513 }
00514
00515 planeItr.ResetFirst();
00516
00517 while(planeItr.IsValid() && fMuonStartPlaneNumber == -1){
00518 ctr = 0;
00519
00520 muonCtr = 0;
00521 startPlane = planeItr.Ptr()->GetPlaneNumber();
00522 endPlane = startPlane+10;
00523 peCtr = 0;
00524
00525 MSG("DmxUtilities", Msg::kDebug) << "plane number " << startPlane
00526 << " charge " << planeItr.Ptr()->GetPlaneCharge()
00527 << " type "
00528 << DmxPlaneTypes::GetPlaneTypeString(planeItr.Ptr()->GetPlaneType())
00529 << endl;
00530 planeItr.Next();
00531
00532
00533 while(ctr < 4 && planeItr.IsValid() ){
00534 currentPlane = planeItr.Ptr();
00535
00536 MSG("DmxUtilities", Msg::kDebug) << "plane number " << currentPlane->GetPlaneNumber()
00537 << " charge " << currentPlane->GetPlaneCharge()
00538 << " type "
00539 << DmxPlaneTypes::GetPlaneTypeString(currentPlane->GetPlaneType())
00540 << " num strips " << currentPlane->GetNumberOfStrips()
00541 << endl;
00542 endPlane = currentPlane->GetPlaneNumber();
00543
00544
00545 if( currentPlane->GetNumberOfStrips() < 3 ) ++muonCtr;
00546
00547 if(currentPlane->GetPlaneCharge() > (peGainConversion * 3.)) ++peCtr;
00548
00549 MSG("DmxUtilities", Msg::kDebug) << " muon planes = " << muonCtr
00550 << " peCtr = " << peCtr << endl;
00551 planeItr.Next();
00552 ++ctr;
00553 }
00554
00555 if(muonCtr == 4 && peCtr >= 3 && endPlane-startPlane<=5)
00556 fMuonStartPlaneNumber = startPlane;
00557
00558
00559
00560 if(planeItr.IsValid() ){
00561 planeItr.Prev();
00562 planeItr.Prev();
00563 planeItr.Prev();
00564 planeItr.Prev();
00565 }
00566 }
00567
00568 planeItr.GetSet()->ClearSlice(false);
00569 planeItr.Reset();
00570
00571 return fMuonStartPlaneNumber;
00572 }
00573
00574
00575 Int_t DmxUtilities::FindBeamMuonStartPlane(DmxPlaneItr &planeItr, Float_t peGainConversion)
00576 {
00577
00578
00579
00580
00581
00582
00583
00584 Int_t fMuonStartPlaneNumber = -1;
00585
00586 Int_t ctr = 0;
00587 Int_t muonCtr = 0;
00588 Int_t startPlane = 0;
00589 Int_t endPlane = 0;
00590 Int_t peCtr = 0;
00591 Int_t lastEventPlane = 0;
00592
00593 DmxPlane *currentPlane = 0;
00594
00595 while( (currentPlane = planeItr()) ){
00596
00597 MSG("DmxUtilities", Msg::kDebug) << "plane " << currentPlane->GetPlaneNumber()
00598 << " type " << DmxPlaneTypes::GetPlaneTypeString(currentPlane->GetPlaneType())
00599 << " charge " << currentPlane->GetPlaneCharge()
00600 << " strips " << currentPlane->GetNumberOfStrips()
00601 << " is valid " << (Int_t)currentPlane->IsValid() << endl;
00602
00603 lastEventPlane = currentPlane->GetPlaneNumber();
00604 }
00605
00606 planeItr.ResetFirst();
00607
00608 while(planeItr.IsValid() && fMuonStartPlaneNumber == -1){
00609 ctr = 0;
00610
00611 muonCtr = 0;
00612 startPlane = planeItr.Ptr()->GetPlaneNumber();
00613 endPlane = startPlane+10;
00614 peCtr = 0;
00615
00616 MSG("DmxUtilities", Msg::kDebug) << "plane number " << startPlane
00617 << " charge " << planeItr.Ptr()->GetPlaneCharge()
00618 << " type "
00619 << DmxPlaneTypes::GetPlaneTypeString(planeItr.Ptr()->GetPlaneType())
00620 << endl;
00621 planeItr.Next();
00622
00623
00624 while(ctr < 4 && planeItr.IsValid() ){
00625 currentPlane = planeItr.Ptr();
00626
00627 MSG("DmxUtilities", Msg::kDebug) << "plane number " << currentPlane->GetPlaneNumber()
00628 << " charge " << currentPlane->GetPlaneCharge()
00629 << " type "
00630 << DmxPlaneTypes::GetPlaneTypeString(currentPlane->GetPlaneType())
00631 << " num strips " << currentPlane->GetNumberOfStrips()
00632 << endl;
00633 endPlane = currentPlane->GetPlaneNumber();
00634
00635
00636 if( currentPlane->GetNumberOfStrips() < 3 ) ++muonCtr;
00637
00638 if(currentPlane->GetPlaneCharge() > (peGainConversion * 3.)) ++peCtr;
00639
00640 MSG("DmxUtilities", Msg::kDebug) << " muon planes = " << muonCtr
00641 << " peCtr = " << peCtr << endl;
00642 planeItr.Next();
00643 ++ctr;
00644 }
00645
00646 if(muonCtr == 4 && peCtr >= 3 && endPlane-startPlane<=5)
00647 fMuonStartPlaneNumber = startPlane;
00648
00649
00650
00651 if(planeItr.IsValid() ){
00652 planeItr.Prev();
00653 planeItr.Prev();
00654 planeItr.Prev();
00655 planeItr.Prev();
00656 }
00657 }
00658
00659
00660
00661
00662
00663 planeItr.GetSet()->ClearSlice(false);
00664
00665 planeItr.GetSet()->Slice(fMuonStartPlaneNumber, lastEventPlane);
00666 planeItr.GetSet()->Update();
00667 planeItr.ResetFirst();
00668
00669 Int_t numShowerPlanes = 0;
00670 Int_t numMuonPlanes = 0;
00671 while( (currentPlane = planeItr()) ){
00672
00673 if(currentPlane->GetPlaneType() == DmxPlaneTypes::kShower
00674 && currentPlane->GetNumberOfStrips()>2) ++numShowerPlanes;
00675 else ++numMuonPlanes;
00676
00677 }
00678
00679 if(1.*numShowerPlanes>0.25*numMuonPlanes) fMuonStartPlaneNumber = -1;
00680
00681 planeItr.GetSet()->ClearSlice(false);
00682
00683 return fMuonStartPlaneNumber;
00684 }
00685
00686
00687
00688
00689 Bool_t DmxUtilities::IsValidFit(DmxPlaneItr &planeItr, Double_t a1, Double_t a2,
00690 Double_t a3, Double_t a4, Float_t offset)
00691 {
00692 Int_t nonPhysicalCtr = 0;
00693 bool validFit = true;
00694 Int_t planesInEvent = planeItr.SizeSelect();
00695
00696 planeItr.Reset();
00697
00698 DmxPlane *plane = 0;
00699 Double_t fitCoG = 0.;
00700
00701 while( planeItr.IsValid() ){
00702
00703 plane = planeItr.Ptr();
00704
00705 fitCoG = (a1 + a2*(plane->GetZPosition()-offset)
00706 + a3*TMath::Power(plane->GetZPosition()-offset,2)
00707 + a4*TMath::Power(plane->GetZPosition()-offset,3));
00708
00709
00710
00711 if( TMath::Abs(fitCoG) >= 4.5) ++nonPhysicalCtr;
00712
00713 planeItr.Next();
00714 }
00715
00716 planeItr.Reset();
00717
00718 if(planesInEvent<8 && (1.*nonPhysicalCtr)/(1.*planesInEvent)>0.33) validFit = false;
00719 else if(planesInEvent>=8 && nonPhysicalCtr>=4) validFit = false;
00720
00721 return validFit;
00722 }
00723
00724
00725
00726 Bool_t DmxUtilities::IsValidFit(DmxPlaneItr &planeItr, Double_t a1, Double_t a2,
00727 Double_t a3, Double_t a4)
00728 {
00729 Int_t nonPhysicalCtr = 0;
00730 bool validFit = true;
00731 Int_t planesInEvent = planeItr.SizeSelect();
00732
00733 planeItr.Reset();
00734
00735 DmxPlane *plane = 0;
00736 Double_t fitCoG = 0.;
00737
00738 while( planeItr.IsValid() ){
00739
00740 plane = planeItr.Ptr();
00741
00742 fitCoG = (a1 + a2*(plane->GetZPosition())
00743 + a3*TMath::Power(plane->GetZPosition(),2)
00744 + a4*TMath::Power(plane->GetZPosition(),3));
00745
00746
00747
00748 if( TMath::Abs(fitCoG) >= 4.5) ++nonPhysicalCtr;
00749
00750 planeItr.Next();
00751 }
00752
00753 planeItr.Reset();
00754
00755 if(planesInEvent<8 && (1.*nonPhysicalCtr)/(1.*planesInEvent)>0.33) validFit = false;
00756 else if(planesInEvent>=8 && nonPhysicalCtr>=4) validFit = false;
00757
00758 return validFit;
00759 }
00760
00761
00762
00763
00764 Int_t DmxUtilities::CheckFit(DmxPlaneItr &planeItr)
00765 {
00766 DmxPlane *plane = 0;
00767
00768
00769
00770
00771
00772 Float_t firstBestMated = 0.;
00773 Float_t firstSMated = 0.;
00774 Float_t firstTMated = 0.;
00775 Float_t firstMated = 0.;
00776 Float_t lastBestMated = 0.;
00777 Float_t lastSMated = 0.;
00778 Float_t lastTMated = 0.;
00779 Float_t lastMated = 0.;
00780
00781 Int_t ctr = 0;
00782 Int_t totPlanes = planeItr.SizeSelect();
00783 Int_t fixedPlanes = 0;
00784 planeItr.ResetFirst();
00785
00786
00787 Float_t firstPlaneCoG = -1.;
00788 Float_t firstPlaneBCoG = -1.;
00789 Float_t firstPlaneSCoG = -1.;
00790 Float_t firstPlaneTCoG = -1.;
00791 Float_t lastPlaneCoG = -1.;
00792 Float_t lastPlaneBCoG = -1.;
00793 Float_t lastPlaneSCoG = -1.;
00794 Float_t lastPlaneTCoG = -1.;
00795 Float_t firstPlaneSpace = 0.;
00796 Float_t lastPlaneSpace = 0.;
00797
00798 while(planeItr.IsValid()){
00799
00800 plane = planeItr.Ptr();
00801 if(ctr == 0){
00802 firstPlaneCoG = plane->GetCoG();
00803 firstPlaneSpace = plane->GetPlaneNumber();
00804 if(plane->GetPlaneType() == DmxPlaneTypes::kShower){
00805
00806 firstPlaneBCoG = dynamic_cast<DmxShowerPlane *>(plane)->GetBestCoG();
00807 firstBestMated = dynamic_cast<DmxShowerPlane *>(plane)->GetBestHypothesis()->GetMatedSignalRatio();
00808
00809 firstPlaneSCoG = dynamic_cast<DmxShowerPlane *>(plane)->GetSecondBestCoG();
00810 firstSMated = dynamic_cast<DmxShowerPlane *>(plane)->GetSecondBestHypothesis()->GetMatedSignalRatio();
00811
00812 firstPlaneTCoG = dynamic_cast<DmxShowerPlane *>(plane)->GetThirdBestCoG();
00813 firstTMated = dynamic_cast<DmxShowerPlane *>(plane)->GetThirdBestHypothesis()->GetMatedSignalRatio();
00814
00815 firstMated = dynamic_cast<DmxShowerPlane *>(plane)->GetSetHypothesis()->GetMatedSignalRatio();
00816 }
00817 else if(plane->GetPlaneType() == DmxPlaneTypes::kMuon){
00818 firstPlaneBCoG = firstPlaneCoG;
00819 firstPlaneSCoG = firstPlaneCoG;
00820 firstPlaneTCoG = firstPlaneCoG;
00821 firstMated = 1.;
00822 firstBestMated = 1.;
00823 firstSMated = 1.;
00824 firstTMated = 1.;
00825 }
00826 }
00827 else if(ctr == 1) firstPlaneSpace -= plane->GetPlaneNumber();
00828 else if(ctr == totPlanes-2) lastPlaneSpace = plane->GetPlaneNumber();
00829 else if(ctr == totPlanes-1){
00830 lastPlaneCoG = plane->GetCoG();
00831 lastPlaneSpace -= plane->GetPlaneNumber();
00832 if(plane->GetPlaneType() == DmxPlaneTypes::kShower){
00833
00834 lastPlaneBCoG = dynamic_cast<DmxShowerPlane *>(plane)->GetBestCoG();
00835 lastBestMated = dynamic_cast<DmxShowerPlane *>(plane)->GetBestHypothesis()->GetMatedSignalRatio();
00836
00837 lastPlaneSCoG = dynamic_cast<DmxShowerPlane *>(plane)->GetSecondBestCoG();
00838 lastSMated = dynamic_cast<DmxShowerPlane *>(plane)->GetSecondBestHypothesis()->GetMatedSignalRatio();
00839
00840 lastPlaneTCoG = dynamic_cast<DmxShowerPlane *>(plane)->GetThirdBestCoG();
00841 lastTMated = dynamic_cast<DmxShowerPlane *>(plane)->GetThirdBestHypothesis()->GetMatedSignalRatio();
00842
00843 lastMated = dynamic_cast<DmxShowerPlane *>(plane)->GetSetHypothesis()->GetMatedSignalRatio();
00844 }
00845 else if(plane->GetPlaneType() == DmxPlaneTypes::kMuon){
00846 lastPlaneBCoG = lastPlaneCoG;
00847 lastPlaneSCoG = lastPlaneCoG;
00848 lastPlaneTCoG = lastPlaneCoG;
00849 lastMated = 1.;
00850 lastBestMated = 1.;
00851 lastSMated = 1.;
00852 lastTMated = 1.;
00853 }
00854 }
00855 ++ctr;
00856 planeItr.Next();
00857 }
00858 planeItr.ResetFirst();
00859
00860
00861 bool useFirstB = false;
00862 bool useFirstS = false;
00863 bool useFirstT = false;
00864 bool useLastB = false;
00865 bool useLastS = false;
00866 bool useLastT = false;
00867
00868 if(firstBestMated>=firstSMated && firstBestMated>=firstTMated
00869 && TMath::Abs(firstBestMated-firstMated)>0.2) useFirstB = true;
00870 else if(firstSMated>firstBestMated && firstSMated>=firstTMated
00871 && TMath::Abs(firstSMated-firstMated)>0.2) useFirstS = true;
00872 else if(firstTMated>firstSMated && firstTMated>firstBestMated
00873 && TMath::Abs(firstTMated-firstMated)>0.2) useFirstT = true;
00874
00875 if(lastBestMated>=lastSMated && lastBestMated>=lastTMated
00876 && TMath::Abs(lastBestMated-lastMated)>0.2) useLastB = true;
00877 else if(lastSMated>lastBestMated && lastSMated>=lastTMated
00878 && TMath::Abs(lastSMated-lastMated)>0.2) useLastS = true;
00879 else if(lastTMated>lastSMated && lastTMated>lastBestMated
00880 && TMath::Abs(lastTMated-lastMated)>0.2) useLastT = true;
00881
00882
00883
00884
00885
00886
00887
00888
00889
00890
00891
00892
00893
00894
00895
00896
00897
00898
00899
00900
00901
00902
00903
00904
00905
00906
00907
00908
00909 if(useFirstB
00910 && TMath::Abs(firstPlaneSpace)*0.25>TMath::Abs(firstPlaneCoG-firstPlaneBCoG)){
00911 plane = planeItr.Ptr();
00912 if(plane->IsStray()){
00913 if(plane->GetPlaneType() == DmxPlaneTypes::kShower)
00914 dynamic_cast<DmxShowerPlane *>(plane)->SetStrips("best");
00915 else if(plane->GetPlaneType() == DmxPlaneTypes::kMuon) plane->SetStrips();
00916 plane->SetStray(false);
00917 ++fixedPlanes;
00918 }
00919 }
00920 else if(useFirstS
00921 && TMath::Abs(firstPlaneSpace)*0.25>TMath::Abs(firstPlaneCoG-firstPlaneSCoG)){
00922 plane = planeItr.Ptr();
00923 if(plane->IsStray()){
00924 if(plane->GetPlaneType() == DmxPlaneTypes::kShower)
00925 dynamic_cast<DmxShowerPlane *>(plane)->SetStrips("second");
00926 plane->SetStray(false);
00927 ++fixedPlanes;
00928 }
00929 }
00930 else if(useFirstT
00931 && TMath::Abs(firstPlaneSpace)*0.25>TMath::Abs(firstPlaneCoG-firstPlaneTCoG)){
00932 plane = planeItr.Ptr();
00933 if(plane->IsStray()){
00934 if(plane->GetPlaneType() == DmxPlaneTypes::kShower)
00935 dynamic_cast<DmxShowerPlane *>(plane)->SetStrips("third");
00936 plane->SetStray(false);
00937 ++fixedPlanes;
00938 }
00939 }
00940
00941
00942 planeItr.ResetLast();
00943
00944 if(useLastB && TMath::Abs(lastPlaneSpace)*0.25>TMath::Abs(lastPlaneCoG-lastPlaneBCoG)){
00945 plane = planeItr.Ptr();
00946 if(plane->IsStray()){
00947 if(plane->GetPlaneType() == DmxPlaneTypes::kShower)
00948 dynamic_cast<DmxShowerPlane *>(plane)->SetStrips("best");
00949 else if(plane->GetPlaneType() == DmxPlaneTypes::kMuon) plane->SetStrips();
00950 plane->SetStray(false);
00951 ++fixedPlanes;
00952 }
00953 }
00954 else if(useLastS
00955 && TMath::Abs(lastPlaneSpace)*0.25>TMath::Abs(lastPlaneCoG-lastPlaneSCoG)){
00956 plane = planeItr.Ptr();
00957 if(plane->IsStray()){
00958 if(plane->GetPlaneType() == DmxPlaneTypes::kShower)
00959 dynamic_cast<DmxShowerPlane *>(plane)->SetStrips("second");
00960 plane->SetStray(false);
00961 ++fixedPlanes;
00962 }
00963 }
00964 else if(useLastT
00965 && TMath::Abs(lastPlaneSpace)*0.25>TMath::Abs(lastPlaneCoG-lastPlaneTCoG)){
00966 plane = planeItr.Ptr();
00967 if(plane->IsStray()){
00968 if(plane->GetPlaneType() == DmxPlaneTypes::kShower)
00969 dynamic_cast<DmxShowerPlane *>(plane)->SetStrips("third");
00970 plane->SetStray(false);
00971 ++fixedPlanes;
00972 }
00973 }
00974
00975 return fixedPlanes;
00976 }
00977
00978
00979
00980 Bool_t DmxUtilities::IsOverlappingMultiple(DmxPlaneItr &planeItr, Float_t vertexZ,
00981 Float_t slopeCutOff, Float_t interceptCutOff,
00982 Float_t peakCutOff)
00983 {
00984
00985 planeItr.ResetFirst();
00986 DmxPlane *plane = 0;
00987
00988
00989
00990
00991 TH2F houghSpaceSM1 = TH2F("houghSpaceSM1", "Hough Space for Multiples",
00992 30, -30, 30, 500, -500, 500);
00993 TH2F houghSpaceSM2 = TH2F("houghSpaceSM2", "Hough Space for Multiples",
00994 30, -30, 30, 500, -500, 500);
00995 TH2F houghSpaceCutSM1 = TH2F("hS75SM1", "Hough Space for U with cut",
00996 30, -30, 30, 500, -500, 500);
00997 TH2F houghSpaceCutSM2 = TH2F("hS75SM2", "Hough Space for U with cut",
00998 30, -30, 30, 500, -500, 500);
00999
01000 Float_t planeZ = 0.;
01001 Float_t cog = 0.;
01002 while( (plane = planeItr()) ){
01003
01004 planeZ = 1.*plane->GetPlaneNumber();
01005
01006 if(plane->GetPlaneType() == DmxPlaneTypes::kShower){
01007
01008 for(Int_t j = 0; j <3; j++){
01009 if( j==0 && dynamic_cast<DmxShowerPlane *>(plane)->GetBestHypothesis() ){
01010 cog = dynamic_cast<DmxShowerPlane *>(plane)->GetBestCoG();
01011 }
01012 else if( j==1 && dynamic_cast<DmxShowerPlane *>(plane)->GetSecondBestHypothesis() ){
01013 cog = dynamic_cast<DmxShowerPlane *>(plane)->GetSecondBestCoG();
01014 }
01015 else if( j==2 && dynamic_cast<DmxShowerPlane *>(plane)->GetThirdBestHypothesis() ){
01016 cog = dynamic_cast<DmxShowerPlane *>(plane)->GetThirdBestCoG();
01017 }
01018
01019 for(Int_t m = -29; m<30; m+=2){
01020
01021 Float_t c = cog - m*1.*(planeZ - vertexZ);
01022
01023 if(planeZ<249) houghSpaceSM1.Fill(m,c);
01024 else if(planeZ>249) houghSpaceSM2.Fill(m,c);
01025
01026 }
01027 }
01028
01029 }
01030 else if(plane->GetPlaneType() == DmxPlaneTypes::kMuon){
01031 cog = dynamic_cast<DmxMuonPlane *>(plane)->GetInitialCoG();
01032
01033
01034 for(Int_t m = -29; m<30; m+=2){
01035
01036 Float_t c = cog - m*1.*(planeZ - vertexZ);
01037
01038
01039 if(planeZ<249){
01040 houghSpaceSM1.Fill(m,c);
01041 houghSpaceSM1.Fill(m,c);
01042 houghSpaceSM1.Fill(m,c);
01043 }
01044 else if(planeZ>249){
01045 houghSpaceSM2.Fill(m,c);
01046 houghSpaceSM2.Fill(m,c);
01047 houghSpaceSM2.Fill(m,c);
01048 }
01049 }
01050
01051 }
01052 }
01053
01054 planeItr.ResetFirst();
01055
01056
01057
01058 Stat_t binContent = 0;
01059 Double_t maximumSM1 = houghSpaceSM1.GetMaximum();
01060 Double_t maximumSM2 = houghSpaceSM2.GetMaximum();
01061
01062 for(Int_t x = 1; x < 30+1; x++){
01063
01064 for(Int_t y = 1; y < 500+1; y++){
01065 binContent = houghSpaceSM1.GetBinContent(x,y);
01066 if(binContent>= peakCutOff*maximumSM1) houghSpaceCutSM1.SetBinContent(x,y,binContent);
01067 binContent = houghSpaceSM2.GetBinContent(x,y);
01068 if(binContent>= peakCutOff*maximumSM2) houghSpaceCutSM2.SetBinContent(x,y,binContent);
01069
01070 }
01071 }
01072
01073
01074
01075
01076 bool multiple = false;
01077 if(houghSpaceCutSM1.GetRMS(1)<=slopeCutOff
01078 && houghSpaceCutSM1.GetRMS(2)>=interceptCutOff)
01079 multiple = true;
01080 else if(houghSpaceCutSM2.GetRMS(1)<=slopeCutOff
01081 && houghSpaceCutSM2.GetRMS(2)>=interceptCutOff)
01082 multiple = true;
01083
01084 return multiple;
01085 }
01086
01087
01088
01089 Int_t DmxUtilities::FindPlanesOffFit(DmxPlaneItr &planeItr, Int_t strayCut)
01090 {
01091
01092 planeItr.Reset();
01093
01094 Int_t strayPlanes = 0;
01095
01096 DmxPlane *plane = 0;
01097
01098
01099 while( planeItr.IsValid() ){
01100
01101 plane = planeItr.Ptr();
01102
01103 if( plane->IsValid() ){
01104
01105 Double_t fitCoG = -1.;
01106
01107
01108 if(plane->GetPlaneType() == DmxPlaneTypes::kShower){
01109 Double_t diff1 = 0.;
01110 Double_t diff2 = 0.;
01111 Double_t diff3 = 0.;
01112 fitCoG = plane->GetCoG();
01113
01114 if( dynamic_cast<DmxShowerPlane *>(plane)->GetBestHypothesis() ){
01115 diff1 = TMath::Abs(fitCoG-dynamic_cast<DmxShowerPlane *>(plane)->GetBestCoG());
01116
01117 }
01118 if( dynamic_cast<DmxShowerPlane *>(plane)->GetSecondBestHypothesis() ){
01119 diff2 = TMath::Abs(fitCoG-dynamic_cast<DmxShowerPlane *>(plane)->GetSecondBestCoG());
01120
01121 }
01122 if( dynamic_cast<DmxShowerPlane *>(plane)->GetThirdBestHypothesis() ){
01123 diff3 = TMath::Abs(fitCoG-dynamic_cast<DmxShowerPlane *>(plane)->GetThirdBestCoG());
01124
01125 }
01126
01127
01128 if(diff1>strayCut*.042 && diff2>strayCut*.042 && diff3>strayCut*.042){
01129
01130
01131
01132 ++strayPlanes;
01133 plane->SetStray(true);
01134
01135
01136 }
01137 }
01138
01139
01140
01141
01142
01143
01144
01145
01146
01147
01148
01149
01150 }
01151 planeItr.Next();
01152 }
01153
01154 planeItr.Reset();
01155
01156 return strayPlanes;
01157 }
01158
01159
01160 Float_t DmxUtilities::CheckFitWithTiming(DmxPlaneItr &planeItr)
01161 {
01162
01163
01164
01165
01166
01167
01168
01169
01170 planeItr.ResetFirst();
01171
01172 Int_t planeCtr = 0;
01173 Int_t numPlanes = planeItr.SizeSelect();
01174 Int_t forwardCtr = 0;
01175 Int_t backwardCtr = 0;
01176 bool opposite = false;
01177 Float_t offset = 0.;
01178 Float_t avOffsetDiff = 0.;
01179 Float_t avCoG = 0.;
01180 Float_t avCoGCnt = 0.;
01181
01182 DmxPlane *plane = 0;
01183 DmxPlane *nextPlane = 0;
01184 DmxPlane *prevPlane = 0;
01185
01186 while( planeItr.IsValid() ){
01187
01188 plane = planeItr.Ptr();
01189
01190
01191 offset = plane->GetTimingOffset();
01192
01193 forwardCtr = 0;
01194 backwardCtr = 0;
01195 avCoG = 0.;
01196 avCoGCnt = 0.;
01197
01198 if(planeCtr == 0 && offset != -10.){
01199
01200
01201 while(planeItr.IsValid() && opposite == false){
01202 planeItr.Next();
01203 ++forwardCtr;
01204 nextPlane = planeItr.Ptr();
01205 if(nextPlane->GetPlaneView() != plane->GetPlaneView()){
01206
01207
01208 opposite = true;
01209 avOffsetDiff += TMath::Abs(TMath::Abs(offset)-TMath::Abs(nextPlane->GetCoG()));
01210 }
01211 }
01212
01213 while(forwardCtr > 0){
01214 planeItr.Prev();
01215 --forwardCtr;
01216 }
01217
01218 }
01219 else if(planeCtr > 0 && planeCtr<numPlanes-1 && offset != -10.){
01220
01221 opposite = false;
01222
01223 while(planeItr.IsValid() && !opposite){
01224 planeItr.Next();
01225 ++forwardCtr;
01226 if(planeItr.IsValid()){
01227 nextPlane = planeItr.Ptr();
01228 if(nextPlane->GetPlaneView() != plane->GetPlaneView()){
01229
01230
01231 opposite = true;
01232 avCoG += nextPlane->GetCoG();
01233 avCoGCnt += 1.;
01234 }
01235 }
01236 }
01237
01238 while(forwardCtr > 0){
01239 planeItr.Prev();
01240 --forwardCtr;
01241 }
01242
01243 opposite = false;
01244
01245
01246
01247
01248 while(planeItr.IsValid() && !opposite){
01249 planeItr.Prev();
01250 ++backwardCtr;
01251 if(planeItr.IsValid()){
01252 prevPlane = planeItr.Ptr();
01253 if(prevPlane->GetPlaneView() != plane->GetPlaneView()){
01254
01255
01256 opposite = true;
01257 avCoG += prevPlane->GetCoG();
01258 avCoGCnt += 1.;
01259 }
01260 }
01261 }
01262
01263 while(backwardCtr > 0){
01264 planeItr.Next();
01265 --backwardCtr;
01266 }
01267
01268
01269 if(avCoGCnt > 0.) avOffsetDiff += TMath::Abs(TMath::Abs(offset)-TMath::Abs(avCoG/avCoGCnt));
01270
01271 }
01272 else if(planeCtr == numPlanes-1 && offset != -10.){
01273 opposite = false;
01274 while(planeItr.IsValid() && !opposite){
01275 planeItr.Prev();
01276 ++backwardCtr;
01277 if(planeItr.IsValid()){
01278 prevPlane = planeItr.Ptr();
01279 if(prevPlane->GetPlaneView() != plane->GetPlaneView()){
01280
01281
01282 opposite = true;
01283 avOffsetDiff += TMath::Abs(TMath::Abs(offset)-TMath::Abs(prevPlane->GetCoG()));
01284 }
01285 }
01286 }
01287
01288 while(backwardCtr > 0){
01289 planeItr.Next();
01290 --backwardCtr;
01291 }
01292
01293 }
01294
01295 ++planeCtr;
01296 planeItr.Next();
01297 }
01298
01299 if(numPlanes>0) avOffsetDiff /= (1.0*numPlanes);
01300
01301 planeItr.ResetFirst();
01302
01303 return avOffsetDiff;
01304 }
01305
01306
01307
01308
01309 void DmxUtilities::FindCubicFit(Double_t *x, Double_t *y, Double_t *weight,
01310 Int_t nPoints, Double_t &a1, Double_t &a2,
01311 Double_t &a3, Double_t &a4, Double_t &chiSq)
01312 {
01313
01314
01315
01316
01317
01318
01319
01320
01321
01322
01323
01324
01325
01326
01327
01328
01329
01330
01331
01332
01333
01334
01335
01336
01337
01338
01339
01340
01341
01342
01343
01344
01345
01346
01347 Double_t yf1divWeight = 0.;
01348 Double_t yf2divWeight = 0.;
01349 Double_t yf3divWeight = 0.;
01350 Double_t yf4divWeight = 0.;
01351 Double_t f1f1divWeight = 0.;
01352 Double_t f1f2divWeight = 0.;
01353 Double_t f1f3divWeight = 0.;
01354 Double_t f1f4divWeight = 0.;
01355 Double_t f2f2divWeight = 0.;
01356 Double_t f2f3divWeight = 0.;
01357 Double_t f2f4divWeight = 0.;
01358 Double_t f3f3divWeight = 0.;
01359 Double_t f3f4divWeight = 0.;
01360 Double_t f4f4divWeight = 0.;
01361
01362 for(Int_t i=0; i<nPoints; i++){
01363 yf1divWeight += y[i]/(weight[i]*weight[i]);
01364 yf2divWeight += (y[i]*x[i])/(weight[i]*weight[i]);
01365 yf3divWeight += (y[i]*x[i]*x[i])/(weight[i]*weight[i]);
01366 yf4divWeight += (y[i]*x[i]*x[i]*x[i])/(weight[i]*weight[i]);
01367 f1f1divWeight += 1./(weight[i]*weight[i]);
01368 f1f2divWeight += x[i]/(weight[i]*weight[i]);
01369 f1f3divWeight += (x[i]*x[i])/(weight[i]*weight[i]);
01370 f1f4divWeight += (x[i]*x[i]*x[i])/(weight[i]*weight[i]);
01371 f2f2divWeight += (x[i]*x[i])/(weight[i]*weight[i]);
01372 f2f3divWeight += (x[i]*x[i]*x[i])/(weight[i]*weight[i]);
01373 f2f4divWeight += (x[i]*x[i]*x[i]*x[i])/(weight[i]*weight[i]);
01374 f3f3divWeight += (x[i]*x[i]*x[i]*x[i])/(weight[i]*weight[i]);
01375 f3f4divWeight += (x[i]*x[i]*x[i]*x[i]*x[i])/(weight[i]*weight[i]);
01376 f4f4divWeight += (x[i]*x[i]*x[i]*x[i]*x[i]*x[i])/(weight[i]*weight[i]);
01377 }
01378
01379
01380 TMatrix deltaMatrix(4,4);
01381 TMatrix a1Matrix(4,4);
01382 TMatrix a2Matrix(4,4);
01383 TMatrix a3Matrix(4,4);
01384 TMatrix a4Matrix(4,4);
01385
01386
01387 deltaMatrix(0,0) = f1f1divWeight;
01388 deltaMatrix(0,1) = f1f2divWeight;
01389 deltaMatrix(0,2) = f1f3divWeight;
01390 deltaMatrix(0,3) = f1f4divWeight;
01391 deltaMatrix(1,0) = f1f2divWeight;
01392 deltaMatrix(1,1) = f2f2divWeight;
01393 deltaMatrix(1,2) = f2f3divWeight;
01394 deltaMatrix(1,3) = f2f4divWeight;
01395 deltaMatrix(2,0) = f1f3divWeight;
01396 deltaMatrix(2,1) = f2f3divWeight;
01397 deltaMatrix(2,2) = f3f3divWeight;
01398 deltaMatrix(2,3) = f3f4divWeight;
01399 deltaMatrix(3,0) = f1f4divWeight;
01400 deltaMatrix(3,1) = f2f4divWeight;
01401 deltaMatrix(3,2) = f3f4divWeight;
01402 deltaMatrix(3,3) = f4f4divWeight;
01403
01404 a1Matrix(0,0) = yf1divWeight;
01405 a1Matrix(0,1) = f1f2divWeight;
01406 a1Matrix(0,2) = f1f3divWeight;
01407 a1Matrix(0,3) = f1f4divWeight;
01408 a1Matrix(1,0) = yf2divWeight;
01409 a1Matrix(1,1) = f2f2divWeight;
01410 a1Matrix(1,2) = f2f3divWeight;
01411 a1Matrix(1,3) = f2f4divWeight;
01412 a1Matrix(2,0) = yf3divWeight;
01413 a1Matrix(2,1) = f2f3divWeight;
01414 a1Matrix(2,2) = f3f3divWeight;
01415 a1Matrix(2,3) = f3f4divWeight;
01416 a1Matrix(3,0) = yf4divWeight;
01417 a1Matrix(3,1) = f2f4divWeight;
01418 a1Matrix(3,2) = f3f4divWeight;
01419 a1Matrix(3,3) = f4f4divWeight;
01420
01421 a2Matrix(0,0) = f1f1divWeight;
01422 a2Matrix(0,1) = yf1divWeight;
01423 a2Matrix(0,2) = f1f3divWeight;
01424 a2Matrix(0,3) = f1f4divWeight;
01425 a2Matrix(1,0) = f1f2divWeight;
01426 a2Matrix(1,1) = yf2divWeight;
01427 a2Matrix(1,2) = f2f3divWeight;
01428 a2Matrix(1,3) = f2f4divWeight;
01429 a2Matrix(2,0) = f1f3divWeight;
01430 a2Matrix(2,1) = yf3divWeight;
01431 a2Matrix(2,2) = f3f3divWeight;
01432 a2Matrix(2,3) = f3f4divWeight;
01433 a2Matrix(3,0) = f1f4divWeight;
01434 a2Matrix(3,1) = yf4divWeight;
01435 a2Matrix(3,2) = f3f4divWeight;
01436 a2Matrix(3,3) = f4f4divWeight;
01437
01438 a3Matrix(0,0) = f1f1divWeight;
01439 a3Matrix(0,1) = f1f2divWeight;
01440 a3Matrix(0,2) = yf1divWeight;
01441 a3Matrix(0,3) = f1f4divWeight;
01442 a3Matrix(1,0) = f1f2divWeight;
01443 a3Matrix(1,1) = f2f2divWeight;
01444 a3Matrix(1,2) = yf2divWeight;
01445 a3Matrix(1,3) = f2f4divWeight;
01446 a3Matrix(2,0) = f1f3divWeight;
01447 a3Matrix(2,1) = f2f3divWeight;
01448 a3Matrix(2,2) = yf3divWeight;
01449 a3Matrix(2,3) = f3f4divWeight;
01450 a3Matrix(3,0) = f1f4divWeight;
01451 a3Matrix(3,1) = f2f4divWeight;
01452 a3Matrix(3,2) = yf4divWeight;
01453 a3Matrix(3,3) = f4f4divWeight;
01454
01455 a4Matrix(0,0) = f1f1divWeight;
01456 a4Matrix(0,1) = f1f2divWeight;
01457 a4Matrix(0,2) = f1f3divWeight;
01458 a4Matrix(0,3) = yf1divWeight;
01459 a4Matrix(1,0) = f1f2divWeight;
01460 a4Matrix(1,1) = f2f2divWeight;
01461 a4Matrix(1,2) = f2f3divWeight;
01462 a4Matrix(1,3) = yf2divWeight;
01463 a4Matrix(2,0) = f1f3divWeight;
01464 a4Matrix(2,1) = f2f3divWeight;
01465 a4Matrix(2,2) = f3f3divWeight;
01466 a4Matrix(2,3) = yf3divWeight;
01467 a4Matrix(3,0) = f1f4divWeight;
01468 a4Matrix(3,1) = f2f4divWeight;
01469 a4Matrix(3,2) = f3f4divWeight;
01470 a4Matrix(3,3) = yf4divWeight;
01471
01472 a1 = -10000.;
01473 a2 = -10000.;
01474 a3 = -10000.;
01475 a4 = -10000.;
01476 Double_t delta = deltaMatrix.Determinant();
01477
01478 if(delta != 0.){
01479 a1 = a1Matrix.Determinant()/delta;
01480 a2 = a2Matrix.Determinant()/delta;
01481 a3 = a3Matrix.Determinant()/delta;
01482 a4 = a4Matrix.Determinant()/delta;
01483 }
01484
01485
01486 chiSq = 0.;
01487 Double_t chi = 0.;
01488 for(Int_t j = 0; j<nPoints; j++){
01489
01490 chi = (y[j] - (a1 + a2*x[j] + a3*(x[j]*x[j]) + a4*(x[j]*x[j]*x[j])))/weight[j];
01491 chiSq += chi*chi;
01492
01493 }
01494
01495
01496
01497 chiSq /= (1.*nPoints);
01498
01499 return;
01500 }
01501
01502
01503
01504
01505 void DmxUtilities::FindQuadraticFit(Double_t *x, Double_t *y, Double_t *weight,
01506 Int_t nPoints, Double_t &a1, Double_t &a2,
01507 Double_t &a3, Double_t &chiSq)
01508 {
01509
01510
01511
01512
01513
01514
01515
01516
01517
01518
01519
01520
01521
01522
01523
01524
01525
01526
01527
01528
01529
01530
01531
01532
01533
01534 Double_t yf1divWeight = 0.;
01535 Double_t yf2divWeight = 0.;
01536 Double_t yf3divWeight = 0.;
01537 Double_t f1f1divWeight = 0.;
01538 Double_t f1f2divWeight = 0.;
01539 Double_t f1f3divWeight = 0.;
01540 Double_t f2f2divWeight = 0.;
01541 Double_t f2f3divWeight = 0.;
01542 Double_t f3f3divWeight = 0.;
01543
01544 for(Int_t i=0; i<nPoints; i++){
01545 yf1divWeight += y[i]/(weight[i]*weight[i]);
01546 yf2divWeight += (y[i]*x[i])/(weight[i]*weight[i]);
01547 yf3divWeight += (y[i]*x[i]*x[i])/(weight[i]*weight[i]);
01548 f1f1divWeight += 1./(weight[i]*weight[i]);
01549 f1f2divWeight += x[i]/(weight[i]*weight[i]);
01550 f1f3divWeight += (x[i]*x[i])/(weight[i]*weight[i]);
01551 f2f2divWeight += (x[i]*x[i])/(weight[i]*weight[i]);
01552 f2f3divWeight += (x[i]*x[i]*x[i])/(weight[i]*weight[i]);
01553 f3f3divWeight += (x[i]*x[i]*x[i]*x[i])/(weight[i]*weight[i]);
01554 }
01555
01556
01557 TMatrix deltaMatrix(3,3);
01558 TMatrix a1Matrix(3,3);
01559 TMatrix a2Matrix(3,3);
01560 TMatrix a3Matrix(3,3);
01561
01562
01563 deltaMatrix(0,0) = f1f1divWeight;
01564 deltaMatrix(0,1) = f1f2divWeight;
01565 deltaMatrix(0,2) = f1f3divWeight;
01566 deltaMatrix(1,0) = f1f2divWeight;
01567 deltaMatrix(1,1) = f2f2divWeight;
01568 deltaMatrix(1,2) = f2f3divWeight;
01569 deltaMatrix(2,0) = f1f3divWeight;
01570 deltaMatrix(2,1) = f2f3divWeight;
01571 deltaMatrix(2,2) = f3f3divWeight;
01572
01573 a1Matrix(0,0) = yf1divWeight;
01574 a1Matrix(0,1) = f1f2divWeight;
01575 a1Matrix(0,2) = f1f3divWeight;
01576 a1Matrix(1,0) = yf2divWeight;
01577 a1Matrix(1,1) = f2f2divWeight;
01578 a1Matrix(1,2) = f2f3divWeight;
01579 a1Matrix(2,0) = yf3divWeight;
01580 a1Matrix(2,1) = f2f3divWeight;
01581 a1Matrix(2,2) = f3f3divWeight;
01582
01583 a2Matrix(0,0) = f1f1divWeight;
01584 a2Matrix(0,1) = yf1divWeight;
01585 a2Matrix(0,2) = f1f3divWeight;
01586 a2Matrix(1,0) = f1f2divWeight;
01587 a2Matrix(1,1) = yf2divWeight;
01588 a2Matrix(1,2) = f2f3divWeight;
01589 a2Matrix(2,0) = f1f3divWeight;
01590 a2Matrix(2,1) = yf3divWeight;
01591 a2Matrix(2,2) = f3f3divWeight;
01592
01593 a3Matrix(0,0) = f1f1divWeight;
01594 a3Matrix(0,1) = f1f2divWeight;
01595 a3Matrix(0,2) = yf1divWeight;
01596 a3Matrix(1,0) = f1f2divWeight;
01597 a3Matrix(1,1) = f2f2divWeight;
01598 a3Matrix(1,2) = yf2divWeight;
01599 a3Matrix(2,0) = f1f3divWeight;
01600 a3Matrix(2,1) = f2f3divWeight;
01601 a3Matrix(2,2) = yf3divWeight;
01602
01603 a1 = -10000.;
01604 a2 = -10000.;
01605 a3 = -10000.;
01606 Double_t delta = deltaMatrix.Determinant();
01607
01608 if(delta != 0.){
01609 a1 = a1Matrix.Determinant()/delta;
01610 a2 = a2Matrix.Determinant()/delta;
01611 a3 = a3Matrix.Determinant()/delta;
01612 }
01613
01614
01615 chiSq = 0.;
01616 Double_t chi = 0.;
01617 for(Int_t j = 0; j<nPoints; j++){
01618
01619 chi = (y[j] - (a1 + a2*x[j] + a3*(x[j]*x[j])))/weight[j];
01620 chiSq += chi*chi;
01621
01622 }
01623
01624
01625
01626 chiSq /= (1.*nPoints);
01627
01628 return;
01629 }
01630
01631
01632
01633
01634 void DmxUtilities::FindLinearFit(Double_t *x, Double_t *y, Double_t *weight,
01635 Int_t nPoints, Double_t &a1, Double_t &a2,
01636 Double_t &chiSq)
01637 {
01638
01639
01640
01641
01642
01643
01644
01645
01646
01647
01648
01649
01650
01651
01652
01653
01654
01655
01656 Double_t yf1divWeight = 0.;
01657 Double_t yf2divWeight = 0.;
01658 Double_t f1f1divWeight = 0.;
01659 Double_t f1f2divWeight = 0.;
01660 Double_t f2f2divWeight = 0.;
01661
01662 for(Int_t i=0; i<nPoints; ++i){
01663 MSG("DmxUtilities", Msg::kDebug) << " x = " << x[i]
01664 << " y = " << y[i]
01665 << " weight = " << weight[i] << endl;
01666 if(weight[i]>0.){
01667 yf1divWeight += y[i]/(weight[i]*weight[i]);
01668 yf2divWeight += (y[i]*x[i])/(weight[i]*weight[i]);
01669 f1f1divWeight += 1./(weight[i]*weight[i]);
01670 f1f2divWeight += x[i]/(weight[i]*weight[i]);
01671 f2f2divWeight += (x[i]*x[i])/(weight[i]*weight[i]);
01672 }
01673 }
01674
01675
01676 TMatrix deltaMatrix(2,2);
01677 TMatrix a1Matrix(2,2);
01678 TMatrix a2Matrix(2,2);
01679
01680
01681 deltaMatrix(0,0) = f1f1divWeight;
01682 deltaMatrix(0,1) = f1f2divWeight;
01683 deltaMatrix(1,0) = f1f2divWeight;
01684 deltaMatrix(1,1) = f2f2divWeight;
01685
01686 a1Matrix(0,0) = yf1divWeight;
01687 a1Matrix(0,1) = f1f2divWeight;
01688 a1Matrix(1,0) = yf2divWeight;
01689 a1Matrix(1,1) = f2f2divWeight;
01690
01691 a2Matrix(0,0) = f1f1divWeight;
01692 a2Matrix(0,1) = yf1divWeight;
01693 a2Matrix(1,0) = f1f2divWeight;
01694 a2Matrix(1,1) = yf2divWeight;
01695
01696
01697 a1 = -10000.;
01698 a2 = -10000.;
01699 Double_t delta = deltaMatrix.Determinant();
01700
01701 if(delta != 0.){
01702 a1 = a1Matrix.Determinant()/delta;
01703 a2 = a2Matrix.Determinant()/delta;
01704 }
01705
01706
01707 chiSq = 0.;
01708 Double_t chi = 0.;
01709 for(Int_t j = 0; j<nPoints; ++j){
01710
01711 chi = (y[j] - (a1 + a2*x[j]))/weight[j];
01712 chiSq += chi*chi;
01713
01714 }
01715
01716
01717
01718 chiSq /= (1.*nPoints);
01719
01720 return;
01721 }