00001 00002 // $Id: AlgDeMuxCosmics.cxx,v 1.101 2007/02/04 05:55:06 rhatcher Exp $ 00003 // 00004 // AlgDeMuxCosmics 00005 // 00006 // An Algorithm class that DeMultiplexes a cosmic ray event and adjusts the 00007 //weights in the PlexSEIdAltLists of the CandDigits from that event 00008 // 00009 // Author: B. Rebel 11/2000 00011 00012 #include <cassert> 00013 00014 #include "Candidate/CandContext.h" 00015 #include "Candidate/CandHandle.h" 00016 #include "CandData/CandHeader.h" 00017 #include "CandData/CandRecord.h" 00018 #include "CandDigit/CandDigitHandle.h" 00019 #include "CandDigit/CandDigitListHandle.h" 00020 #include "CandDigit/CandDeMuxDigitHandle.h" 00021 #include "CandDigit/CandDeMuxDigitListHandle.h" 00022 #include "MessageService/MsgService.h" 00023 #include "Algorithm/AlgConfig.h" 00024 #include "DeMux/DmxStatus.h" 00025 #include "DeMux/DmxHypothesis.h" 00026 #include "DeMux/DmxPlane.h" 00027 #include "DeMux/DmxShowerPlane.h" 00028 #include "DeMux/DmxMuonPlane.h" 00029 #include "DeMux/DmxUtilities.h" 00030 #include "Algorithm/AlgFactory.h" 00031 #include "Algorithm/AlgHandle.h" 00032 #include "DeMux/AlgDeMuxCosmics.h" 00033 #include "Navigation/NavKey.h" 00034 #include "Navigation/NavSet.h" 00035 #include "TObjArray.h" 00036 00037 #include "TFolder.h" 00038 #include "TObjArray.h" 00039 #include "TROOT.h" 00040 #include "TMath.h" 00041 00042 //define the NavKey to sort the planes 00043 static NavKey KeyOnPlane( const DmxPlane *plane){ 00044 return plane->GetPlaneNumber(); 00045 } 00046 00047 //define the NavKeys to select U and V planes 00048 NavKey KeyOnUView( const DmxPlane *plane){ 00049 return plane->GetPlaneView() == PlaneView::kU; 00050 } 00051 00052 NavKey KeyOnVView( const DmxPlane *plane){ 00053 return plane->GetPlaneView() == PlaneView::kV; 00054 } 00055 00056 //define the NavKeys to select only valid U and V planes 00057 NavKey KeyOnValidU( const DmxPlane *plane){ 00058 return plane->GetPlaneView() == PlaneView::kU && (Int_t)plane->IsValid() == 1; 00059 } 00060 00061 NavKey KeyOnValidV( const DmxPlane *plane){ 00062 return plane->GetPlaneView() == PlaneView::kV && (Int_t)plane->IsValid() == 1; 00063 } 00064 00065 ClassImp(AlgDeMuxCosmics) 00066 00067 00068 //----------------------------------------------------------------------- 00069 00070 CVSID("$Id: AlgDeMuxCosmics.cxx,v 1.101 2007/02/04 05:55:06 rhatcher Exp $"); 00071 00072 //----------------------------------------------------------------------- 00073 00074 AlgDeMuxCosmics::AlgDeMuxCosmics() : 00075 fRequiredMatedSignalRatio(0.33), 00076 fSlopeRMS(0.), 00077 fStrayPlanes(0), 00078 fPlanesInSet(6), 00079 fStrayCut(6) 00080 { 00081 //default constructor 00082 } 00083 00084 //----------------------------------------------------------------------- 00085 00086 AlgDeMuxCosmics::~AlgDeMuxCosmics() 00087 { 00088 00089 } 00090 00091 //----------------------------------------------------------------------- 00092 //run the demuxing on an event 00093 00094 void AlgDeMuxCosmics::RunAlg(AlgConfig &acd, CandHandle &ch, CandContext & /* cx */) 00095 { 00096 00097 assert( ch.InheritsFrom("CandDigitListHandle") ); 00098 CandDeMuxDigitListHandle &cdlh = dynamic_cast<CandDeMuxDigitListHandle&>(ch); 00099 00100 MSG("AlgDeMuxCosmics", Msg::kDebug) << cdlh.GetNDaughters() << " digits in AlgDeMuxCosmics" << endl; 00101 00102 VldContext vldc = ch.GetCandRecord()->GetCandHeader()->GetVldContext(); 00103 if (vldc.GetDetector() != Detector::kFar) { 00104 static int msglimit = 20; // no more than 20 warnings about the detector 00105 if (msglimit) { 00106 MSG("DMX",Msg::kDebug) 00107 << "AlgDeMuxCosmics::RunAlg() can not DeMux " 00108 << Detector::AsString(vldc.GetDetector()) 00109 << " detector. Skip futher DeMux processing." 00110 << endl; 00111 if (--msglimit == 0) 00112 MSG("DMX",Msg::kDebug) 00113 << " ... last message of this type." << endl; 00114 } 00115 return; 00116 } 00117 00118 //get the AlgConfigDeMux object 00119 fPlanesInSet = acd.GetInt("PlanesInSet"); 00120 fRequiredMatedSignalRatio = acd.GetDouble("RatioMatedSignalForValid"); 00121 fStrayCut = acd.GetInt("StrayDeltaStripLimit"); 00122 //MSG("DMX", Msg::kDebug) << "starting cosmics algorithm" << endl; 00123 00124 //get the DmxStatus object 00125 // Find the DmxStatus object or create one for needed scratch space 00126 DmxStatus *status = dynamic_cast<DmxStatus *>(gROOT->GetRootFolder()->FindObject("Loon/DeMux/DmxStatus")); 00127 bool tempStatus = false; 00128 if (status == 0) { 00129 MSG("DMXX", Msg::kDebug) << "//root/Loon/DeMux/DmxStatus not found." 00130 << " Create a temporary DmxStatus." << endl; 00131 status = new DmxStatus; // Make a temporary DmxStatus if needed 00132 tempStatus = true; 00133 } 00134 else status->ResetStatus(); 00135 00136 status->SetEventNumber(ch.GetCandRecord()->GetCandHeader()->GetSnarl()); 00137 00138 //instantiate the DmxInitialize object and then fill DmxStatus with the event information 00139 DmxUtilities util; 00140 00141 util.FillPlaneArray(status, cdlh, acd); 00142 const TObjArray *planeArray = status->GetPlaneArray(); 00143 00144 //create the TObjectItr over planes and program it to sort the planes 00145 DmxPlaneItr planeItr(planeArray); 00146 DmxPlaneKeyFunc *pnKF = planeItr.CreateKeyFunc(); 00147 pnKF->SetFun(KeyOnPlane); 00148 planeItr.GetSet()->AdoptSortKeyFunc(pnKF); 00149 pnKF = 0; 00150 00151 planeItr.ResetFirst(); 00152 00153 // while(planeItr.IsValid()){ 00154 // cout << dynamic_cast<DmxPlane *>(planeItr.Ptr())->GetPlaneNumber() << endl; 00155 // planeItr.Next(); 00156 // } 00157 // planeItr.ResetFirst(); 00158 00159 status->SetNumberOfPlanes(planeItr.SizeSelect()); 00160 status->SetVertexPlaneNumber(util.FindVertexPlane(planeItr)); 00161 00162 //demux the event if there is an identified vertex 00163 if( status->GetVertexPlaneNumber() != -1){ 00164 00165 planeItr.ResetFirst(); 00166 planeItr.GetSet()->Slice(status->GetVertexPlaneNumber(), 500); 00167 planeItr.GetSet()->Update(); 00168 //set the end plane number since there was a vertex plane 00169 status->SetEndPlaneNumber(util.FindEndPlane(planeItr)); 00170 planeItr.GetSet()->ClearSlice(false); 00171 planeItr.ResetFirst(); 00172 00173 //set the z position of the vertex plane 00174 planeItr.GetSet()->Slice(status->GetVertexPlaneNumber()); 00175 planeItr.GetSet()->Update(); 00176 planeItr.ResetFirst(); 00177 status->SetVertexPlaneZPosition(dynamic_cast<DmxPlane *>(planeItr.Ptr())->GetZPosition()); 00178 00179 planeItr.GetSet()->ClearSlice(false); 00180 planeItr.ResetFirst(); 00181 00182 //make the iterators for the window, valid planes, and vertex 00183 DmxPlaneItr vertexPlaneItr(planeArray); 00184 DmxPlaneItr validPlaneItr(planeArray); 00185 DmxPlaneItr windowPlaneItr(planeArray); 00186 00187 //create a KeyFunc to sort planes by number 00188 DmxPlaneKeyFunc *vertexPlaneKF = vertexPlaneItr.CreateKeyFunc(); 00189 DmxPlaneKeyFunc *validPlaneKF = validPlaneItr.CreateKeyFunc(); 00190 DmxPlaneKeyFunc *validWindowPlaneKF = windowPlaneItr.CreateKeyFunc(); 00191 00192 //program the KeyFunc with the sort function 00193 vertexPlaneKF->SetFun(KeyOnPlane); 00194 validPlaneKF->SetFun(KeyOnPlane); 00195 validWindowPlaneKF->SetFun(KeyOnPlane); 00196 00197 //get the NavSet from the iterator and pass the KeyFunc to it 00198 vertexPlaneItr.GetSet()->AdoptSortKeyFunc(vertexPlaneKF); 00199 validPlaneItr.GetSet()->AdoptSortKeyFunc(validPlaneKF); 00200 windowPlaneItr.GetSet()->AdoptSortKeyFunc(validWindowPlaneKF); 00201 00202 //clear the KF pointer because we no longer own the KeyFunc 00203 vertexPlaneKF = 0; 00204 validPlaneKF = 0; 00205 validWindowPlaneKF = 0; 00206 planeItr.ResetFirst(); 00207 validPlaneItr.ResetFirst(); 00208 windowPlaneItr.ResetFirst(); 00209 00210 //now program a key function to select on plane orientation - U first 00211 DmxPlaneKeyFunc *orientValidUKF = validPlaneItr.CreateKeyFunc(); 00212 DmxPlaneKeyFunc *orientValidWindowUKF = windowPlaneItr.CreateKeyFunc(); 00213 DmxPlaneKeyFunc *orientUKF = planeItr.CreateKeyFunc(); 00214 DmxPlaneKeyFunc *orientValidVKF = validPlaneItr.CreateKeyFunc(); 00215 DmxPlaneKeyFunc *orientValidWindowVKF = windowPlaneItr.CreateKeyFunc(); 00216 DmxPlaneKeyFunc *orientVKF = planeItr.CreateKeyFunc(); 00217 00218 Int_t viewCtr = 0; 00219 while( viewCtr < 2 ){ 00220 fSlopeRMS = 0.; 00221 fStrayPlanes = 0; 00222 00223 if( viewCtr == 0){ 00224 //program this function with the select function 00225 orientUKF->SetFun(KeyOnUView); 00226 orientValidUKF->SetFun(KeyOnValidU); 00227 orientValidWindowUKF->SetFun(KeyOnValidU); 00228 00229 //adopt it as a selection function 00230 planeItr.GetSet()->AdoptSelectKeyFunc(orientUKF); 00231 orientUKF = 0; 00232 planeItr.Reset(); 00233 validPlaneItr.GetSet()->AdoptSelectKeyFunc(orientValidUKF); 00234 orientValidUKF = 0; 00235 validPlaneItr.Reset(); 00236 windowPlaneItr.GetSet()->AdoptSelectKeyFunc(orientValidWindowUKF); 00237 orientValidWindowUKF = 0; 00238 windowPlaneItr.Reset(); 00239 } 00240 else if(viewCtr == 1){ 00241 //program this function with the select function 00242 orientVKF->SetFun(KeyOnVView); 00243 orientValidVKF->SetFun(KeyOnValidV); 00244 orientValidWindowVKF->SetFun(KeyOnValidV); 00245 00246 //adopt it as a selection function 00247 planeItr.GetSet()->AdoptSelectKeyFunc(orientVKF); 00248 orientVKF = 0; 00249 planeItr.Reset(); 00250 validPlaneItr.GetSet()->AdoptSelectKeyFunc(orientValidVKF); 00251 orientValidVKF = 0; 00252 validPlaneItr.Reset(); 00253 windowPlaneItr.GetSet()->AdoptSelectKeyFunc(orientValidWindowVKF); 00254 orientValidWindowVKF = 0; 00255 windowPlaneItr.Reset(); 00256 } 00257 00258 // validPlaneItr.ResetLast(); 00259 // MSG("AlgDeMuxCosmics", Msg::kDebug)<<"event " << status->GetEventNumber() << endl; 00260 // while(validPlaneItr.IsValid()){ 00261 // MSG("DMX1", Msg::kDebug)<<"\tvalid plane " 00262 // << dynamic_cast<DmxPlane* >(validPlaneItr.Ptr())->GetPlaneNumber() << endl; 00263 // validPlaneItr.Prev(); 00264 // } 00265 00266 // validPlaneItr.Reset(); 00267 00268 // DmxPlane *plane = 0; 00269 00270 // while( (plane = dynamic_cast<DmxPlane *>(validPlaneItr())) ){ 00271 // MSG("DMX1", Msg::kDebug) << "\t" << plane->GetPlaneNumber() <<endl; 00272 // } 00273 // validPlaneItr.Reset(); 00274 00275 //slice to those planes from the vertex on 00276 planeItr.GetSet()->Slice(status->GetVertexPlaneNumber(), status->GetEndPlaneNumber()); 00277 planeItr.GetSet()->Update(); 00278 00279 validPlaneItr.GetSet()->Slice(status->GetVertexPlaneNumber(), status->GetEndPlaneNumber()); 00280 validPlaneItr.GetSet()->Update(); 00281 00282 windowPlaneItr.GetSet()->Slice(status->GetVertexPlaneNumber(), status->GetEndPlaneNumber()); 00283 windowPlaneItr.GetSet()->Update(); 00284 00285 //if only 2 planes set them to their best hyps 00286 if(validPlaneItr.SizeSelect() == 2){ 00287 validPlaneItr.ResetFirst(); 00288 00289 //variables for straight line fit 00290 Float_t cogBeg = -1., zBeg = -1., cogEnd = -1., zEnd = -1.; 00291 00292 while( validPlaneItr.IsValid() ){ 00293 00294 //only set it if it is a shower plane, muon planes are set in the constructor 00295 if(validPlaneItr.Ptr()->GetPlaneType() == DmxPlaneTypes::kShower 00296 && !validPlaneItr.Ptr()->IsGolden()) 00297 dynamic_cast<DmxShowerPlane *>(validPlaneItr.Ptr())->SetStrips("best"); 00298 00299 //cout << dynamic_cast<DmxPlane *>(validPlaneItr.Ptr())->GetCoG() << "\t" 00300 // << dynamic_cast<DmxPlane *>(validPlaneItr.Ptr())->GetPlaneNumber() 00301 // << "\t" << dynamic_cast<DmxPlane *>(validPlaneItr.Ptr())->GetZPosition() << endl; 00302 00303 //set the variables for the straighe line fit between the two planes 00304 if(cogBeg == -1.){ 00305 cogBeg = validPlaneItr.Ptr()->GetCoG(); 00306 zBeg = validPlaneItr.Ptr()->GetZPosition(); 00307 } 00308 else{ 00309 cogEnd = validPlaneItr.Ptr()->GetCoG(); 00310 zEnd = validPlaneItr.Ptr()->GetZPosition(); 00311 } 00312 00313 validPlaneItr.Next(); 00314 }//end loop over planes 00315 00316 //set the nonvalid planes if they exist 00317 if(planeItr.SizeSelect()>2 && cogEnd-cogBeg != 0. && cogBeg != -1. && cogEnd != -1.){ 00318 Double_t slope = (cogEnd-cogBeg)/(zEnd - zBeg); 00319 Double_t intercept = cogBeg - slope*zBeg; 00320 //cout << slope << "\t" << intercept << endl; 00321 SetPlanesToDeterminedFit(planeItr, intercept, slope); 00322 fStrayPlanes += util.FindPlanesOffFit(planeItr, fStrayCut); 00323 } 00324 00325 //fStrayPlanes -= util.CheckFit(validPlaneItr); 00326 validPlaneItr.ResetFirst(); 00327 00328 }//end if only 2 valid planes 00329 else if(validPlaneItr.SizeSelect() >2 ){ 00330 00331 //if there are only enough planes for 1 instances of the sliding window + initial fit, 00332 //change fPlanesInSet to give you 3 + the initial fit, but at least 4 always 00333 if(validPlaneItr.SizeSelect() == (fPlanesInSet+1) && fPlanesInSet==6) fPlanesInSet -= 2; 00334 else if(validPlaneItr.SizeSelect() == (fPlanesInSet+1) 00335 && fPlanesInSet==5) fPlanesInSet -= 1; 00336 00337 if(validPlaneItr.SizeSelect() > fPlanesInSet ){ 00338 UseSlidingWindow(planeItr, validPlaneItr, windowPlaneItr, status, 00339 status->GetVertexPlaneNumber(), 00340 status->GetEndPlaneNumber()); 00341 } 00342 else if(validPlaneItr.SizeSelect() <= fPlanesInSet){ 00343 UseSingleFit(planeItr, validPlaneItr, status); 00344 } 00345 00346 //check the end points of the event - send the validPlaneItr to the function 00347 //fStrayPlanes -= util.CheckFit(validPlaneItr); 00348 00349 //what about multiple muons? look for another vertex after the end plane 00350 planeItr.GetSet()->ClearSlice(false); 00351 validPlaneItr.GetSet()->ClearSlice(false); 00352 windowPlaneItr.GetSet()->ClearSlice(false); 00353 vertexPlaneItr.GetSet()->Slice(status->GetEndPlaneNumber()+1, 500); 00354 vertexPlaneItr.GetSet()->Update(); 00355 00356 //MSG("DMX1", Msg::kDebug)<< "event = " << status->GetEventNumber() 00357 // << "\tend plane = " << status->GetEndPlaneNumber() << endl; 00358 00359 Int_t nextVertex = -1; 00360 if(vertexPlaneItr.SizeSelect() > 3){ nextVertex = util.FindVertexPlane(vertexPlaneItr);} 00361 00362 while( nextVertex != -1){ 00363 00364 status->SetMultipleMuon(true); 00365 cdlh.SetDeMuxDigitListFlagBit(CandDeMuxDigitList::kMultipleMuonEvent); 00366 vertexPlaneItr.GetSet()->ClearSlice(false); 00367 vertexPlaneItr.GetSet()->Slice(nextVertex, 500); 00368 vertexPlaneItr.GetSet()->Update(); 00369 00370 //get the next end plane 00371 Int_t endPlane = util.FindEndPlane(vertexPlaneItr); 00372 00373 //MSG("DMX1", Msg::kDebug)<< "\tin double muon loop, vertex at plane " << nextVertex 00374 // << "\tend plane = " << endPlane << "\tplanes in slice = " 00375 // << vertexPlaneItr.SizeSelect() << endl; 00376 00377 planeItr.GetSet()->Slice(nextVertex, endPlane); 00378 planeItr.GetSet()->Update(); 00379 00380 validPlaneItr.GetSet()->Slice(nextVertex, endPlane); 00381 validPlaneItr.GetSet()->Update(); 00382 00383 windowPlaneItr.GetSet()->Slice(nextVertex, endPlane); 00384 windowPlaneItr.GetSet()->Update(); 00385 00386 //if only 2 planes set them to their best hyps 00387 if(validPlaneItr.SizeSelect() == 2){ 00388 validPlaneItr.ResetFirst(); 00389 00390 //variables for straight line fit 00391 Float_t cogBeg = -1., zBeg = -1., cogEnd = -1., zEnd = -1.; 00392 00393 while( validPlaneItr.IsValid() ){ 00394 00395 //only set it if it is a shower plane, muon planes are set in the constructor 00396 if(validPlaneItr.Ptr()->GetPlaneType() == DmxPlaneTypes::kShower 00397 && !validPlaneItr.Ptr()->IsGolden()) 00398 dynamic_cast<DmxShowerPlane *>(validPlaneItr.Ptr())->SetStrips("best"); 00399 00400 //set the variables for the straighe line fit between the two planes 00401 if(cogBeg == -1.){ 00402 cogBeg = validPlaneItr.Ptr()->GetCoG(); 00403 zBeg = validPlaneItr.Ptr()->GetZPosition(); 00404 } 00405 else{ 00406 cogEnd = validPlaneItr.Ptr()->GetCoG(); 00407 zEnd = validPlaneItr.Ptr()->GetZPosition(); 00408 } 00409 00410 validPlaneItr.Next(); 00411 }//end loop over planes 00412 00413 if(planeItr.SizeSelect()>2 && cogEnd-cogBeg != 0. && cogBeg != -1. && cogEnd != -1.){ 00414 Double_t slope = (cogEnd-cogBeg)/(zEnd - zBeg); 00415 Double_t intercept = cogBeg - slope*zBeg; 00416 SetPlanesToDeterminedFit(planeItr, intercept, slope); 00417 fStrayPlanes += util.FindPlanesOffFit(planeItr, fStrayCut); 00418 } 00419 00420 //fStrayPlanes -= util.CheckFit(validPlaneItr); 00421 validPlaneItr.ResetFirst(); 00422 00423 }//end if only 2 valid planes 00424 else if(validPlaneItr.SizeSelect() > 2){ 00425 //if there are only enough planes for 1 instances of the sliding window + initial fit, 00426 //change fPlanesInSet to give you 3 + the initial fit 00427 if(validPlaneItr.SizeSelect() == (fPlanesInSet+1) && fPlanesInSet==6) fPlanesInSet -= 2; 00428 else if(validPlaneItr.SizeSelect() == (fPlanesInSet+1) 00429 && fPlanesInSet==5) fPlanesInSet -= 1; 00430 00431 if(validPlaneItr.SizeSelect() > fPlanesInSet ){ 00432 UseSlidingWindow(planeItr, validPlaneItr, windowPlaneItr, status, 00433 nextVertex, endPlane); 00434 } 00435 else if(validPlaneItr.SizeSelect() <= fPlanesInSet ){ 00436 UseSingleFit(planeItr, validPlaneItr, status); 00437 } 00438 }//end if more than 2 valid planes in event 00439 00440 //check the end points of the event - send the validPlaneItr to the function 00441 //fStrayPlanes -= util.CheckFit(validPlaneItr); 00442 00443 //look for another vertex after the end plane 00444 planeItr.GetSet()->ClearSlice(false); 00445 validPlaneItr.GetSet()->ClearSlice(false); 00446 windowPlaneItr.GetSet()->ClearSlice(false); 00447 vertexPlaneItr.GetSet()->ClearSlice(false); 00448 00449 vertexPlaneItr.GetSet()->Slice(endPlane+1, 500); 00450 vertexPlaneItr.GetSet()->Update(); 00451 00452 //MSG("DMX1", Msg::kDebug)<< "\tlook for new vertex, slice from " << endPlane+1 00453 // << "\tto plane 500, planes in slice = " 00454 // << vertexPlaneItr.SizeSelect() << endl; 00455 00456 vertexPlaneItr.Reset(); 00457 00458 if(vertexPlaneItr.SizeSelect() > 0){ 00459 nextVertex = util.FindVertexPlane(vertexPlaneItr); 00460 } 00461 else{ nextVertex = -1; } 00462 }//end loop to find next vertex for spread out multiples 00463 }//end if more than 2 valid planes in set 00464 else if(validPlaneItr.SizeSelect() < 2){ 00465 MSG("DMX", Msg::kDebug)<< "Event " << status->GetEventNumber() 00466 << " not demuxed; only " 00467 << validPlaneItr.SizeSelect() 00468 << " valid planes in view" << endl; 00469 00470 status->SetValidPlanesFailure(true); 00471 cdlh.SetDeMuxDigitListFlagBit(CandDeMuxDigitList::kTooFewValidPlanes); 00472 } //not enough planes to demux 00473 00474 //done using the first view, so clear the selection function 00475 //MSG("Dmx", Msg::kDebug) <<"Done with View " << viewCtr << endl; 00476 00477 status->SetFigureOfMerit(validPlaneItr.SizeSelect(), fStrayPlanes); 00478 if(viewCtr == 0 && status->GetEventDeMuxed() ){ 00479 status->SetUStrayPlanes(fStrayPlanes); 00480 status->SetUValidPlanes(validPlaneItr.SizeSelect()); 00481 cdlh.SetNumValidPlanesU(validPlaneItr.SizeSelect()); 00482 cdlh.SetNumStrayPlanesU(fStrayPlanes); 00483 if( status->GetFigureOfMeritFailure() ){ 00484 //see if the event failed the figure of Merit test, if so, see if it is an 00485 //overlapping muon 00486 cdlh.SetDeMuxDigitListFlagBit(CandDeMuxDigitList::kEventFailedFilter); 00487 if(util.IsOverlappingMultiple(validPlaneItr, 1.*status->GetVertexPlaneNumber(), 00488 acd.GetDouble("HoughInterceptRMSLimit"), 00489 acd.GetDouble("HoughSlopeRMSLimit"), 00490 acd.GetDouble("HoughPeakLimit"))){ 00491 status->SetUOverlappingMultiple(true); 00492 cdlh.SetDeMuxDigitListFlagBit(CandDeMuxDigitList::kMultipleMuonEvent); 00493 } 00494 } 00495 } 00496 if(viewCtr == 1 && status->GetEventDeMuxed() ){ 00497 status->SetVStrayPlanes(fStrayPlanes); 00498 status->SetVValidPlanes(validPlaneItr.SizeSelect()); 00499 cdlh.SetNumValidPlanesV(validPlaneItr.SizeSelect()); 00500 cdlh.SetNumStrayPlanesV(fStrayPlanes); 00501 //see if the event failed the figure of Merit test, if so, see if it is an 00502 //overlapping muon 00503 if( status->GetFigureOfMeritFailure() ){ 00504 cdlh.SetDeMuxDigitListFlagBit(CandDeMuxDigitList::kEventFailedFilter); 00505 if(util.IsOverlappingMultiple(validPlaneItr, 1.*status->GetVertexPlaneNumber(), 00506 acd.GetDouble("HoughInterceptRMSLimit"), 00507 acd.GetDouble("HoughSlopeRMSLimit"), 00508 acd.GetDouble("HoughPeakLimit"))){ 00509 status->SetVOverlappingMultiple(true); 00510 cdlh.SetDeMuxDigitListFlagBit(CandDeMuxDigitList::kMultipleMuonEvent); 00511 } 00512 } 00513 } 00514 vertexPlaneItr.GetSet()->ClearSlice(false); 00515 planeItr.GetSet()->ClearSlice(false); 00516 planeItr.GetSet()->AdoptSelectKeyFunc(0); 00517 planeItr.Reset(); 00518 validPlaneItr.GetSet()->ClearSlice(false); 00519 validPlaneItr.GetSet()->AdoptSelectKeyFunc(0); 00520 validPlaneItr.Reset(); 00521 windowPlaneItr.GetSet()->ClearSlice(false); 00522 windowPlaneItr.GetSet()->AdoptSelectKeyFunc(0); 00523 windowPlaneItr.Reset(); 00524 00525 ++viewCtr; 00526 } //end loop over views 00527 00528 //if the event was demuxed, check to see how the demuxing and timing jive 00529 //otherwise see if you need to set the nonphysical solution flag 00530 if( status->GetEventDeMuxed() ){ 00531 status->SetAverageTimingOffset(util.CheckFitWithTiming(validPlaneItr)); 00532 cdlh.SetAvgTimeOffset(status->GetAverageTimingOffset()); 00533 } 00534 else if(status->GetNonPhysicalFailure() ) 00535 cdlh.SetDeMuxDigitListFlagBit(CandDeMuxDigitList::kNonPhysicalStripSolution); 00536 00537 00538 }//end if there was a vertex 00539 else{ 00540 status->SetNoVertexFailure(true); 00541 cdlh.SetDeMuxDigitListFlagBit(CandDeMuxDigitList::kNoVertex); 00542 MSG("DMX", Msg::kDebug) << "no vertex found for event " << status->GetEventNumber() << endl; 00543 } 00544 00545 //get rid of the temporary status object if you made it. 00546 if(tempStatus) delete status; 00547 00548 return; 00549 } 00550 00551 //______________________________________________________________________ 00552 void AlgDeMuxCosmics::Trace(const char * /* c */) const 00553 { 00554 } 00555 00556 00557 //---------------------------------------------------------------------------------- 00558 //this is the method used in the current algorithm 00559 void AlgDeMuxCosmics::FindCosmicSolution(DmxPlaneItr &planeItr, DmxPlaneItr &validPlaneItr, 00560 DmxStatus *status, Double_t &a1, Double_t &a2, 00561 Double_t &a3, Double_t &a4, Double_t &chiSq, 00562 Float_t offset) 00563 { 00564 //variables to keep track of the best reconstruction 00565 Double_t fitA1 = 0.; 00566 Double_t fitA2 = 0.; 00567 Double_t fitA3 = 0.; 00568 Double_t fitA4 = 0.; 00569 Double_t useA1 = -10000.; 00570 Double_t useA2 = -10000.; 00571 Double_t useA3 = -10000.; 00572 Double_t useA4 = -10000.; 00573 Double_t bestChi2 = 1.e20; 00574 Double_t chi2 = 1.000001e20; 00575 Int_t direction = status->GetEventDirection(); 00576 00577 DmxUtilities util; 00578 00579 //make the lever arm for the demuxer the # of valid planes or 6, whichever 00580 //is smaller 00581 UInt_t leverArm = validPlaneItr.SizeSelect(); 00582 00583 if(leverArm > fPlanesInSet){ leverArm = fPlanesInSet;} 00584 00585 //MSG("DMXX", Msg::kDebug) << "in FindCosmicSolution" << endl; 00586 00587 //MSG("DMX", Msg::kDebug) << "\tlever arm = " << leverArm << endl; 00588 00589 //declare an array to tell the fitter which hypotheses to use 00590 Int_t hypsToUse[] = {0,0,0,0,0,0}; 00591 00592 for(Int_t plane0Hyp = 1; plane0Hyp < 4; plane0Hyp++){ 00593 hypsToUse[0] = plane0Hyp; 00594 for(Int_t plane1Hyp = 1; plane1Hyp < 4; plane1Hyp++){ 00595 hypsToUse[1] = plane1Hyp; 00596 if(leverArm == 2){ 00597 00598 FindFit(validPlaneItr, chi2, fitA1, fitA2, fitA3, fitA4, hypsToUse, direction, leverArm, offset); 00599 00600 if(chi2 < bestChi2){ 00601 bestChi2 = chi2; 00602 useA1 = fitA1; 00603 useA2 = fitA2; 00604 useA3 = fitA3; 00605 useA4 = fitA4; 00606 }//end if its a better straight line fit 00607 } 00608 else if(leverArm >= 3){ 00609 for(Int_t plane2Hyp = 1; plane2Hyp < 4; plane2Hyp++){ 00610 hypsToUse[2] = plane2Hyp; 00611 if(leverArm == 3){ 00612 00613 FindFit(validPlaneItr, chi2, fitA1, fitA2, fitA3, fitA4, hypsToUse, direction, leverArm, offset); 00614 00615 if(chi2 < bestChi2 && util.IsValidFit(planeItr, fitA1, fitA2, fitA3, fitA4, offset) ){ 00616 bestChi2 = chi2; 00617 useA1 = fitA1; 00618 useA2 = fitA2; 00619 useA3 = fitA3; 00620 useA4 = fitA4; 00621 00622 //see if you can drop some planes and improve the fit 00623 if( FindPlanesToDropFromFit(validPlaneItr, fitA1, fitA2, fitA3, fitA4, direction, leverArm, offset) ){ 00624 FindFit(validPlaneItr, chi2, fitA1, fitA2, fitA3, fitA4, hypsToUse, direction, leverArm, offset); 00625 00626 if(chi2 < bestChi2 && util.IsValidFit(planeItr, fitA1, fitA2, fitA3, fitA4, offset) ){ 00627 bestChi2 = chi2; 00628 useA1 = fitA1; 00629 useA2 = fitA2; 00630 useA3 = fitA3; 00631 useA4 = fitA4; 00632 } 00633 validPlaneItr.GetSet()->GetMasks().SetAllMasks(kFALSE); 00634 }//end if planes should be dropped because they are way off 00635 }//end if its a better straight line fit 00636 } 00637 else if(leverArm >= 4){ 00638 for(Int_t plane3Hyp = 1; plane3Hyp < 4; plane3Hyp++){ 00639 hypsToUse[3] = plane3Hyp; 00640 if(leverArm == 4){ 00641 00642 FindFit(validPlaneItr, chi2, fitA1, fitA2, fitA3, fitA4, hypsToUse, direction, leverArm, offset); 00643 00644 if(chi2 < bestChi2 && util.IsValidFit(planeItr, fitA1, fitA2, fitA3, fitA4, offset) ){ 00645 bestChi2 = chi2; 00646 useA1 = fitA1; 00647 useA2 = fitA2; 00648 useA3 = fitA3; 00649 useA4 = fitA4; 00650 00651 //see if you can drop some planes and improve the fit 00652 if( FindPlanesToDropFromFit(validPlaneItr, fitA1, fitA2, fitA3, fitA4, direction, leverArm, offset) ){ 00653 FindFit(validPlaneItr, chi2, fitA1, fitA2, fitA3, fitA4, hypsToUse, direction, leverArm, offset); 00654 00655 if(chi2 < bestChi2 && util.IsValidFit(planeItr, fitA1, fitA2, fitA3, fitA4, offset) ){ 00656 bestChi2 = chi2; 00657 useA1 = fitA1; 00658 useA2 = fitA2; 00659 useA3 = fitA3; 00660 useA4 = fitA4; 00661 } 00662 validPlaneItr.GetSet()->GetMasks().SetAllMasks(kFALSE); 00663 }//end if planes should be dropped because they are way off 00664 }//end if its a better straight line fit 00665 } 00666 else if(leverArm >= 5){ 00667 for(Int_t plane4Hyp = 1; plane4Hyp < 4; plane4Hyp++){ 00668 hypsToUse[4] = plane4Hyp; 00669 00670 if(leverArm == 5){ 00671 00672 FindFit(validPlaneItr, chi2, fitA1, fitA2, fitA3, fitA4, hypsToUse, direction, leverArm, offset); 00673 00674 if(chi2 < bestChi2 && util.IsValidFit(planeItr, fitA1, fitA2, fitA3, fitA4, offset) ){ 00675 bestChi2 = chi2; 00676 useA1 = fitA1; 00677 useA2 = fitA2; 00678 useA3 = fitA3; 00679 useA4 = fitA4; 00680 00681 //see if you can drop some planes and improve the fit 00682 if( FindPlanesToDropFromFit(validPlaneItr, fitA1, fitA2, fitA3, fitA4, direction, leverArm, offset) ){ 00683 FindFit(validPlaneItr, chi2, fitA1, fitA2, fitA3, fitA4, hypsToUse, direction, leverArm, offset); 00684 00685 if(chi2 < bestChi2 && util.IsValidFit(planeItr, fitA1, fitA2, fitA3, fitA4, offset) ){ 00686 bestChi2 = chi2; 00687 useA1 = fitA1; 00688 useA2 = fitA2; 00689 useA3 = fitA3; 00690 useA4 = fitA4; 00691 } 00692 validPlaneItr.GetSet()->GetMasks().SetAllMasks(kFALSE); 00693 }//end if planes should be dropped because they are way off 00694 }//end if its a better straight line fit 00695 } 00696 else if(leverArm == 6){ 00697 for(Int_t plane5Hyp = 1; plane5Hyp < 4; plane5Hyp++){ 00698 00699 hypsToUse[5] = plane5Hyp; 00700 FindFit(validPlaneItr, chi2, fitA1, fitA2, fitA3, fitA4, hypsToUse, direction, leverArm, offset); 00701 if(chi2 < bestChi2 && util.IsValidFit(planeItr, fitA1, fitA2, fitA3, fitA4, offset) ){ 00702 bestChi2 = chi2; 00703 useA1 = fitA1; 00704 useA2 = fitA2; 00705 useA3 = fitA3; 00706 useA4 = fitA4; 00707 00708 //see if you can drop some planes and improve the fit 00709 if( FindPlanesToDropFromFit(validPlaneItr, fitA1, fitA2, fitA3, fitA4, direction, leverArm, offset) ){ 00710 FindFit(validPlaneItr, chi2, fitA1, fitA2, fitA3, fitA4, hypsToUse, direction, leverArm, offset); 00711 if(chi2 < bestChi2 && util.IsValidFit(planeItr, fitA1, fitA2, fitA3, fitA4, offset) ){ 00712 bestChi2 = chi2; 00713 useA1 = fitA1; 00714 useA2 = fitA2; 00715 useA3 = fitA3; 00716 useA4 = fitA4; 00717 00718 } 00719 validPlaneItr.GetSet()->GetMasks().SetAllMasks(kFALSE); 00720 } //end if planes should be dropped because they are way off 00721 }//end if its a better straight line fit 00722 }//end for loop over 6th plane's hyps 00723 }//end if using 6 planes 00724 }//end for loop over 5th plane's hyps 00725 }//end if at least 5 planes 00726 } //loop over 4th plane 00727 } //end if at least 4 planes 00728 } //loop over 3rd plane 00729 } //end if at least 3 planes 00730 } //loop over 2nd plane 00731 } //loop over 1st plane 00732 00733 //force the fit to the one found 00734 if(useA1 != -10000. && useA2 != -10000. && useA3 != 10000. && useA4 != 10000.){ 00735 a1 = useA1; 00736 a2 = useA2; 00737 a3 = useA3; 00738 a4 = useA4; 00739 chiSq = bestChi2; 00740 } 00741 00742 //MSG("DMX", Msg::kDebug) << "finished in FindCosmicsSolution" << endl; 00743 return; 00744 } 00745 00746 //---------------------------------------------------------------------------------- 00747 void AlgDeMuxCosmics::FindWindowCosmicSolution(DmxPlaneItr &validPlaneItr, 00748 DmxStatus *status, Double_t &a1, 00749 Double_t &a2, Double_t &a3, 00750 Double_t &a4,Double_t &chiSq, 00751 Float_t offset) 00752 00753 { 00754 //MSG("DMXX", Msg::kDebug) << "in FindWindowCosmicSolution" << endl; 00755 00756 //variables to keep track of the best reconstruction 00757 Double_t fitA1L = 0.; 00758 Double_t fitA2L = 0.; 00759 Double_t chi2L = 1.0e20; 00760 // Double_t fitA1Q = 0.; 00761 // Double_t fitA2Q = 0.; 00762 // Double_t fitA3Q = 0.; 00763 // Double_t chi2Q = 1.0e20; 00764 Double_t fitA1 = 0.; 00765 Double_t fitA2 = 0.; 00766 Double_t fitA3 = 0.; 00767 Double_t fitA4 = 0.; 00768 Double_t chi2 = 1.0e20; 00769 Double_t chi2Fit = 1.0e20; 00770 00771 Int_t direction = status->GetEventDirection(); 00772 00773 //make the lever arm for the demuxer the # of valid planes or 6, whichever 00774 //is smaller 00775 Int_t leverArm = fPlanesInSet; 00776 00777 //offset is the lowest z pos in the window. subtract it from each x array value 00778 //- this has the effect of changing your y axis location 00779 //relative to the z = 0 location so that when doing higher order fits, you 00780 //dont get really stupid numbers 00781 00782 //declare the variables to do a least squares fit to a straight line. 00783 //use three chiSq values to keep track of the 3 different hyps in the 00784 //unset plane - also have 3 different y values for those hyps and 3 00785 //different weights 00786 Double_t x[] = {0.,0.,0.,0.,0.,0.}; 00787 Double_t y[] = {0.,0.,0.,0.,0.,0.}; 00788 Double_t weight[] = {1.,1.,1.,1.,1.,1.}; 00789 Double_t weight2 = 1.; 00790 Double_t weight3 = 1.; 00791 Double_t y2 = 0.; 00792 Double_t y3 = 0.; 00793 00794 //variable to let you know if the unset plane is a golden plane or not 00795 bool lastGolden = false; 00796 00797 Double_t a1L = 0.; 00798 Double_t a2L = 0.; 00799 Double_t a1LB = 0.; 00800 Double_t a2LB = 0.; 00801 Double_t a1LS = 0.; 00802 Double_t a2LS = 0.; 00803 Double_t a1LT = 0.; 00804 Double_t a2LT = 0.; 00805 // Double_t a1QB = 0.; 00806 // Double_t a2QB = 0.; 00807 // Double_t a3QB = 0.; 00808 // Double_t a1QS = 0.; 00809 // Double_t a2QS = 0.; 00810 // Double_t a3QS = 0.; 00811 // Double_t a1QT = 0.; 00812 // Double_t a2QT = 0.; 00813 // Double_t a3QT = 0.; 00814 // Double_t a1Q = 0.; 00815 // Double_t a2Q = 0.; 00816 // Double_t a3Q = 0.; 00817 00818 Double_t chiSqL = 1.e20; 00819 Double_t chiSqLB = 1.e20; 00820 Double_t chiSqLS = 1.e20; 00821 Double_t chiSqLT = 1.e20; 00822 // Double_t chiSqQB = 1.e20; 00823 // Double_t chiSqQS = 1.e20; 00824 // Double_t chiSqQT = 1.e20; 00825 // Double_t chiSqQ = 1.e20; 00826 00827 Double_t a1Fit = 0.; 00828 Double_t a2Fit = 0.; 00829 Double_t a3Fit = 0.; 00830 Double_t a4Fit = 0.; 00831 00832 00833 DmxUtilities util; 00834 00835 if(direction == -1) validPlaneItr.ResetLast(); 00836 else if( direction == 1) validPlaneItr.ResetFirst(); 00837 00838 Int_t planeCtr = 0; 00839 DmxPlane *plane = 0; 00840 00841 while( (plane = validPlaneItr()) && planeCtr < leverArm){ 00842 00843 //cout << "plane = " << plane->GetPlaneNumber() << endl; 00844 00845 x[planeCtr] = plane->GetZPosition() - offset; 00846 y[planeCtr] = plane->GetCoG(); 00847 weight[planeCtr] = 1. / TMath::Sqrt(plane->GetPlaneCharge()); 00848 00849 if(plane->IsGolden()){ 00850 00851 //golden plane, so make the weight smaller to give it more 00852 //clout in the fit 00853 weight[planeCtr] /= TMath::Sqrt(10.); 00854 if(planeCtr == leverArm-1){ 00855 lastGolden = true; 00856 y2 = y[planeCtr]; 00857 y3 = y[planeCtr]; 00858 weight2 = weight[planeCtr]; 00859 weight3 = weight[planeCtr]; 00860 } 00861 } 00862 00863 //only make changes if not a golden plane 00864 if(plane->GetPlaneType() == DmxPlaneTypes::kShower && !plane->IsGolden() ){ 00865 00866 //make sure you dont divide by zero when getting the mated signal ratio of 00867 //the set hypothesis - could be that you set the plane to a hypothesis 00868 //with no mated signal, even though it is a valid plane 00869 if(planeCtr < leverArm-1 00870 && dynamic_cast<DmxShowerPlane *>(plane)->GetSetHypothesis()->GetMatedSignalRatio() > 0.){ 00871 weight[planeCtr] /= TMath::Sqrt(dynamic_cast<DmxShowerPlane *>(plane)->GetSetHypothesis()->GetMatedSignalRatio()); 00872 // MSG("Dmx", Msg::kDebug) << dynamic_cast<DmxShowerPlane *>(plane)->GetSetHypothesis()->GetMatedSignalRatio() << endl; 00873 } 00874 else if( planeCtr == leverArm-1 ){ 00875 00876 y2 = dynamic_cast<DmxShowerPlane *>(plane)->GetSecondBestCoG(); 00877 y3 = dynamic_cast<DmxShowerPlane *>(plane)->GetThirdBestCoG(); 00878 00879 //dont have to worry about dividing by zero here because you havent 00880 //set the plane yet and you know that the best hypotheses in the planes 00881 //must have at least 0.3 mated signal 00882 weight2 = weight[planeCtr]/TMath::Sqrt(dynamic_cast<DmxShowerPlane *>(plane)->GetSecondBestHypothesis()->GetMatedSignalRatio()); 00883 weight3 = weight[planeCtr]/TMath::Sqrt(dynamic_cast<DmxShowerPlane *>(plane)->GetThirdBestHypothesis()->GetMatedSignalRatio()); 00884 00885 weight[planeCtr] /= TMath::Sqrt(dynamic_cast<DmxShowerPlane *>(plane)->GetBestHypothesis()->GetMatedSignalRatio()); 00886 } 00887 } 00888 00889 ++planeCtr; 00890 00891 } //end loop over planes to find variables for fit 00892 00893 //do fit using function in DmxUtilities 00894 00895 //the best hyp fit first 00896 util.FindLinearFit(x, y, weight, leverArm, a1LB, a2LB, chiSqLB); 00897 //util.FindQuadraticFit(x, y, weight, leverArm, a1QB, a2QB, a3QB, chiSqQB); 00898 00899 //find fit for using the last plane's second best hyp 00900 y[leverArm-1] = y2; 00901 weight[leverArm-1] = weight2; 00902 util.FindLinearFit(x, y, weight, leverArm, a1LS, a2LS, chiSqLS); 00903 //util.FindQuadraticFit(x, y, weight, leverArm, a1QS, a2QS, a3QS, chiSqQS); 00904 00905 //find fit using the last plane's third best hyp 00906 y[leverArm-1] = y3; 00907 weight[leverArm-1] = weight3; 00908 util.FindLinearFit(x, y, weight, leverArm, a1LT, a2LT, chiSqLT); 00909 //util.FindQuadraticFit(x, y, weight, leverArm, a1QT, a2QT, a3QT, chiSqQT); 00910 00911 //util.FindCubicFit(x, y, weight, leverArm, a1, a2, a3, a4, chiSq); 00912 00913 // MSG("DMXX", Msg::kDebug) << "\tlinear fit1 " << chiSqLB << "\t" << a1LB << "\t" << a2LB << endl; 00914 // MSG("DMXX", Msg::kDebug) << "\tlinear fit2 " << chiSqLS << "\t" << a1LS << "\t" << a2LS << endl; 00915 // MSG("DMXX", Msg::kDebug) << "\tlinear fit3 " << chiSqLT << "\t" << a1LT << "\t" << a2LT << endl; 00916 //MSG("DMXX", Msg::kDebug) << "\tquadratic fit " << chiSqQ << "\t" << a1Q 00917 // << "\t" << a2Q << "\t" << a3Q << endl; 00918 00919 //pick the better linear fit 00920 if(chiSqLB<=chiSqLS && chiSqLB<=chiSqLT){ 00921 chiSqL = chiSqLB; 00922 a1L = a1LB; 00923 a2L = a2LB; 00924 } 00925 else if(chiSqLS<chiSqLB && chiSqLS<=chiSqLT){ 00926 chiSqL = chiSqLS; 00927 a1L = a1LS; 00928 a2L = a2LS; 00929 } 00930 else if(chiSqLT<chiSqLB && chiSqLT<chiSqLS){ 00931 chiSqL = chiSqLT; 00932 a1L = a1LT; 00933 a2L = a2LT; 00934 } 00935 00936 //pick the better quadratic fit 00937 // if(chiSqQB<=chiSqQS && chiSqQB<=chiSqQT){ 00938 // chiSqQ = chiSqQB; 00939 // a1Q = a1QB; 00940 // a2Q = a2QB; 00941 // a3Q = a3QB; 00942 // } 00943 // else if(chiSqQS<chiSqQB && chiSqQS<=chiSqQT){ 00944 // chiSqQ = chiSqQS; 00945 // a1Q = a1QS; 00946 // a2Q = a2QS; 00947 // a3Q = a3QS; 00948 // } 00949 // else if(chiSqQT<chiSqQB && chiSqQT<chiSqQS){ 00950 // chiSqQ = chiSqQT; 00951 // a1Q = a1QT; 00952 // a2Q = a2QT; 00953 // a3Q = a3QT; 00954 // } 00955 00956 //pick the better fit - linear or quadratic 00957 //if(chiSqL<=chiSqQ){ 00958 chi2Fit = chiSqL; 00959 a1Fit = a1L; 00960 a2Fit = a2L; 00961 a3Fit = 0.; 00962 a4Fit = 0.; 00963 //} 00964 // else{ 00965 // chi2Fit = chiSqQ; 00966 // a1Fit = a1Q; 00967 // a2Fit = a2Q; 00968 // a3Fit = a3Q; 00969 // a4Fit = 0.; 00970 // } 00971 00972 //MSG("DMXX", Msg::kDebug) << "\tinitial fit " << chi2Fit << "\t" << a1Fit << "\t" << a2Fit 00973 // << "\t" << a3Fit << "\t" << a4Fit << endl; 00974 00975 //redo the fit using only the previously set planes and only if you have more than 3 planes in the set 00976 if(leverArm > 3){ 00977 00978 //do fit using function in DmxUtilities 00979 util.FindLinearFit(x, y, weight, leverArm-1, fitA1L, fitA2L, chi2L); 00980 //util.FindQuadraticFit(x, y, weight, planeCtr, fitA1Q, fitA2Q, fitA3Q, chi2Q); 00981 //util.FindCubicFit(x, y, weight, planeCtr, fitA1, fitA2, fitA3, fitA4, chiSq); 00982 00983 //MSG("DMXX", Msg::kDebug) << "\trefined linear fit " << chi2L << "\t" << fitA1L << "\t" << fitA2L << endl; 00984 //MSG("DMXX", Msg::kDebug) << "\tquadratic fit " << chiSqQ << "\t" << a1Q 00985 // << "\t" << a2Q << "\t" << a3Q << endl; 00986 00987 //pick the better fit - linear or quadratic 00988 //if(chi2L<=chi2Q){ 00989 chi2 = chi2L; 00990 fitA1 = fitA1L; 00991 fitA2 = fitA2L; 00992 fitA3 = 0.; 00993 fitA4 = 0.; 00994 //} 00995 // else{ 00996 // chi2 = chi2Q; 00997 // fitA1 = fitA1Q; 00998 // fitA2 = fitA2Q; 00999 // fitA3 = fitA3Q; 01000 // fitA4 = 0.; 01001 // } 01002 01003 01004 if( lastGolden ){ 01005 01006 if(direction == 1) validPlaneItr.ResetLast(); 01007 else if( direction == -1) validPlaneItr.ResetFirst(); 01008 01009 plane = validPlaneItr(); 01010 01011 MSG("AlgDmx", Msg::kDebug) << "last plane number = " << plane->GetPlaneNumber() 01012 << " this is a golden plane " 01013 << plane->IsGolden() << endl; 01014 01015 01016 //unset the IsGolden flag for the last plane if the difference between the 01017 //fit center of gravity and the plane's center of gravity is > 0.5m and 01018 //any of the following 01019 //1. the golden CoG is different from the previous set valid plane's 01020 // CoG by more than 0.25m/plane (plane to plane spacing is 0.1188m) 01021 //2. chi^2 of fit without the golden plane is an order of magnitude 01022 // smaller than the chi^2 of the fit with it 01023 //3. the average difference between the set CoG's and the golden CoG and 01024 // the fit CoG's for all planes in the window is greater than 0.5m 01025 01026 //cout << x[leverArm-1] << " " << x[leverArm-2] << " " << a1Fit << " " << a2Fit << endl; 01027 01028 Double_t fitCoG = (a1Fit + a2Fit*(x[leverArm-1]) 01029 + a3Fit*TMath::Power(x[leverArm-1],2) 01030 + a4Fit*TMath::Power(x[leverArm-1],3)); 01031 01032 Double_t fitDiff = 0.; 01033 for(Int_t ii = 0; ii<leverArm; ii++){ 01034 fitDiff += TMath::Abs((a1Fit + a2Fit*(x[ii]) + a3Fit*TMath::Power(x[ii],2) 01035 + a4Fit*TMath::Power(x[ii],3) - y[ii])); 01036 } 01037 Double_t planeDiff = TMath::Abs(x[leverArm-1]-x[leverArm-2])/0.1188; 01038 01039 MSG("DmxAlg", Msg::kDebug) << "fit is " << fitCoG << " golden CoG = " 01040 << plane->GetCoG() << endl 01041 <<" y diff = " << TMath::Abs(y[leverArm-2]-plane->GetCoG()) 01042 << "/" << planeDiff*.25 << endl 01043 <<" fitDiff = " << fitDiff <<"/" << 0.5*leverArm << endl 01044 << "chi2Fit = " << chi2Fit << "/" << 10.*chi2 << endl; 01045 01046 if(TMath::Abs(plane->GetCoG()-fitCoG)>0.5 && (fitDiff>0.5*leverArm 01047 || TMath::Abs(y[leverArm-2]-plane->GetCoG())>(0.25*planeDiff) 01048 || chi2Fit>10.*chi2)){ 01049 01050 plane->SetGolden(false); 01051 MSG("DmxAlg", Msg::kDebug) << plane->GetPlaneNumber() << " was golden " 01052 << plane->IsGolden() << endl; 01053 lastGolden = false; 01054 } 01055 }//end check of last plane is golden 01056 01057 //if the fit found by dropping the last plane has a better chi^2 than the 01058 //fit using all planes, and that last plane was not golden, then pass the 01059 //fit from the first planes in the window out. if the last plane was initially 01060 //golden, this only happens for the last time through. 01061 // 01062 if(chi2 < chi2Fit && !lastGolden){ 01063 01064 chi2Fit = chi2; 01065 a1Fit = fitA1; 01066 a2Fit = fitA2; 01067 a3Fit = fitA3; 01068 a4Fit = fitA4; 01069 } 01070 01071 }//end for loop to improve fit by dropping a plane 01072 01073 chiSq = chi2Fit; 01074 a1 = a1Fit; 01075 a2 = a2Fit; 01076 a3 = a3Fit; 01077 a4 = a4Fit; 01078 01079 //MSG("DMXX", Msg::kDebug) << "\tchosen linear fit " << chiSq << "\t" << a1 << "\t" << a2 << endl; 01080 01081 validPlaneItr.Reset(); 01082 01083 return; 01084 } 01085 01086 //------------------------------------------------------------------------------------------ 01087 //this method is used in the algorithm 01088 void AlgDeMuxCosmics::UseSingleFit(DmxPlaneItr &planeItr, DmxPlaneItr &validPlaneItr, 01089 DmxStatus *status) 01090 { 01091 //MSG("DMXX", Msg::kDebug) << "in UseSingleFit" << endl; 01092 01093 DmxUtilities util = DmxUtilities(); 01094 01095 Double_t a1F = -10000.; 01096 Double_t a2F = -10000.; 01097 Double_t a3F = -10000.; 01098 Double_t a4F = -10000.; 01099 Double_t chiSqF = 1.1e20; 01100 Double_t a1B = -10000.; 01101 Double_t a2B = -10000.; 01102 Double_t a3B = -10000.; 01103 Double_t a4B = -10000.; 01104 Double_t chiSqB = 1.1e20; 01105 01106 validPlaneItr.ResetFirst(); 01107 Float_t offset = validPlaneItr.Ptr()->GetZPosition(); 01108 validPlaneItr.ResetLast(); 01109 //set the event direction forwards 01110 status->SetEventDirection(1); 01111 01112 //cout << "calling FindCosmicSolution" << endl; 01113 FindCosmicSolution(planeItr, validPlaneItr, status, a1F, a2F, a3F, a4F, chiSqF, offset); 01114 01115 //set the event direction to backwards 01116 status->SetEventDirection(-1); 01117 01118 FindCosmicSolution(planeItr, validPlaneItr, status, a1B, a2B, a3B, a4B, chiSqB, offset); 01119 01120 DmxPlane *plane = 0; 01121 if( chiSqF <= chiSqB && a1F != -10000. && a2F != -10000. 01122 && a3F != -10000. && a4F != 10000.){ 01123 01124 //loop over the planes and if a golden plane cog is more than 0.25m off from the fit 01125 //set it as non-golden. 01126 validPlaneItr.Reset(); 01127 01128 while( (plane = planeItr()) ){ 01129 Double_t fitCoG = (a1F + a2F*plane->GetZPosition() 01130 + a3F*TMath::Power(plane->GetZPosition(),2) 01131 + a4F*TMath::Power(plane->GetZPosition(),3)); 01132 if(plane->IsGolden() && TMath::Abs(plane->GetCoG()-fitCoG)>0.25) plane->SetGolden(false); 01133 } 01134 01135 SetPlanesToDeterminedFit(planeItr, a1F, a2F, a3F, a4F, offset); 01136 01137 fStrayPlanes += util.FindPlanesOffFit(planeItr, fStrayCut); 01138 } 01139 else if(chiSqB < chiSqF && a1B != -10000. && a2B != -10000. 01140 && a3B != 10000. && a4B != 10000.){ 01141 01142 //loop over the planes and if a golden plane cog is more than 0.25m off from the fit 01143 //set it as non-golden. 01144 validPlaneItr.Reset(); 01145 01146 while( (plane = planeItr()) ){ 01147 Double_t fitCoG = (a1B + a2B*plane->GetZPosition() 01148 + a3B*TMath::Power(plane->GetZPosition(),2) 01149 + a4B*TMath::Power(plane->GetZPosition(),3)); 01150 if(plane->IsGolden() && TMath::Abs(plane->GetCoG()-fitCoG)>0.25) plane->SetGolden(false); 01151 } 01152 01153 SetPlanesToDeterminedFit(planeItr, a1B, a2B, a3B, a4B, offset); 01154 01155 fStrayPlanes += util.FindPlanesOffFit(planeItr, fStrayCut); 01156 } 01157 else if( a1B == -10000. && a2B == -10000. && a3B != 10000. && a4B != 10000. 01158 && a1F == -10000. && a2F == -10000. && a3F != -10000. && a4F != 10000.){ 01159 01160 MSG("DMX", Msg::kDebug)<< "Event " << status->GetEventNumber() 01161 << " not demuxed; can't find a physical solution" 01162 << endl; 01163 status->SetNonPhysicalFailure(true); 01164 } 01165 01166 01167 return; 01168 } 01169 01170 //------------------------------------------------------------------------------------------- 01171 //this method is the one used in the current algorithm 01172 void AlgDeMuxCosmics::UseSlidingWindow(DmxPlaneItr &planeItr, DmxPlaneItr &validPlaneItr, 01173 DmxPlaneItr &windowPlaneItr, DmxStatus *status, 01174 Int_t vertex, Int_t endPlane) 01175 { 01176 //MSG("DMXX", Msg::kDebug) << "in UseSlidingWindow" << endl; 01177 01178 //start the sliding window - keep the window to 6 valid planes 01179 //and use the fit parameters you found for the previous set. if the 01180 //new plane is a shower plane, set to the hypothesis nearest the fit. 01181 //if none of the 3 best hypotheses is within 12 strips of the fit, then 01182 //just use the same fit parameters. redo the fit, and then set all 01183 //non-set planes in the window. move the the window down another plane 01184 //and do it again. 01185 01186 DmxUtilities util; 01187 01188 UInt_t validPlaneCnt = validPlaneItr.SizeSelect(); 01189 UInt_t loopCtr = 0; 01190 UInt_t ctr = 0; 01191 Int_t firstPlane = 0; 01192 Int_t almostLastPlane = 0; 01193 Int_t lastPlane = 0; 01194 Double_t a1 = -10000.; 01195 Double_t a2 = -10000.; 01196 Double_t a3 = -10000.; 01197 Double_t a4 = -10000.; 01198 Double_t chiSq = 1.1e20; 01199 Float_t offset = 0.; 01200 DmxPlane *plane = 0; 01201 Int_t direction = 1; //status->GetEventDirection(); 01202 01203 // MSG("dmx", Msg::kDebug) << "Event = " << status->GetEventNumber() << "\tvertex = " << vertex 01204 // << "\tend = " << endPlane << endl; 01205 // while(validPlaneItr.IsValid() ){ 01206 // MSG("dmx", Msg::kDebug) << "\t" << dynamic_cast<DmxPlane *>(validPlaneItr.Ptr())->GetPlaneNumber() 01207 // << "\t" << dynamic_cast<DmxPlane *>(validPlaneItr.Ptr())->IsGolden() 01208 // <<endl; 01209 // validPlaneItr.Next(); 01210 // } 01211 01212 validPlaneItr.ResetFirst(); 01213 windowPlaneItr.ResetFirst(); 01214 01215 //now demux the event the <= makes sure that you find an initial fit for the first 01216 //set of planes, then go from there 01217 while(loopCtr <= (validPlaneCnt - fPlanesInSet) ){ 01218 01219 ctr = 0; 01220 01221 //MSG("dmx", Msg::kDebug) << "find new window" << endl; 01222 //MSG("dmx", Msg::kDebug) << "\tdirection = " << direction; 01223 01224 while( validPlaneItr.IsValid() && ctr < fPlanesInSet){ 01225 01226 plane = validPlaneItr.Ptr(); 01227 //MSG("dmx", Msg::kDebug) << "plane number = " << plane->GetPlaneNumber() 01228 // << endl; 01229 01230 if(direction == 1){ 01231 if( ctr == 0){ 01232 firstPlane = plane->GetPlaneNumber(); 01233 offset = plane->GetZPosition(); 01234 } 01235 if( ctr == fPlanesInSet-2){ almostLastPlane = plane->GetPlaneNumber(); } 01236 if( ctr == fPlanesInSet-1){ lastPlane = plane->GetPlaneNumber(); } 01237 validPlaneItr.Next(); 01238 } 01239 else if(direction == -1){ 01240 if( ctr == 0){ lastPlane = plane->GetPlaneNumber(); } 01241 if( ctr == fPlanesInSet-2){ almostLastPlane = plane->GetPlaneNumber(); } 01242 if( ctr == fPlanesInSet-1){ 01243 firstPlane = plane->GetPlaneNumber(); 01244 offset = plane->GetZPosition(); 01245 } 01246 validPlaneItr.Prev(); 01247 } 01248 ++ctr; 01249 01250 } 01251 01252 //MSG("dmx", Msg::kDebug) << "end find new window" << endl; 01253 ctr = 0; 01254 01255 //MSG("dmx", Msg::kDebug) << "\tfirst plane = " << firstPlane << "\talmost last plane = " 01256 // << almostLastPlane << "\tlast plane = " << lastPlane << endl; 01257 01258 //move the window 01259 windowPlaneItr.GetSet()->ClearSlice(false); 01260 planeItr.GetSet()->ClearSlice(false); 01261 01262 windowPlaneItr.GetSet()->Slice(firstPlane, lastPlane); 01263 windowPlaneItr.GetSet()->Update(); 01264 planeItr.GetSet()->Slice(firstPlane, lastPlane); 01265 planeItr.GetSet()->Update(); 01266 01267 if( loopCtr == 0){ 01268 01269 //set the initial window - try it both ways and take the best one as 01270 //determined by the chiSq 01271 Double_t a1B = -10000.; 01272 Double_t a2B = -10000.; 01273 Double_t a3B = -10000.; 01274 Double_t a4B = -10000.; 01275 Double_t chiSqB = 1.1e20; 01276 01277 //set the event direction forwards 01278 status->SetEventDirection(1); 01279 01280 //you are looking at the first planes of the event, so your offset should be the 01281 //z position of the vertex 01282 Float_t offsetF = status->GetVertexZPosition(); 01283 01284 FindCosmicSolution(planeItr, windowPlaneItr, status, a1, a2, a3, a4, chiSq, offsetF); 01285 01286 //MSG("dmx", Msg::kDebug) << "\tforward direction" << a1 << "\t" << a2 01287 // << "\t" << chiSq << "\t" << offset << endl; 01288 01289 //set the event direction to backwards 01290 Int_t forwardLastPlane = lastPlane; 01291 01292 status->SetEventDirection(-1); 01293 direction = -1; 01294 validPlaneItr.ResetLast(); 01295 windowPlaneItr.GetSet()->ClearSlice(false); 01296 planeItr.GetSet()->ClearSlice(false); 01297 windowPlaneItr.ResetLast(); 01298 ctr = 0; 01299 01300 //MSG("dmx", Msg::kDebug) << "check reverse direction" << endl; 01301 while( validPlaneItr.IsValid() && ctr < fPlanesInSet){ 01302 01303 plane = validPlaneItr.Ptr(); 01304 // MSG("dmx", Msg::kDebug) << "plane number = " << plane->GetPlaneNumber() 01305 // << endl; 01306 01307 if( ctr == 0){ lastPlane = plane->GetPlaneNumber(); } 01308 if( ctr == fPlanesInSet-2){ almostLastPlane = plane->GetPlaneNumber(); } 01309 if( ctr == fPlanesInSet-1){ 01310 firstPlane = plane->GetPlaneNumber(); 01311 offset = plane->GetZPosition(); 01312 } 01313 ++ctr; 01314 validPlaneItr.Prev(); 01315 } 01316 //MSG("dmx", Msg::kDebug) << "end check reverse direction" << endl; 01317 ctr = 0; 01318 01319 //MSG("dmx", Msg::kDebug) << "first plane = " << firstPlane << "\talmost last plane = " 01320 // << almostLastPlane << "\tlast plane = " << lastPlane << endl; 01321 01322 windowPlaneItr.GetSet()->Slice(firstPlane, lastPlane); 01323 windowPlaneItr.GetSet()->Update(); 01324 windowPlaneItr.ResetLast(); 01325 planeItr.GetSet()->Slice(firstPlane, lastPlane); 01326 planeItr.GetSet()->Update(); 01327 01328 FindCosmicSolution(planeItr, windowPlaneItr, status, a1B, a2B, a3B, a4B, chiSqB, offset); 01329 01330 //MSG("dmx", Msg::kDebug) << "\tbackward direction" << a1B << "\t" << a2B 01331 // << "\t" << chiSqB << "\t" << offset << endl; 01332 01333 if( chiSq <= chiSqB && a1 != -10000. && a2 != -10000. && a3 != 10000. && a4 != 10000.){ 01334 planeItr.GetSet()->ClearSlice(false); 01335 01336 //slice from the vertex to the last plane in the forward direction to get them 01337 //all 01338 planeItr.GetSet()->Slice(vertex, forwardLastPlane); 01339 planeItr.GetSet()->Update(); 01340 01341 //loop over the planes and if a golden plane cog is more than 0.25m off from the fit 01342 //set it as non-golden. 01343 windowPlaneItr.GetSet()->ClearSlice(false); 01344 windowPlaneItr.GetSet()->Slice(vertex, forwardLastPlane); 01345 windowPlaneItr.GetSet()->Update(); 01346 01347 while( (plane = windowPlaneItr()) ){ 01348 Double_t fitCoG = (a1 + a2*plane->GetZPosition() 01349 + a3*TMath::Power(plane->GetZPosition(),2) 01350 + a4*TMath::Power(plane->GetZPosition(),3)); 01351 if(plane->IsGolden() && TMath::Abs(plane->GetCoG()-fitCoG)>0.25) plane->SetGolden(false); 01352 } 01353 01354 //MSG("dmx", Msg::kDebug) << "\tloop = " << loopCtr << "\tsetting planes " << vertex 01355 // << "\tto " << forwardLastPlane << endl; 01356 01357 SetPlanesToDeterminedFit(planeItr, a1, a2, a3, a4, offsetF); 01358 01359 fStrayPlanes += util.FindPlanesOffFit(planeItr, fStrayCut); 01360 01361 status->SetEventDirection(1); 01362 direction = 1; 01363 validPlaneItr.ResetFirst(); 01364 ctr = 0; 01365 01366 //get the validPlaneItr back to where it should be for this direction 01367 while(ctr<fPlanesInSet){ 01368 validPlaneItr.Next(); 01369 ++ctr; 01370 } 01371 01372 ctr = 0; 01373 01374 } 01375 else if(chiSqB < chiSq && a1B != -10000. && a2B != -10000. && a3B != 10000. && a4B != 10000.){ 01376 01377 //set a, b, and chiSq to the backwards values 01378 a1 = a1B; 01379 a2 = a2B; 01380 a3 = a3B; 01381 a4 = a4B; 01382 chiSq = chiSqB; 01383 01384 //slice from the end plane to the first plane 01385 planeItr.GetSet()->ClearSlice(false); 01386 planeItr.GetSet()->Slice(firstPlane, endPlane); 01387 planeItr.GetSet()->Update(); 01388 01389 //loop over the planes and if a golden plane cog is more than 0.25m off from the fit 01390 //set it as non-golden. 01391 windowPlaneItr.ResetFirst(); 01392 while( (plane = windowPlaneItr()) ){ 01393 Double_t fitCoG = (a1 + a2*plane->GetZPosition() 01394 + a3*TMath::Power(plane->GetZPosition(),2) 01395 + a4*TMath::Power(plane->GetZPosition(),3)); 01396 if(plane->IsGolden() && TMath::Abs(plane->GetCoG()-fitCoG)>0.25) plane->SetGolden(false); 01397 } 01398 //MSG("dmx", Msg::kDebug) << "\tloop = " << loopCtr << "\tsetting planes " << firstPlane 01399 // << "\tto " << endPlane << endl; 01400 01401 SetPlanesToDeterminedFit(planeItr, a1, a2, a3, a4, offset); 01402 01403 fStrayPlanes += util.FindPlanesOffFit(planeItr, fStrayCut); 01404 01405 //event direction is already backwards and the validPlaneItr is where it should be 01406 } 01407 else if( a1B == -10000. && a2B == -10000. && a1 == -10000. 01408 && a2 == -10000. && a3 == -10000. && a4 == -10000. 01409 && a3B == -10000. && a4B == -10000.){ 01410 01411 MSG("dmx", Msg::kDebug)<< "Event " << status->GetEventNumber() 01412 << " not demuxed;" 01413 << " can't find a physical solution" << endl; 01414 status->SetNonPhysicalFailure(true); 01415 } 01416 //MSG("dmx", Msg::kDebug) << "\tloop 0 fit - " << a1 << "\t" << a2 << "\t" << a3 << "\tchi^2 = " 01417 // << chiSq << "\tstray planes = " << fStrayPlanes << endl; 01418 }//end if initial set 01419 else{ 01420 //set the window 01421 01422 FindWindowCosmicSolution(windowPlaneItr, status, a1, a2, a3, a4, chiSq, offset); 01423 01424 //MSG("dmx", Msg::kDebug) << "\tloop " << loopCtr << " " << firstPlane << " " << lastPlane 01425 // << "\t" << a1 << "\t" << a2 << "\t" << a3 << "\tchi^2 = " 01426 // << chiSq << "\tstray planes = " << fStrayPlanes << endl; 01427 01428 planeItr.GetSet()->ClearSlice(false); 01429 if(direction == 1 ){ 01430 firstPlane = almostLastPlane + 1; 01431 //if its the last loop, select the rest of the unset planes to set, otherwise 01432 //stay in the loop bounds 01433 if(loopCtr == (validPlaneItr.SizeSelect()-fPlanesInSet)) lastPlane = endPlane; 01434 } 01435 else if(direction == -1 ){ 01436 lastPlane = almostLastPlane-1; 01437 if(loopCtr == (validPlaneItr.SizeSelect()-fPlanesInSet)) firstPlane = vertex; 01438 } 01439 planeItr.GetSet()->Slice(firstPlane, lastPlane); 01440 planeItr.GetSet()->Update(); 01441 01442 //MSG("dmx", Msg::kDebug) << "\tloop = " << loopCtr << "\tsetting planes " << firstPlane 01443 // << "\tto " << lastPlane << endl; 01444 01445 SetPlanesToDeterminedFit(planeItr, a1, a2, a3, a4, offset); 01446 fStrayPlanes += util.FindPlanesOffFit(planeItr, fStrayCut); 01447 //status->SetHistogramEntries(b, a, plane->GetPlaneView()); 01448 } 01449 01450 01451 ctr = 0; 01452 01453 //set the validPlaneItr to the opposite direction and back up 5 planes 01454 //MSG("dmx", Msg::kDebug) << "move iterator to first plane in new window" << endl; 01455 while(ctr<fPlanesInSet-1 && validPlaneItr.IsValid()){ 01456 01457 //MSG("dmx", Msg::kDebug) << "plane number = " 01458 // << dynamic_cast<DmxPlane *>(validPlaneItr.Ptr())->GetPlaneNumber() 01459 // << endl; 01460 ++ctr; 01461 if(direction == 1){ validPlaneItr.Prev(); } 01462 else if(direction == -1){ validPlaneItr.Next(); } 01463 } 01464 //MSG("dmx", Msg::kDebug) << "end move iterator to first plane in new window" << endl; 01465 ctr = 0; 01466 01467 //should go through the loop and get the new window 01468 ++loopCtr; 01469 } 01470 01471 return; 01472 } 01473 01474 //----------------------------------------------------------------------------- 01475 //this method is used in the current algorithm 01476 //find the best line for a set of planes 01477 void AlgDeMuxCosmics::FindFit(DmxPlaneItr &planeItr, Double_t &prevChiSq, 01478 Double_t &a1, Double_t &a2, Double_t &a3, 01479 Double_t &a4, Int_t* hypotheses, 01480 Int_t direction, Int_t leverArm, Float_t offset) 01481 { 01482 01483 //MSG("DMXX", Msg::kDebug) << "in FindFit" << endl; 01484 01485 //cout << "in find fit for first n planes" << endl; 01486 Double_t a1L = 0.; 01487 Double_t a2L = 0.; 01488 Double_t a1Q = 0.; 01489 Double_t a2Q = 0.; 01490 Double_t a3Q = 0.; 01491 01492 Double_t chiSqL = 1.e20; 01493 Double_t chiSqQ = 1.e20; 01494 01495 //declare the variables to do a least squares fit to a straight line. 01496 //weight is the inverse fraction of the total charge on the plane that 01497 //is on opposite ends of common strips. multiply the inverse by a 01498 //sensible number to take account for digits with 1000+ adc's 01499 01500 //the arrays are the number of planes in the set, ie the lever arm 01501 Double_t x[] = {0.,0.,0.,0.,0.,0.}; 01502 Double_t y[] = {0.,0.,0.,0.,0.,0.}; 01503 Double_t weight[] = {1.,1.,1.,1.,1.,1.}; 01504 01505 DmxUtilities util; 01506 01507 //cout << "got util object" << endl; 01508 if(direction == -1){ planeItr.ResetLast(); } 01509 else if( direction == 1){ planeItr.ResetFirst(); } 01510 01511 //planeItr.ResetFirst(); 01512 01513 Int_t planeCtr = 0; 01514 Int_t arrayCtr = 0; 01515 DmxPlane *plane = 0; 01516 01517 01518 //MSG("DMX", Msg::kDebug) << "\t" << hypotheses[0] << "\t" << hypotheses[1] 01519 // << "\t" << hypotheses[2] << "\t" << hypotheses[3] 01520 // << "\t" << hypotheses[4] << "\t" << hypotheses[5] << endl; 01521 01522 //loop over the plane iterator to fill the variables 01523 01524 while( (plane = planeItr()) && planeCtr < leverArm){ 01525 01526 if( !planeItr.GetSet()->GetMasks().GetMask(plane) ){ 01527 x[arrayCtr] = plane->GetZPosition() - offset; 01528 01529 //get the maximum possible weight first, then for each hypothesis multiply by the square of the fraction 01530 weight[arrayCtr] = 1./ TMath::Sqrt(plane->GetPlaneCharge()); 01531 if(plane->IsGolden()) weight[arrayCtr] /= TMath::Sqrt(10.); 01532 01533 y[arrayCtr] = plane->GetCoG(); 01534 01535 //only do this if the shower plane is not golden - if it is, you know where it should be 01536 //reconstructed to 01537 if( plane->GetPlaneType() == DmxPlaneTypes::kShower && !plane->IsGolden()){ 01538 01539 if(hypotheses[planeCtr] == 1){ 01540 //MSG("DMX", Msg::kDebug) << "\t" << dynamic_cast<DmxShowerPlane *>(plane)->GetBestHypothesis()->GetCoG(); 01541 weight[arrayCtr] /= TMath::Sqrt(dynamic_cast<DmxShowerPlane *>(plane)->GetBestHypothesis()->GetMatedSignalRatio()); 01542 } 01543 //plane->GetCoG() returns the best hypothesis CoG so only change the value of y if you are wanting 01544 //the 2nd or 3rd best hypotheses 01545 else if(hypotheses[planeCtr] == 2){ 01546 //MSG("DMX", Msg::kDebug) << "\t" << dynamic_cast<DmxShowerPlane *>(plane)->GetSecondBestHypothesis()->GetCoG(); 01547 y[arrayCtr] = dynamic_cast<DmxShowerPlane *>(plane)->GetSecondBestCoG(); 01548 weight[arrayCtr] /= TMath::Sqrt(dynamic_cast<DmxShowerPlane *>(plane)->GetSecondBestHypothesis()->GetMatedSignalRatio()); 01549 } 01550 else if(hypotheses[planeCtr] == 3){ 01551 //MSG("DMX", Msg::kDebug) << "\t" << dynamic_cast<DmxShowerPlane *>(plane)->GetThirdBestHypothesis()->GetCoG(); 01552 y[arrayCtr] = dynamic_cast<DmxShowerPlane *>(plane)->GetThirdBestCoG(); 01553 weight[arrayCtr] /= TMath::Sqrt(dynamic_cast<DmxShowerPlane *>(plane)->GetThirdBestHypothesis()->GetMatedSignalRatio()); 01554 } 01555 } 01556 ++arrayCtr; 01557 01558 }//end if the plane isnt marked as sucking && it is in the window bounds 01559 01560 ++planeCtr; 01561 } //end loop over planes to find variables for fit 01562 01563 //cout << "filled arrays" << endl; 01564 01565 Double_t chiSq = 0.; 01566 01567 //use the DmxUtilities function to find a linear fit 01568 util.FindLinearFit(x, y, weight, arrayCtr, a1L, a2L, chiSqL); 01569 //util.FindQuadraticFit(x, y, weight, arrayCtr, a1Q, a2Q, a3Q, chiSqQ); 01570 //util.FindCubicFit(x, y, weight, arrayCtr, a1, a2, a3, a4, chiSq); 01571 01572 //MSG("DMXX", Msg::kDebug) << "\tlinear fit " << chiSqL << "\t" << a1L << "\t" << a2L << endl; 01573 //MSG("DMXX", Msg::kDebug) << "\tquadratic fit " << chiSqQ << "\t" << a1Q 01574 // << "\t" << a2Q << "\t" << a3Q << endl; 01575 01576 //pick the better fit 01577 if(chiSqL<=chiSqQ){ 01578 prevChiSq = chiSqL; 01579 a1 = a1L; 01580 a2 = a2L; 01581 a3 = 0.; 01582 a4 = 0.; 01583 } 01584 else{ 01585 prevChiSq = chiSqQ; 01586 a1 = a1Q; 01587 a2 = a2Q; 01588 a3 = a3Q; 01589 a4 = 0.; 01590 } 01591 //MSG("DMX", Msg::kDebug) << "\tinitial fit " << a1 << "\t" << a2 << "\t" << a3 << "\t" << a4 << chiSq << endl; 01592 01593 planeItr.Reset(); 01594 planeCtr = 0; 01595 arrayCtr = 0; 01596 //cout << "reset the iterator" << endl; 01597 01598 //redo the fit as many times as there are planes, dropping each plane in 01599 //turn to see if it produces a better chi^2 value - only do it if you have 01600 //more than 3 planes - ie you can drop one and still do a reasonable fit 01601 //2 planes = great straight line every time. 01602 if(leverArm > 3){ 01603 a1L = 0.; 01604 a2L = 0.; 01605 a1Q = 0.; 01606 a2Q = 0.; 01607 a3Q = 0.; 01608 01609 Double_t fitA1 = 0.; 01610 Double_t fitA2 = 0.; 01611 Double_t fitA3 = 0.; 01612 Double_t fitA4 = 0.; 01613 01614 for(Int_t i = 0; i < leverArm; i++){ 01615 arrayCtr = 0; 01616 01617 //cout <<"in loop " << i << endl; 01618 //loop over the plane iterator to fill the variables 01619 while( (plane = planeItr()) && planeCtr < leverArm){ 01620 01621 //use those planes not marked as kTRUE - a mark of kTRUE means to drop the plane 01622 //from the set when finding the fit. ie if its true, the plane truely sucks 01623 if( !planeItr.GetSet()->GetMasks().GetMask(plane) ){ 01624 01625 if(i != planeCtr){ 01626 x[arrayCtr] = plane->GetZPosition() - offset; 01627 y[arrayCtr] = plane->GetCoG(); 01628 01629 //cout << "filling arrays " << arrayCtr << " " << x[arrayCtr] << " " << y[arrayCtr] 01630 // << " " << weightSq[arrayCtr] << endl; 01631 01632 weight[arrayCtr] = 1. / TMath::Sqrt(plane->GetPlaneCharge()); 01633 if(plane->IsGolden()) weight[arrayCtr] /= TMath::Sqrt(10.); 01634 01635 //only make changes if not a golden plane 01636 if( plane->GetPlaneType() == DmxPlaneTypes::kShower && !plane->IsGolden()){ 01637 //only change y if the hypothesis isnt the best one - the unset plane returns the best 01638 //cog from the GetCoG() method 01639 01640 if(hypotheses[planeCtr] == 1){ 01641 weight[arrayCtr] /= TMath::Sqrt(dynamic_cast<DmxShowerPlane *>(plane)->GetBestHypothesis()->GetMatedSignalRatio()); 01642 } 01643 else if(hypotheses[planeCtr] == 2){ 01644 y[arrayCtr] = dynamic_cast<DmxShowerPlane *>(plane)->GetSecondBestCoG(); 01645 weight[arrayCtr] /= TMath::Sqrt(dynamic_cast<DmxShowerPlane *>(plane)->GetSecondBestHypothesis()->GetMatedSignalRatio()); 01646 } 01647 else if(hypotheses[planeCtr] == 3){ 01648 y[arrayCtr] = dynamic_cast<DmxShowerPlane *>(plane)->GetThirdBestCoG(); 01649 weight[arrayCtr] /= TMath::Sqrt(dynamic_cast<DmxShowerPlane *>(plane)->GetThirdBestHypothesis()->GetMatedSignalRatio()); 01650 } 01651 } 01652 01653 ++arrayCtr; 01654 //else{ MSG("DMX", Msg::kDebug) << "\tdrop plane " << plane->GetPlaneNumber() << endl; } 01655 } //end if plane is not the dropped one 01656 }//end if plane is in window bounds 01657 ++planeCtr; 01658 } //end loop over planes to find variables for fit 01659 01660 //use the DmxUtilities function to find a linear fit 01661 01662 util.FindLinearFit(x, y, weight, arrayCtr, a1L, a2L, chiSqL); 01663 //util.FindQuadraticFit(x, y, weight, arrayCtr, a1Q, a2Q, a3Q, chiSqQ); 01664 //util.FindCubicFit(x, y, weight, arrayCtr, fitA1, fitA2, fitA3, fitA4, chiSq); 01665 01666 //MSG("DMXX", Msg::kDebug) << "\tlinear fit " << chiSqL << "\t" << a1L << "\t" << a2L << endl; 01667 //MSG("DMXX", Msg::kDebug) << "\tquadratic fit " << chiSqQ << "\t" << a1Q 01668 // << "\t" << a2Q << "\t" << a3Q << endl; 01669 //pick the better fit 01670 if(chiSqL<=chiSqQ){ 01671 chiSq = chiSqL; 01672 fitA1 = a1L; 01673 fitA2 = a2L; 01674 } 01675 else{ 01676 chiSq = chiSqQ; 01677 fitA1 = a1Q; 01678 fitA2 = a2Q; 01679 fitA3 = a3Q; 01680 } 01681 01682 planeItr.Reset(); 01683 01684 planeCtr = 0; 01685 if(chiSq < prevChiSq){ 01686 prevChiSq = chiSq; 01687 a1 = fitA1; 01688 a2 = fitA2; 01689 a3 = fitA3; 01690 a4 = fitA4; 01691 //MSG("DMX", Msg::kDebug) << "\trefined fit, drop plane " << i 01692 // << "\t" << prevChiSq << "\t" << a << "\t" << b << endl; 01693 } 01694 01695 }//end for loop to improve fit by dropping a plane 01696 }//end if enough planes to improve fit 01697 01698 planeItr.ResetFirst(); 01699 //MSG("DMX", Msg::kDebug) << "\tfinal fit" << "\t" << a << "\t" << b << "\t" << prevChiSq << endl; 01700 01701 //cout << "finished find fit for first n planes" << endl; 01702 01703 return; 01704 } 01705 01706 //------------------------------------------------------------------------------------------ 01707 //function to set the planes in the event to the straight line fit 01708 //this one is used in the current algorithm 01709 void AlgDeMuxCosmics::SetPlanesToDeterminedFit(DmxPlaneItr &planeItr, Double_t a1, Double_t a2, 01710 Double_t a3, Double_t a4, Float_t offset) 01711 { 01712 //MSG("DMXX", Msg::kDebug) << "in SetPlanesToDeterminedFit" << endl; 01713 01714 planeItr.ResetFirst(); 01715 01716 DmxPlane *plane = 0; 01717 01718 while( planeItr.IsValid() ){ 01719 01720 plane = planeItr.Ptr(); 01721 01722 //MSG("DMXX", Msg::kDebug)<<"\tin SetPlanesToDeterminedFit " << plane->GetPlaneNumber() 01723 // <<" has golden flag " << (Int_t)plane->IsGolden() << endl; 01724 01725 Float_t fitCoG = (a1 + (plane->GetZPosition()-offset)*a2 01726 + TMath::Power(plane->GetZPosition()-offset,2)*a3 01727 + TMath::Power(plane->GetZPosition()-offset,3)*a4); 01728 01729 //MSG("DMXX", Msg::kDebug)<< a1 << "\t" << a2 << "\t" << a3 01730 // << "\t" << a4 << "\t" << fitCoG 01731 // << "\t" << plane->GetZPosition() << endl; 01732 01733 //golden planes have already been set in their constructors 01734 if( !plane->IsGolden() ){ 01735 //MSG("DMXX", Msg::kDebug)<<"\tsetting plane " << plane->GetPlaneNumber() 01736 // << " to " << fitCoG << endl; 01737 plane->SetStrips(fitCoG); 01738 } 01739 01740 planeItr.Next(); 01741 } 01742 01743 planeItr.Reset(); 01744 01745 //cout << "finished set planes for fit" << endl; 01746 return; 01747 } 01748 01749 //------------------------------------------------------------------------------------------ 01750 //function to set the planes in the event to the straight line fit 01751 //used for cases with only 2 valid planes in a view 01752 void AlgDeMuxCosmics::SetPlanesToDeterminedFit(DmxPlaneItr &planeItr, Double_t a, Double_t b) 01753 { 01754 01755 //MSG("DMXX", Msg::kDebug) << "in SetPlanesToDeterminedFit" << endl; 01756 01757 planeItr.ResetFirst(); 01758 01759 DmxPlane *plane = 0; 01760 01761 while( planeItr.IsValid() ){ 01762 01763 plane = planeItr.Ptr(); 01764 01765 //if(plane->GetPlaneNumber()>=firstPlane && plane->GetPlaneNumber()<=lastPlane){ 01766 //MSG("DMXX", Msg::kDebug)<<"\tin SetPlanesToDeterminedFit " << plane->GetPlaneNumber() 01767 // <<" has golden flag " << (Int_t)plane->IsGolden() << endl; 01768 Float_t fitCoG = a + (plane->GetZPosition() * b); 01769 //MSG("DMXX", Msg::kDebug)<< a << "\t" << b << "\t" << fitCoG << endl; 01770 01771 //golden planes have already been set in their constructors 01772 if( !plane->IsGolden() ){ 01773 //MSG("DMXX", Msg::kDebug)<<"\tsetting plane " << plane->GetPlaneNumber() << endl; 01774 plane->SetStrips(fitCoG); 01775 } 01776 //}//end if plane is in the window bounds 01777 01778 planeItr.Next(); 01779 } 01780 01781 planeItr.Reset(); 01782 01783 return; 01784 } 01785 01786 //------------------------------------------------------------------------------ 01787 //function to identify planes whose 3 best hypotheses are all way off from the fit line 01788 //make a cut for them to be at least 12 strips off. only pass this an iterator over valid 01789 //planes 01790 Bool_t AlgDeMuxCosmics::FindPlanesToDropFromFit(DmxPlaneItr &planeItr, Double_t a1, Double_t a2, 01791 Double_t a3, Double_t a4, 01792 Int_t direction, Int_t leverArm, Float_t offset) 01793 { 01794 01795 //MSG("DMXX", Msg::kDebug) << "in FindPlanesToDropFromFit" << endl; 01796 01797 Double_t diff1 = 0.; 01798 Double_t diff2 = 0.; 01799 Double_t diff3 = 0.; 01800 bool planesDropped = false; 01801 01802 Int_t dropPlanes = 0; 01803 Int_t planeCtr = 0; 01804 if( direction == 1 ){ planeItr.ResetFirst(); } 01805 else if( direction == -1 ){ planeItr.ResetLast(); } 01806 01807 //MSG("DMX", Msg::kDebug)<<"\tin FindPlanesToDropFromFit"; 01808 01809 DmxPlane *plane = 0; 01810 //find the plane farthest off from the fit, keep going until you have just 3 planes left 01811 while( (plane = planeItr()) && dropPlanes<(Int_t)(0.1*leverArm) && planeCtr<leverArm){ 01812 01813 Double_t fitCoG = (a1 + (plane->GetZPosition()-offset)*a2 01814 + TMath::Power(plane->GetZPosition()-offset,2)*a3 01815 + TMath::Power(plane->GetZPosition()-offset,3)*a4); 01816 01817 //MSG("DMX", Msg::kDebug)<<"\t" << plane->GetPlaneNumber() << endl; 01818 01819 if( !planeItr.GetSet()->GetMasks().GetMask(plane) ){ 01820 if( plane->GetPlaneType() == DmxPlaneTypes::kShower ){ 01821 diff1 = TMath::Abs(fitCoG-dynamic_cast<DmxShowerPlane *>(plane)->GetBestCoG()); 01822 diff2 = TMath::Abs(fitCoG-dynamic_cast<DmxShowerPlane *>(plane)->GetSecondBestCoG()); 01823 diff3 = TMath::Abs(fitCoG-dynamic_cast<DmxShowerPlane *>(plane)->GetThirdBestCoG()); 01824 } 01825 else if( plane->GetPlaneType() == DmxPlaneTypes::kMuon ){ 01826 diff1 = TMath::Abs(fitCoG - plane->GetCoG()); 01827 diff2 = TMath::Abs(fitCoG - plane->GetCoG()); 01828 diff3 = TMath::Abs(fitCoG - plane->GetCoG()); 01829 } 01830 01831 //if all the 3 best hypotheses are way off from the fit, that plane is most 01832 //likely messing up the fit. so mark it as kTRUE - ie it, it truely sucks 01833 if(diff1 > .504 && diff2 > .504 && diff3 > .504 && !plane->IsGolden() ){ 01834 planeItr.GetSet()->GetMasks().SetMask(kTRUE, planeItr.Ptr()); 01835 planesDropped = true; 01836 //MSG("DMX", Msg::kDebug)<<"\tmarking plane " << plane->GetPlaneNumber() << endl; 01837 //decrement the number of planes now used for a fit. 01838 ++dropPlanes; 01839 } 01840 else if(diff1 > 0.504 && plane->IsGolden()){ 01841 01842 //if this was a golden plane but it just doesnt work, make a non-golden plane 01843 planeItr.GetSet()->GetMasks().SetMask(kTRUE, planeItr.Ptr()); 01844 plane->SetGolden(false); 01845 planesDropped = true; 01846 //MSG("DMX", Msg::kDebug)<<"\tmarking plane " << plane->GetPlaneNumber() << endl; 01847 //decrement the number of planes now used for a fit. 01848 ++dropPlanes; 01849 }//end if dropping a golden plane 01850 } //end if the mask hasnt already been set for this plane 01851 01852 ++planeCtr; 01853 } 01854 planeItr.ResetFirst(); 01855 01856 //cout << "finished drop planes from fit" << endl; 01857 01858 return planesDropped; 01859 } 01860 01861 //---------------------------------------------------------------------------------- 01862 // void AlgDeMuxCosmics::FindWinCosmicSolution(DmxPlaneItr &validPlaneItr, DmxStatus *status, 01863 // Double_t &a1, Double_t &a2, Double_t &a3, Double_t &a4, 01864 // Double_t &chiSq, Float_t offset) 01865 01866 // { 01867 // MSG("DMXX", Msg::kDebug) << "in FindWinCosmicSolution" << endl; 01868 01869 // //variables to keep track of the best reconstruction 01870 // Double_t fitA1 = 0.; 01871 // Double_t fitA2 = 0.; 01872 // Double_t fitA3 = 0.; 01873 // Double_t fitA4 = 0.; 01874 // Double_t useA1 = -10000.; 01875 // Double_t useA2 = -10000.; 01876 // Double_t useA3 = -10000.; 01877 // Double_t useA4 = -10000.; 01878 // Double_t bestChi2 = 1.0e20; 01879 // Double_t chi2 = 1.0000001e20; 01880 // Int_t direction = status->GetEventDirection(); 01881 01882 // //make the lever arm for the demuxer the # of valid planes or 6, whichever 01883 // //is smaller 01884 // Int_t leverArm = fPlanesInSet; 01885 01886 // for(Int_t unSetPlaneHyp = 1; unSetPlaneHyp < 4; unSetPlaneHyp++){ 01887 01888 // FindFit(validPlaneItr, chi2, fitA1, fitA2, fitA3, fitA4, 01889 // unSetPlaneHyp, direction, leverArm, offset); 01890 01891 // if(chi2 < bestChi2 ){ 01892 // bestChi2 = chi2; 01893 // useA1 = fitA1; 01894 // useA2 = fitA2; 01895 // useA3 = fitA3; 01896 // useA4 = fitA4; 01897 // }//end if its a better straight line fit 01898 // } 01899 01900 // //check to make sure that the fit parameters aren't the defaults and 01901 // //that the bestChi2 fit for the window isn't horrible compared to the previous 01902 // //fit 01903 // if(useA1 != -10000. && useA2 != -10000. && useA3 != -10000. 01904 // && useA4 != -10000. ){//&& bestChi2<10.*chiSq){ 01905 // a1 = useA1; 01906 // a2 = useA2; 01907 // a3 = useA3; 01908 // a4 = useA4; 01909 // chiSq = bestChi2; 01910 // } 01911 01912 // //MSG("DMXX", Msg::kDebug) << "\tchosen linear fit " << chiSq << "\t" << a1 << "\t" << a2 << endl; 01913 01914 // return; 01915 // } 01916 01917 //--------------------------------------------------------------------------------------- 01918 //find the best line for a set of planes 01919 // void AlgDeMuxCosmics::FindFit(DmxPlaneItr &planeItr, Double_t &prevChiSq, 01920 // Double_t &a1, Double_t &a2, Double_t &a3, 01921 // Double_t &a4, Int_t unSetPlaneHyp, 01922 // Int_t direction, Int_t leverArm, Float_t offset) 01923 // { 01924 01925 // MSG("DMXX", Msg::kDebug) << "in FindFit" << endl; 01926 01927 // //offset is the lowest z pos in the window. subtract it from each x array value 01928 // //- this has the effect of changing your y axis location 01929 // //relative to the z = 0 location so that when doing higher order fits, you 01930 // //dont get really stupid numbers 01931 01932 // //cout << "in find fit for window" << endl; 01933 01934 // //declare the variables to do a least squares fit to a straight line. 01935 01936 // Double_t x[] = {0.,0.,0.,0.,0.,0.}; 01937 // Double_t y[] = {0.,0.,0.,0.,0.,0.}; 01938 // Double_t weight[] = {1.,1.,1.,1.,1.,1.}; 01939 // Double_t chiSq = 0.; 01940 01941 // Double_t a1L = 0.; 01942 // Double_t a2L = 0.; 01943 // Double_t a1Q = 0.; 01944 // Double_t a2Q = 0.; 01945 // Double_t a3Q = 0.; 01946 01947 // Double_t chiSqL = 1.e20; 01948 // Double_t chiSqQ = 1.e20; 01949 01950 // DmxUtilities util; 01951 01952 // if(direction == -1){ planeItr.ResetLast(); } 01953 // else if( direction == 1){ planeItr.ResetFirst(); } 01954 01955 // Int_t planeCtr = 0; 01956 // DmxPlane *plane = 0; 01957 01958 // while( (plane = planeItr()) && planeCtr < leverArm){ 01959 01960 // //if(plane->GetPlaneNumber()>=firstPlane && plane->GetPlaneNumber()<=lastPlane){ 01961 // x[planeCtr] = plane->GetZPosition() - offset; 01962 // y[planeCtr] = plane->GetCoG(); 01963 // weight[planeCtr] = 1. / TMath::Sqrt(plane->GetPlaneCharge()); 01964 // if(plane->IsGolden()) weight[planeCtr] /= TMath::Sqrt(10.); 01965 01966 // //only make changes if not a golden plane 01967 // if(plane->GetPlaneType() == DmxPlaneTypes::kShower && !plane->IsGolden()){ 01968 // if( planeCtr < leverArm-1 ){ 01969 // weight[planeCtr] /= TMath::Sqrt(dynamic_cast<DmxShowerPlane *>(plane)->GetSetHypothesis()->GetMatedSignalRatio()); 01970 // } 01971 // else if( planeCtr == leverArm-1 && unSetPlaneHyp == 1 ){ 01972 // weight[planeCtr] /= TMath::Sqrt(dynamic_cast<DmxShowerPlane *>(plane)->GetBestHypothesis()->GetMatedSignalRatio()); 01973 // } 01974 // else if( planeCtr == leverArm-1 && unSetPlaneHyp == 2 ){ 01975 // y[planeCtr] = dynamic_cast<DmxShowerPlane *>(plane)->GetSecondBestCoG(); 01976 // weight[planeCtr] /= TMath::Sqrt(dynamic_cast<DmxShowerPlane *>(plane)->GetSecondBestHypothesis()->GetMatedSignalRatio()); 01977 // } 01978 // else if( planeCtr == leverArm-1 && unSetPlaneHyp == 3 ){ 01979 // y[planeCtr] = dynamic_cast<DmxShowerPlane *>(plane)->GetThirdBestCoG(); 01980 // weight[planeCtr] /= TMath::Sqrt(dynamic_cast<DmxShowerPlane *>(plane)->GetThirdBestHypothesis()->GetMatedSignalRatio()); 01981 // } 01982 // } 01983 01984 01985 // ++planeCtr; 01986 01987 // //}//end if plane is in bounds for the window. 01988 // } //end loop over planes to find variables for fit 01989 01990 // planeItr.Reset(); 01991 // planeCtr = 0; 01992 01993 // //do fit using function in DmxUtilities 01994 // util.FindLinearFit(x, y, weight, leverArm, a1L, a2L, chiSqL); 01995 // //util.FindQuadraticFit(x, y, weight, leverArm, a1Q, a2Q, a3Q, chiSqQ); 01996 // //util.FindCubicFit(x, y, weight, leverArm, a1, a2, a3, a4, chiSq); 01997 01998 // MSG("DMXX", Msg::kDebug) << "\tlinear fit " << chiSqL << "\t" << a1L << "\t" << a2L << endl; 01999 // //MSG("DMXX", Msg::kDebug) << "\tquadratic fit " << chiSqQ << "\t" << a1Q 02000 // // << "\t" << a2Q << "\t" << a3Q << endl; 02001 02002 // //pick the better fit 02003 // if(chiSqL<=chiSqQ){ 02004 // prevChiSq = chiSqL; 02005 // a1 = a1L; 02006 // a2 = a2L; 02007 // a3 = 0.; 02008 // a4 = 0.; 02009 // } 02010 // else{ 02011 // prevChiSq = chiSqQ; 02012 // a1 = a1Q; 02013 // a2 = a2Q; 02014 // a3 = a3Q; 02015 // a4 = 0.; 02016 // } 02017 02018 // //MSG("DMXX", Msg::kDebug) << "\tinitial fit " << prevChiSq << "\t" << a1 << "\t" << a2 02019 // // << "\t" << a3 << "\t" << a4 << endl; 02020 02021 // //redo the fit using only the previously set planes and only if you have more than 3 planes in the set 02022 // if(leverArm > 3){ 02023 // a1L = 0.; 02024 // a2L = 0.; 02025 // a1Q = 0.; 02026 // a2Q = 0.; 02027 // a3Q = 0.; 02028 02029 // Double_t fitA1 = 0.; 02030 // Double_t fitA2 = 0.; 02031 // Double_t fitA3 = 0.; 02032 // Double_t fitA4 = 0.; 02033 02034 // //loop over the plane iterator to fill the variables 02035 // //use all but the last plane in the set to see what your fit is without it 02036 // while( (plane = planeItr()) && planeCtr < (leverArm - 1)){ 02037 02038 // x[planeCtr] = plane->GetZPosition() - offset; 02039 // y[planeCtr] = plane->GetCoG(); 02040 // //weight[planeCtr] = 100. / plane->GetPlaneCharge(); 02041 // //if(plane->IsGolden() ) weight[planeCtr] = 0.001; // /= TMath::Sqrt(10.); 02042 // weight[planeCtr] = 1. / TMath::Sqrt(plane->GetPlaneCharge()); 02043 // if(plane->IsGolden() ) weight[planeCtr] /= TMath::Sqrt(10.); 02044 02045 // if(plane->GetPlaneType() == DmxPlaneTypes::kShower && !plane->IsGolden()){ 02046 // weight[planeCtr] /= TMath::Sqrt(dynamic_cast<DmxShowerPlane *>(plane)->GetSetHypothesis()->GetMatedSignalRatio()); 02047 // } 02048 02049 // ++planeCtr; 02050 02051 // } //end loop over planes to find variables for fit 02052 02053 02054 // planeItr.Reset(); 02055 02056 // //do fit using function in DmxUtilities 02057 // util.FindLinearFit(x, y, weight, planeCtr, a1L, a2L, chiSqL); 02058 // //util.FindQuadraticFit(x, y, weight, planeCtr, a1Q, a2Q, a3Q, chiSqQ); 02059 // //util.FindCubicFit(x, y, weight, planeCtr, fitA1, fitA2, fitA3, fitA4, chiSq); 02060 02061 // MSG("DMXX", Msg::kDebug) << "\trefined linear fit " << chiSqL << "\t" << a1L << "\t" << a2L << endl; 02062 // //MSG("DMXX", Msg::kDebug) << "\tquadratic fit " << chiSqQ << "\t" << a1Q 02063 // // << "\t" << a2Q << "\t" << a3Q << endl; 02064 // //pick the better fit 02065 // if(chiSqL<=chiSqQ){ 02066 // chiSq = chiSqL; 02067 // fitA1 = a1L; 02068 // fitA2 = a2L; 02069 // } 02070 // else{ 02071 // chiSq = chiSqQ; 02072 // fitA1 = a1Q; 02073 // fitA2 = a2Q; 02074 // fitA3 = a3Q; 02075 // } 02076 02077 // //MSG("DMXX", Msg::kDebug) << "\tdrop fit " << chiSq << "\t" << fitA1 << "\t" << fitA2 02078 // // << "\t" << fitA3 << "\t" << fitA4 << endl << "\t\t" << x[0] << "\t" 02079 // // << x[planeCtr] << "\t" << planeCtr << endl; 02080 // planeCtr = 0; 02081 02082 // bool droppedGolden = false; 02083 02084 // while( (plane = planeItr()) ){ 02085 02086 // if( planeCtr == (leverArm - 1) && plane->IsGolden() && unSetPlaneHyp == 3){ 02087 // droppedGolden = true; 02088 02089 // //if this is the 3rd time through the loop and the difference in the golden CoG and the 02090 // //fitCoG without the golden plane is greater than 0.25m, and the fit is inside the detector 02091 // //then set the plane as non-Golden it just fooled the golden cut beforee 02092 // //or, go with the better fit if it is way better - ie the chi^2 is a factor of 10 02093 // //or more less than the fit with all planes, golden or not. again, only do that 02094 // //the last time through 02095 02096 // Double_t fitCoG = (fitA1 + fitA2*(plane->GetZPosition()-offset) 02097 // + fitA3*TMath::Power(plane->GetZPosition()-offset,2) 02098 // + fitA4*TMath::Power(plane->GetZPosition()-offset,3)); 02099 02100 // if(TMath::Abs(fitCoG)<=4.0 02101 // && (TMath::Abs(plane->GetCoG()-fitCoG)>0.25 || prevChiSq>10.*chiSq)){ 02102 // plane->SetGolden(false); 02103 // //MSG("DmxAlg", Msg::kDebug) << " is golden " << (Int_t)plane->IsGolden() << endl; 02104 // droppedGolden = false; 02105 // } 02106 // }//end check of last plane is golden 02107 // ++planeCtr; 02108 02109 // } //end loop to find chiSq 02110 02111 // planeCtr = 0; 02112 // planeItr.Reset(); 02113 02114 // //if the fit found by dropping the last plane has a better chi^2 than the 02115 // //fit using all planes, and that last plane was not golden, then pass the 02116 // //fit from the first planes in the window out. if the last plane was initially 02117 // //golden, this only happens for the last time through. 02118 // // 02119 // if(chiSq < prevChiSq && !droppedGolden){ 02120 02121 // prevChiSq = chiSq; 02122 // a1 = fitA1; 02123 // a2 = fitA2; 02124 // a3 = fitA3; 02125 // a4 = fitA4; 02126 // } 02127 02128 // planeItr.Reset(); 02129 02130 // }//end for loop to improve fit by dropping a plane 02131 02132 // planeItr.ResetFirst(); 02133 02134 // //cout << "finished find fit for window" << endl; 02135 02136 // return; 02137 // } 02138 02139 //------------------------------------------------------------------------------------- 02140 //function to identify planes whose 3 best hypotheses are all way off from the fit line 02141 //make a cut for them to be at least 12 strips off. only pass this an iterator over valid 02142 //planes 02143 // Bool_t AlgDeMuxCosmics::FindPlanesToDropFromFit(DmxPlaneItr &planeItr, Double_t a, Double_t b, 02144 // Int_t direction, Int_t leverArm, 02145 // Int_t /* firstPlane */, Int_t /* lastPlane */) 02146 // { 02147 // MSG("DMXX", Msg::kDebug) << "in FindPlanesToDropFromFit" << endl; 02148 02149 // Double_t diff1 = 0.; 02150 // Double_t diff2 = 0.; 02151 // Double_t diff3 = 0.; 02152 // bool planesDropped = false; 02153 02154 // Int_t dropPlanes = 0; 02155 // Int_t planeCtr = 0; 02156 // if( direction == 1 ){ planeItr.ResetFirst(); } 02157 // else if( direction == -1 ){ planeItr.ResetLast(); } 02158 02159 // //MSG("DMX", Msg::kDebug)<<"\tin FindPlanesToDropFromFit"; 02160 02161 // DmxPlane *plane = 0; 02162 // //find the plane farthest off from the fit, keep going until you have just 3 planes left 02163 // while( (plane = planeItr()) && dropPlanes<(Int_t)(0.1*leverArm) && planeCtr<leverArm){ 02164 02165 // //if(plane->GetPlaneNumber()>=firstPlane && plane->GetPlaneNumber()<=lastPlane){ 02166 // Double_t fitCoG = a + ((plane->GetZPosition() * 1.0) * b); 02167 // //MSG("DMX", Msg::kDebug)<<"\t" << plane->GetPlaneNumber() << endl; 02168 02169 // if( !planeItr.GetSet()->GetMasks().GetMask(plane) ){ 02170 // if( plane->GetPlaneType() == DmxPlaneTypes::kShower ){ 02171 // diff1 = TMath::Abs(fitCoG-dynamic_cast<DmxShowerPlane *>(plane)->GetBestCoG()); 02172 // diff2 = TMath::Abs(fitCoG-dynamic_cast<DmxShowerPlane *>(plane)->GetSecondBestCoG()); 02173 // diff3 = TMath::Abs(fitCoG-dynamic_cast<DmxShowerPlane *>(plane)->GetThirdBestCoG()); 02174 // } 02175 // else if( plane->GetPlaneType() == DmxPlaneTypes::kMuon ){ 02176 // diff1 = TMath::Abs(fitCoG - plane->GetCoG()); 02177 // diff2 = TMath::Abs(fitCoG - plane->GetCoG()); 02178 // diff3 = TMath::Abs(fitCoG - plane->GetCoG()); 02179 // } 02180 02181 // //if all the 3 best hypotheses are way off from the fit, that plane is most 02182 // //likely messing up the fit. so mark it as kTRUE - ie it, it truely sucks 02183 // if(diff1 > .504 && diff2 > .504 && diff3 > .504 && !plane->IsGolden() ){ 02184 // planeItr.GetSet()->GetMasks().SetMask(kTRUE, planeItr.Ptr()); 02185 // planesDropped = true; 02186 // //MSG("DMX", Msg::kDebug)<<"\tmarking plane " << plane->GetPlaneNumber() << endl; 02187 // //decrement the number of planes now used for a fit. 02188 // ++dropPlanes; 02189 // } 02190 // else if(diff1 > 0.504 && plane->IsGolden()){ 02191 02192 // //if this was a golden plane but it just doesnt work, make a non-golden plane 02193 // planeItr.GetSet()->GetMasks().SetMask(kTRUE, planeItr.Ptr()); 02194 // plane->SetGolden(false); 02195 // planesDropped = true; 02196 // //MSG("DMX", Msg::kDebug)<<"\tmarking plane " << plane->GetPlaneNumber() << endl; 02197 // //decrement the number of planes now used for a fit. 02198 // ++dropPlanes; 02199 // }//end if dropping a golden plane 02200 // } //end if the mask hasnt already been set for this plane 02201 02202 // ++planeCtr; 02203 // //}//end if plane is in window bounds 02204 // } 02205 // planeItr.ResetFirst(); 02206 02207 // return planesDropped; 02208 // } 02209 02210 //---------------------------------------------------------------------------------- 02211 // void AlgDeMuxCosmics::FindCosmicSolution(DmxPlaneItr &planeItr, DmxPlaneItr &validPlaneItr, 02212 // DmxStatus *status, Double_t &a, Double_t &b, 02213 // Double_t &chiSq, Int_t firstPlane, Int_t lastPlane) 02214 // { 02215 // MSG("DMXX", Msg::kDebug) << "in FindCosmicSolution" << endl; 02216 02217 // //variables to keep track of the best reconstruction 02218 // Double_t fitA = 0.; 02219 // Double_t fitB = 0.; 02220 // Double_t useA = -10000.; 02221 // Double_t useB = -10000.; 02222 // Double_t bestChi2 = 1.e20; 02223 // Double_t chi2 = 1.0000001e20; 02224 // Int_t direction = status->GetEventDirection(); 02225 02226 // DmxUtilities util; 02227 // //make the lever arm for the demuxer the # of valid planes or 6, whichever 02228 // //is smaller 02229 // UInt_t leverArm = validPlaneItr.SizeSelect(); 02230 02231 // if(leverArm > fPlanesInSet){ leverArm = fPlanesInSet;} 02232 02233 // //MSG("DMX", Msg::kDebug) << "\tlever arm = " << leverArm << endl; 02234 02235 // //declare an array to tell the fitter which hypotheses to use 02236 // Int_t hypsToUse[] = {0,0,0,0,0,0}; 02237 02238 // for(Int_t plane0Hyp = 1; plane0Hyp < 4; plane0Hyp++){ 02239 // hypsToUse[0] = plane0Hyp; 02240 // for(Int_t plane1Hyp = 1; plane1Hyp < 4; plane1Hyp++){ 02241 // hypsToUse[1] = plane1Hyp; 02242 // if(leverArm == 2){ 02243 02244 // FindStraightLineFit(validPlaneItr, chi2, fitA, fitB, hypsToUse, direction, leverArm, firstPlane, lastPlane); 02245 02246 // if(chi2 < bestChi2){ 02247 // bestChi2 = chi2; 02248 // useA = fitA; 02249 // useB = fitB; 02250 // }//end if its a better straight line fit 02251 // } 02252 // else if(leverArm >= 3){ 02253 // for(Int_t plane2Hyp = 1; plane2Hyp < 4; plane2Hyp++){ 02254 // hypsToUse[2] = plane2Hyp; 02255 // if(leverArm == 3){ 02256 02257 // FindStraightLineFit(validPlaneItr, chi2, fitA, fitB, hypsToUse, direction, leverArm, firstPlane, lastPlane); 02258 02259 // if(chi2 < bestChi2 && util.IsValidFit(planeItr, fitA, fitB, firstPlane, lastPlane) ){ 02260 // bestChi2 = chi2; 02261 // useA = fitA; 02262 // useB = fitB; 02263 02264 // //see if you can drop some planes and improve the fit 02265 // if( FindPlanesToDropFromFit(validPlaneItr, fitA, fitB, direction, leverArm, firstPlane, lastPlane) ){ 02266 // FindStraightLineFit(validPlaneItr, chi2, fitA, fitB, hypsToUse, direction, leverArm, firstPlane, lastPlane); 02267 02268 // if(chi2 < bestChi2 && util.IsValidFit(planeItr, fitA, fitB, firstPlane, lastPlane) ){ 02269 // bestChi2 = chi2; 02270 // useA = fitA; 02271 // useB = fitB; 02272 // } 02273 // validPlaneItr.GetSet()->GetMasks().SetAllMasks(kFALSE); 02274 // }//end if planes should be dropped because they are way off 02275 // }//end if its a better straight line fit 02276 // } 02277 // else if(leverArm >= 4){ 02278 // for(Int_t plane3Hyp = 1; plane3Hyp < 4; plane3Hyp++){ 02279 // hypsToUse[3] = plane3Hyp; 02280 // if(leverArm == 4){ 02281 02282 // FindStraightLineFit(validPlaneItr, chi2, fitA, fitB, hypsToUse, direction, leverArm, firstPlane, lastPlane); 02283 02284 // if(chi2 < bestChi2 && util.IsValidFit(planeItr, fitA, fitB, firstPlane, lastPlane) ){ 02285 // bestChi2 = chi2; 02286 // useA = fitA; 02287 // useB = fitB; 02288 02289 // //see if you can drop some planes and improve the fit 02290 // if( FindPlanesToDropFromFit(validPlaneItr, fitA, fitB, direction, leverArm, firstPlane, lastPlane) ){ 02291 // FindStraightLineFit(validPlaneItr, chi2, fitA, fitB, hypsToUse, direction, leverArm, firstPlane, lastPlane); 02292 02293 // if(chi2 < bestChi2 && util.IsValidFit(planeItr, fitA, fitB, firstPlane, lastPlane) ){ 02294 // bestChi2 = chi2; 02295 // useA = fitA; 02296 // useB = fitB; 02297 // } 02298 // validPlaneItr.GetSet()->GetMasks().SetAllMasks(kFALSE); 02299 // }//end if planes should be dropped because they are way off 02300 // }//end if its a better straight line fit 02301 // } 02302 // else if(leverArm >= 5){ 02303 // for(Int_t plane4Hyp = 1; plane4Hyp < 4; plane4Hyp++){ 02304 // hypsToUse[4] = plane4Hyp; 02305 02306 // if(leverArm == 5){ 02307 02308 // FindStraightLineFit(validPlaneItr, chi2, fitA, fitB, hypsToUse, direction, leverArm, firstPlane, lastPlane); 02309 02310 // if(chi2 < bestChi2 && util.IsValidFit(planeItr, fitA, fitB, firstPlane, lastPlane) ){ 02311 // bestChi2 = chi2; 02312 // useA = fitA; 02313 // useB = fitB; 02314 02315 // //see if you can drop some planes and improve the fit 02316 // if( FindPlanesToDropFromFit(validPlaneItr, fitA, fitB, direction, leverArm, firstPlane, lastPlane) ){ 02317 // FindStraightLineFit(validPlaneItr, chi2, fitA, fitB, hypsToUse, direction, leverArm, firstPlane, lastPlane); 02318 02319 // if(chi2 < bestChi2 && util.IsValidFit(planeItr, fitA, fitB, firstPlane, lastPlane) ){ 02320 // bestChi2 = chi2; 02321 // useA = fitA; 02322 // useB = fitB; 02323 // } 02324 // validPlaneItr.GetSet()->GetMasks().SetAllMasks(kFALSE); 02325 // }//end if planes should be dropped because they are way off 02326 // }//end if its a better straight line fit 02327 // } 02328 // else if(leverArm == 6){ 02329 // for(Int_t plane5Hyp = 1; plane5Hyp < 4; plane5Hyp++){ 02330 02331 // hypsToUse[5] = plane5Hyp; 02332 // FindStraightLineFit(validPlaneItr, chi2, fitA, fitB, hypsToUse, direction, leverArm, firstPlane, lastPlane); 02333 // if(chi2 < bestChi2 && util.IsValidFit(planeItr, fitA, fitB, firstPlane, lastPlane) ){ 02334 // bestChi2 = chi2; 02335 // useA = fitA; 02336 // useB = fitB; 02337 // //MSG("DMX", Msg::kDebug) << "\tfindstraightlinefit" << useA << "\t" << useB << "\t" << chi2 << endl; 02338 02339 // //see if you can drop some planes and improve the fit 02340 // if( FindPlanesToDropFromFit(validPlaneItr, fitA, fitB, direction, leverArm, firstPlane, lastPlane) ){ 02341 // FindStraightLineFit(validPlaneItr, chi2, fitA, fitB, hypsToUse, direction, leverArm, firstPlane, lastPlane); 02342 // if(chi2 < bestChi2 && util.IsValidFit(planeItr, fitA, fitB, firstPlane, lastPlane) ){ 02343 // bestChi2 = chi2; 02344 // useA = fitA; 02345 // useB = fitB; 02346 // //MSG("DMX", Msg::kDebug) << "\tfindstraightlinedropfit" << useA << "\t" << useB << "\t" << chi2 << endl; 02347 02348 // } 02349 // validPlaneItr.GetSet()->GetMasks().SetAllMasks(kFALSE); 02350 // } //end if planes should be dropped because they are way off 02351 // }//end if its a better straight line fit 02352 // }//end for loop over 6th plane's hyps 02353 // }//end if using 6 planes 02354 // }//end for loop over 5th plane's hyps 02355 // }//end if at least 5 planes 02356 // } //loop over 4th plane 02357 // } //end if at least 4 planes 02358 // } //loop over 3rd plane 02359 // } //end if at least 3 planes 02360 // } //loop over 2nd plane 02361 // } //loop over 1st plane 02362 02363 // //force the fit to the one found 02364 // if(useA != -10000. && useB != -10000.){ 02365 // a = useA; 02366 // b = useB; 02367 // chiSq = bestChi2; 02368 02369 // //loop over the planes and if a golden plane cog is more than 0.25m off from the fit 02370 // //set it as non-golden. 02371 // validPlaneItr.Reset(); 02372 // DmxPlane *plane = 0; 02373 02374 // while( (plane = dynamic_cast<DmxPlane *>(planeItr())) ){ 02375 // if(plane->IsGolden() && TMath::Abs(a+(b*plane->GetZPosition()))>0.25) plane->SetGolden(false); 02376 // } 02377 // validPlaneItr.Reset(); 02378 02379 // } 02380 02381 // //MSG("DMX", Msg::kDebug) << "\t" << a << "\t" << b << "\t" << chiSq << endl; 02382 // return; 02383 // } 02384 02385 //---------------------------------------------------------------------------------- 02386 // void AlgDeMuxCosmics::FindWindowCosmicSolution(DmxPlaneItr &validPlaneItr, DmxStatus *status, 02387 // Double_t &a, Double_t &b, Double_t &chiSq, Int_t firstPlane, 02388 // Int_t lastPlane) 02389 02390 // { 02391 // MSG("DMXX", Msg::kDebug) << "in FindWindowCosmicSolution" << endl; 02392 02393 // //variables to keep track of the best reconstruction 02394 // Double_t fitA = 0.; 02395 // Double_t fitB = 0.; 02396 // Double_t useA = -10000.; 02397 // Double_t useB = -10000.; 02398 // Double_t bestChi2 = 1.e20; 02399 // Double_t chi2 = 1.000001e20; 02400 // Int_t direction = status->GetEventDirection(); 02401 02402 // //make the lever arm for the demuxer the # of valid planes or 6, whichever 02403 // //is smaller 02404 // Int_t leverArm = fPlanesInSet; 02405 02406 // for(Int_t unSetPlaneHyp = 1; unSetPlaneHyp < 4; unSetPlaneHyp++){ 02407 02408 // FindStraightLineFit(validPlaneItr, chi2, fitA, fitB, unSetPlaneHyp, direction, leverArm, firstPlane, lastPlane); 02409 02410 // if(chi2 < bestChi2 ){ 02411 // bestChi2 = chi2; 02412 // useA = fitA; 02413 // useB = fitB; 02414 // }//end if its a better straight line fit 02415 // } 02416 02417 // a = useA; 02418 // b = useB; 02419 // chiSq = bestChi2; 02420 02421 // return; 02422 // } 02423 02424 //------------------------------------------------------------------------------------ 02425 //find the best line for a set of planes 02426 // void AlgDeMuxCosmics::FindStraightLineFit(DmxPlaneItr &planeItr, Double_t &prevChiSq, 02427 // Double_t &a, Double_t &b, Int_t* hypotheses, 02428 // Int_t direction, Int_t leverArm, 02429 // Int_t /* firstPlane */, Int_t /* lastPlane */) 02430 // { 02431 // MSG("DMXX", Msg::kDebug) << "in FindStraightLineFit" << endl; 02432 02433 02434 // //declare the variables to do a least squares fit to a straight line. all 02435 // //equations taken from Bevington, second edition. fit to the line 02436 // //CoG = a + b*plane 02437 // //where CoG is the center of gravity for plane number plane. 02438 // //the variables used are 02439 // // pSqDivSSqSum = sum of (plane number)^2 / (weight)^2 02440 // // cogDivSSqSum = sum of (center of gravity)^2 / (weight)^2 02441 // // pDivSSqSum = sum of plane number / (weight)^2 02442 // // pCoGDivSSqSum = sum of (plane number * center of gravity) / (weight)^2 02443 // // invSSqSum = sum of weight^-2 02444 // // pDivSSqSum = sum of plane number / weight^2 02445 // //weight is the inverse fraction of the total charge on the plane that is on opposite ends of common strips 02446 // //multiply the inverse by a sensible number to take account for digits with 1000+ adc's 02447 02448 // Double_t pSqDivSSqSum = 0.; 02449 // Double_t cogDivSSqSum = 0.; 02450 // Double_t pDivSSqSum = 0.; 02451 // Double_t pCoGDivSSqSum = 0.; 02452 // Double_t invSSqSum = 0.; 02453 02454 // if(direction == -1){ planeItr.ResetLast(); } 02455 // else if( direction == 1){ planeItr.ResetFirst(); } 02456 02457 // //planeItr.ResetFirst(); 02458 02459 // Int_t planeCtr = 0; 02460 // DmxPlane *plane = 0; 02461 02462 // //MSG("DMX", Msg::kDebug) << "\t" << hypotheses[0] << "\t" << hypotheses[1] 02463 // // << "\t" << hypotheses[2] << "\t" << hypotheses[3] 02464 // // << "\t" << hypotheses[4] << "\t" << hypotheses[5] << endl; 02465 // //loop over the plane iterator to fill the variables 02466 02467 // while( (plane = planeItr()) && planeCtr < leverArm){ 02468 02469 // if( !planeItr.GetSet()->GetMasks().GetMask(plane) ){ 02470 // //&& plane->GetPlaneNumber()>=firstPlane && plane->GetPlaneNumber()<=lastPlane){ 02471 // Double_t x = plane->GetZPosition(); 02472 02473 // //get the maximum possible weight first, then for each hypothesis multiply 02474 // //by the square of the fraction 02475 // Double_t weightSq = 10000. / (plane->GetPlaneCharge() * plane->GetPlaneCharge()); 02476 // if(plane->IsGolden()) weightSq = 0.000001; 02477 02478 // Double_t y = plane->GetCoG(); 02479 02480 // //only do this if the shower plane is not golden - if it is, you know where it should be 02481 // //reconstructed to 02482 // if( plane->GetPlaneType() == DmxPlaneTypes::kShower && !plane->IsGolden()){ 02483 02484 // if(hypotheses[planeCtr] == 1){ 02485 // //MSG("DMX", Msg::kDebug) << "\t" << dynamic_cast<DmxShowerPlane *>(plane)->GetBestHypothesis()->GetCoG(); 02486 // weightSq *= 1. / (dynamic_cast<DmxShowerPlane *>(plane)->GetBestHypothesis()->GetMatedSignalRatio() 02487 // * dynamic_cast<DmxShowerPlane *>(plane)->GetBestHypothesis()->GetMatedSignalRatio()); 02488 // } 02489 // //plane->GetCoG() returns the best hypothesis CoG so only change the value of y if you are wanting 02490 // //the 2nd or 3rd best hypotheses 02491 // else if(hypotheses[planeCtr] == 2){ 02492 // //MSG("DMX", Msg::kDebug) << "\t" << dynamic_cast<DmxShowerPlane *>(plane)->GetSecondBestHypothesis()->GetCoG(); 02493 // y = dynamic_cast<DmxShowerPlane *>(plane)->GetSecondBestCoG(); 02494 // weightSq *= 1. / (dynamic_cast<DmxShowerPlane *>(plane)->GetSecondBestHypothesis()->GetMatedSignalRatio() 02495 // * dynamic_cast<DmxShowerPlane *>(plane)->GetSecondBestHypothesis()->GetMatedSignalRatio()); 02496 // } 02497 // else if(hypotheses[planeCtr] == 3){ 02498 // //MSG("DMX", Msg::kDebug) << "\t" << dynamic_cast<DmxShowerPlane *>(plane)->GetThirdBestHypothesis()->GetCoG(); 02499 // y = dynamic_cast<DmxShowerPlane *>(plane)->GetThirdBestCoG(); 02500 // weightSq *= 1. / (dynamic_cast<DmxShowerPlane *>(plane)->GetThirdBestHypothesis()->GetMatedSignalRatio() 02501 // * dynamic_cast<DmxShowerPlane *>(plane)->GetThirdBestHypothesis()->GetMatedSignalRatio()); 02502 // } 02503 // } 02504 02505 // pSqDivSSqSum += (x * x) / weightSq; 02506 // cogDivSSqSum += y / weightSq; 02507 // pDivSSqSum += x / weightSq; 02508 // pCoGDivSSqSum += (x * y) / weightSq; 02509 // invSSqSum += 1. / weightSq; 02510 // //MSG("DMX", Msg::kDebug) << "\t" << x << "\t" << y << "\t" << hypotheses[planeCtr] << "\t" << weightSq 02511 // // << "\t" << pSqDivSSqSum << "\t" << cogDivSSqSum << "\t" 02512 // // << pDivSSqSum << "\t" << pCoGDivSSqSum << "\t" << invSSqSum << endl; 02513 02514 // }//end if the plane isnt marked as sucking && it is in the window bounds 02515 02516 // ++planeCtr; 02517 // } //end loop over planes to find variables for fit 02518 02519 // Int_t degreesOfFreedom = planeCtr-1; 02520 // planeItr.Reset(); 02521 // planeCtr = 0; 02522 02523 // //find the values of a and b 02524 // Double_t delta = (invSSqSum * pSqDivSSqSum) - (pDivSSqSum * pDivSSqSum); 02525 // a = (1. / delta) * ((pSqDivSSqSum * cogDivSSqSum) - (pDivSSqSum * pCoGDivSSqSum)); 02526 // b = (1. / delta) * ((invSSqSum * pCoGDivSSqSum) - (pDivSSqSum * cogDivSSqSum)); 02527 // //MSG("DMX", Msg::kDebug) << "\t" << delta << "\t" << a << "\t" << b << endl; 02528 02529 // //find the chi^2 value using the typical equation for chi^2 - 02530 // //chi^2 = SUM[(y_i - y(x_i)) / sigma_i]^2 02531 02532 // Double_t chiSq = 0.; 02533 02534 // while( (plane = planeItr()) && planeCtr < leverArm){ 02535 02536 // if( !planeItr.GetSet()->GetMasks().GetMask(plane) ){ 02537 // //&& plane->GetPlaneNumber()>=firstPlane && plane->GetPlaneNumber()<=lastPlane){ 02538 // Double_t xi = plane->GetZPosition(); 02539 // Double_t weight = 100. / plane->GetPlaneCharge(); 02540 // Double_t yi = plane->GetCoG(); 02541 // if(plane->IsGolden()) weight = 0.001; 02542 02543 // //only change the value if the plane isnot golden 02544 // if( plane->GetPlaneType() == DmxPlaneTypes::kShower && !plane->IsGolden()){ 02545 02546 // if(hypotheses[planeCtr] == 1){ 02547 // weight *= 1. / dynamic_cast<DmxShowerPlane *>(plane)->GetBestHypothesis()->GetMatedSignalRatio(); 02548 // } 02549 // //plane->GetCoG() returns the best hypothesis CoG so only change the value of y if you are wanting 02550 // //the 2nd or 3rd best hypotheses 02551 // else if(hypotheses[planeCtr] == 2){ 02552 // yi = dynamic_cast<DmxShowerPlane *>(plane)->GetSecondBestCoG(); 02553 // weight *= 1. / dynamic_cast<DmxShowerPlane *>(plane)->GetSecondBestHypothesis()->GetMatedSignalRatio(); 02554 // } 02555 // else if(hypotheses[planeCtr] == 3){ 02556 // yi = dynamic_cast<DmxShowerPlane *>(plane)->GetThirdBestCoG(); 02557 // weight *= 1. / dynamic_cast<DmxShowerPlane *>(plane)->GetThirdBestHypothesis()->GetMatedSignalRatio(); 02558 // } 02559 // } 02560 02561 // Double_t yxi = a + (b * xi); 02562 // Double_t quotient = (yi - yxi) / weight; 02563 02564 // chiSq += quotient * quotient; 02565 02566 // }//end if plane is in window bounds 02567 02568 // ++planeCtr; 02569 // } //end loop to find chiSq 02570 02571 02572 // prevChiSq = chiSq/(1.*degreesOfFreedom); 02573 // //MSG("DMX", Msg::kDebug) << "\tinitial fit " << prevChiSq << "\t" << a << "\t" << b << endl; 02574 02575 // planeItr.Reset(); 02576 // planeCtr = 0; 02577 02578 // //redo the fit as many times as there are planes, dropping each plane in 02579 // //turn to see if it produces a better chi^2 value - only do it if you have 02580 // //more than 3 planes - ie you can drop one and still do a reasonable fit 02581 // //2 planes = great straight line every time. 02582 // if(leverArm > 3){ 02583 // Double_t fitA = 0.; 02584 // Double_t fitB = 0.; 02585 02586 // for(Int_t i = 0; i < leverArm; i++){ 02587 // planeCtr = 0; 02588 // pSqDivSSqSum = 0; 02589 // cogDivSSqSum = 0; 02590 // pDivSSqSum = 0; 02591 // pCoGDivSSqSum = 0; 02592 // invSSqSum = 0; 02593 02594 // //loop over the plane iterator to fill the variables 02595 // while( (plane = planeItr()) && planeCtr < leverArm){ 02596 02597 // //use those planes not marked as kTRUE - a mark of kTRUE means to drop the plane 02598 // //from the set when finding the fit. ie if its true, the plane truely sucks 02599 // if( !planeItr.GetSet()->GetMasks().GetMask(plane) ){ 02600 // //&& plane->GetPlaneNumber()>=firstPlane && plane->GetPlaneNumber()<=lastPlane){ 02601 // if(i != planeCtr){ 02602 // Double_t x = plane->GetZPosition(); 02603 // Double_t weightSq = 10000. / (plane->GetPlaneCharge() * plane->GetPlaneCharge()); 02604 // Double_t y = plane->GetCoG(); 02605 // if(plane->IsGolden()) weightSq = 0.000001; 02606 02607 // //only make changes if not a golden plane 02608 // if( plane->GetPlaneType() == DmxPlaneTypes::kShower && !plane->IsGolden()){ 02609 // //only change y if the hypothesis isnt the best one - the unset plane returns the best 02610 // //cog from the GetCoG() method 02611 02612 // if(hypotheses[planeCtr] == 1){ 02613 // weightSq *= 1. / (dynamic_cast<DmxShowerPlane *>(plane)->GetBestHypothesis()->GetMatedSignalRatio() * 02614 // dynamic_cast<DmxShowerPlane *>(plane)->GetBestHypothesis()->GetMatedSignalRatio()); 02615 // } 02616 // else if(hypotheses[planeCtr] == 2){ 02617 // y = dynamic_cast<DmxShowerPlane *>(plane)->GetSecondBestCoG(); 02618 // weightSq *= 1. / (dynamic_cast<DmxShowerPlane *>(plane)->GetSecondBestHypothesis()->GetMatedSignalRatio() 02619 // * dynamic_cast<DmxShowerPlane *>(plane)->GetSecondBestHypothesis()->GetMatedSignalRatio()); 02620 // } 02621 // else if(hypotheses[planeCtr] == 3){ 02622 // y = dynamic_cast<DmxShowerPlane *>(plane)->GetThirdBestCoG(); 02623 // weightSq *= 1. / (dynamic_cast<DmxShowerPlane *>(plane)->GetThirdBestHypothesis()->GetMatedSignalRatio() 02624 // * dynamic_cast<DmxShowerPlane *>(plane)->GetThirdBestHypothesis()->GetMatedSignalRatio()); 02625 // } 02626 // } 02627 02628 // pSqDivSSqSum += (x * x) / weightSq; 02629 // cogDivSSqSum += y / weightSq; 02630 // pDivSSqSum += x / weightSq; 02631 // pCoGDivSSqSum += (x * y) / weightSq; 02632 // invSSqSum += 1. / weightSq; 02633 // //MSG("DMX", Msg::kDebug) << "\t" << x << "\t" << y << "\t" << hypotheses[planeCtr] << endl; //"\t" << weightSq << "\t" 02634 // // << pSqDivSSqSum << "\t" << cogDivSSqSum << "\t" 02635 // // << pDivSSqSum << "\t" << pCoGDivSSqSum << "\t" << invSSqSum << endl; 02636 02637 // //else{ MSG("DMX", Msg::kDebug) << "\tdrop plane " << plane->GetPlaneNumber() << endl; } 02638 // } //end if plane is not the dropped one 02639 // }//end if plane is in window bounds 02640 // ++planeCtr; 02641 // } //end loop over planes to find variables for fit 02642 02643 // degreesOfFreedom = planeCtr-2; 02644 // //find the values of a and b 02645 // delta = (invSSqSum * pSqDivSSqSum) - (pDivSSqSum * pDivSSqSum); 02646 // fitA = (1. / delta) * ((pSqDivSSqSum * cogDivSSqSum) - (pDivSSqSum * pCoGDivSSqSum)); 02647 // fitB = (1. / delta) * ((invSSqSum * pCoGDivSSqSum) - (pDivSSqSum * cogDivSSqSum)); 02648 // //MSG("DMX", Msg::kDebug) << "\tfit " << "\t" << fitA << "\t" << fitB << endl; 02649 02650 // //find the chi^2 value using the typical equation for chi^2 - 02651 // //chi^2 = SUM[(y_i - y(x_i)) / sigma_i]^2 02652 02653 // planeItr.Reset(); 02654 02655 // chiSq = 0.; 02656 // planeCtr = 0; 02657 02658 // while( (plane = planeItr()) && planeCtr < leverArm){ 02659 // //MSG("DmxAlg" , Msg::kDebug) << "plane " << plane->GetPlaneNumber() << " mask " 02660 // // << (Int_t)planeItr.GetSet()->GetMasks().GetMask(plane) 02661 // // << endl; 02662 // if(!planeItr.GetSet()->GetMasks().GetMask(plane)){ 02663 // //&& plane->GetPlaneNumber()>=firstPlane && plane->GetPlaneNumber()<=lastPlane){ 02664 // if( i != planeCtr ){ 02665 // Double_t xi = plane->GetZPosition(); 02666 // Double_t weight = 100. / plane->GetPlaneCharge(); 02667 // Double_t yi = plane->GetCoG(); 02668 // if(plane->IsGolden()) weight = 0.001; 02669 02670 // //only make changes if not a golden plane 02671 // if( plane->GetPlaneType() == DmxPlaneTypes::kShower && !plane->IsGolden()){ 02672 // if(hypotheses[planeCtr] == 1){ 02673 // weight *= 1. / dynamic_cast<DmxShowerPlane *>(plane)->GetBestHypothesis()->GetMatedSignalRatio(); 02674 // } 02675 // //plane->GetCoG() returns the best hypothesis CoG so only change the value of y if you are wanting 02676 // //the 2nd or 3rd best hypotheses 02677 // else if(hypotheses[planeCtr] == 2){ 02678 // yi = dynamic_cast<DmxShowerPlane *>(plane)->GetSecondBestCoG(); 02679 // weight *= 1. / dynamic_cast<DmxShowerPlane *>(plane)->GetSecondBestHypothesis()->GetMatedSignalRatio(); 02680 // } 02681 // else if(hypotheses[planeCtr] == 3){ 02682 // yi = dynamic_cast<DmxShowerPlane *>(plane)->GetThirdBestCoG(); 02683 // weight *= 1. / dynamic_cast<DmxShowerPlane *>(plane)->GetThirdBestHypothesis()->GetMatedSignalRatio(); 02684 // } 02685 // } 02686 02687 // Double_t yxi = fitA + (fitB * xi); 02688 // Double_t quotient = (yi - yxi) / weight; 02689 // //add the contribution to the chiSq if its not the plane you are dropping 02690 // chiSq += quotient * quotient; 02691 // } //end if plane is not the one to be dropped 02692 // }//end if plane is in bounds of the window 02693 // ++planeCtr; 02694 // } //end loop to find chiSq 02695 02696 // planeItr.Reset(); 02697 02698 // planeCtr = 0; 02699 // chiSq /= 1.*degreesOfFreedom; 02700 // if(chiSq < prevChiSq){ 02701 // prevChiSq = chiSq; 02702 // a = fitA; 02703 // b = fitB; 02704 // //MSG("DMX", Msg::kDebug) << "\trefined fit, drop plane " << i 02705 // // << "\t" << prevChiSq << "\t" << a << "\t" << b << endl; 02706 // } 02707 02708 // }//end for loop to improve fit by dropping a plane 02709 // }//end if enough planes to improve fit 02710 02711 // planeItr.ResetFirst(); 02712 // //MSG("DMX", Msg::kDebug) << "\tfinal fit" << "\t" << a << "\t" << b << "\t" << prevChiSq << endl; 02713 02714 // return; 02715 // } 02716 02717 //--------------------------------------------------------------------------------------- 02718 //find the best line for a set of planes 02719 // void AlgDeMuxCosmics::FindStraightLineFit(DmxPlaneItr &planeItr, Double_t &prevChiSq, 02720 // Double_t &a, Double_t &b, Int_t unSetPlaneHyp, 02721 // Int_t direction, Int_t leverArm, 02722 // Int_t /* firstPlane */, Int_t /* lastPlane */) 02723 // { 02724 02725 // MSG("DMXX", Msg::kDebug) << "in FindStraightLineFit" << endl; 02726 02727 // //declare the variables to do a least squares fit to a straight line. all 02728 // //equations taken from Bevington, second edition. fit to the line 02729 // //CoG = a + b*plane 02730 // //where CoG is the center of gravity for plane number plane. 02731 // //the variables used are 02732 // // pSqDivSSqSum = sum of (plane number)^2 / (weight)^2 02733 // // cogDivSSqSum = sum of (center of gravity)^2 / (weight)^2 02734 // // pDivSSqSum = sum of plane number / (weight)^2 02735 // // pCoGDivSSqSum = sum of (plane number * center of gravity) / (weight)^2 02736 // // invSSqSum = sum of weight^-2 02737 // // pDivSSqSum = sum of plane number / weight^2 02738 // //weight is the total charge on the plane 02739 02740 // Double_t pSqDivSSqSum = 0.; 02741 // Double_t cogDivSSqSum = 0.; 02742 // Double_t pDivSSqSum = 0.; 02743 // Double_t pCoGDivSSqSum = 0.; 02744 // Double_t invSSqSum = 0.; 02745 02746 // if(direction == -1){ planeItr.ResetLast(); } 02747 // else if( direction == 1){ planeItr.ResetFirst(); } 02748 02749 // Int_t planeCtr = 0; 02750 // DmxPlane *plane = 0; 02751 02752 // while( (plane = planeItr()) && planeCtr < leverArm){ 02753 02754 // //if(plane->GetPlaneNumber()>=firstPlane && plane->GetPlaneNumber()<=lastPlane){ 02755 // Double_t x = plane->GetZPosition(); 02756 // Double_t weightSq = 10000. / (plane->GetPlaneCharge() * plane->GetPlaneCharge()); 02757 // Double_t y = plane->GetCoG(); 02758 // if(plane->IsGolden()) weightSq = 0.000001; 02759 02760 // //only make changes if not a golden plane 02761 // if(plane->GetPlaneType() == DmxPlaneTypes::kShower && !plane->IsGolden()){ 02762 // if( planeCtr < leverArm-1 ){ 02763 // weightSq *= 1. / (dynamic_cast<DmxShowerPlane *>(plane)->GetSetHypothesis()->GetMatedSignalRatio() 02764 // * dynamic_cast<DmxShowerPlane *>(plane)->GetSetHypothesis()->GetMatedSignalRatio()); 02765 // } 02766 // else if( planeCtr == leverArm-1 && unSetPlaneHyp == 1 ){ 02767 // weightSq *= 1. / (dynamic_cast<DmxShowerPlane *>(plane)->GetBestHypothesis()->GetMatedSignalRatio() 02768 // * dynamic_cast<DmxShowerPlane *>(plane)->GetBestHypothesis()->GetMatedSignalRatio()); 02769 // } 02770 // else if( planeCtr == leverArm-1 && unSetPlaneHyp == 2 ){ 02771 // y = dynamic_cast<DmxShowerPlane *>(plane)->GetSecondBestCoG(); 02772 // weightSq *= 1. / (dynamic_cast<DmxShowerPlane *>(plane)->GetSecondBestHypothesis()->GetMatedSignalRatio() 02773 // * dynamic_cast<DmxShowerPlane *>(plane)->GetSecondBestHypothesis()->GetMatedSignalRatio()); 02774 // } 02775 // else if( planeCtr == leverArm-1 && unSetPlaneHyp == 3 ){ 02776 // y = dynamic_cast<DmxShowerPlane *>(plane)->GetThirdBestCoG(); 02777 // weightSq *= 1. / (dynamic_cast<DmxShowerPlane *>(plane)->GetThirdBestHypothesis()->GetMatedSignalRatio() 02778 // * dynamic_cast<DmxShowerPlane *>(plane)->GetThirdBestHypothesis()->GetMatedSignalRatio()); 02779 // } 02780 // } 02781 02782 // pSqDivSSqSum += (x * x) / weightSq; 02783 // cogDivSSqSum += y / weightSq; 02784 // pDivSSqSum += x / weightSq; 02785 // pCoGDivSSqSum += (x * y) / weightSq; 02786 // invSSqSum += 1. / weightSq; 02787 // //MSG("DMX", Msg::kDebug) << "\t" << x << "\t" << y << endl; //<< "\t" << weightSq << "\t" 02788 // //<< pSqDivSSqSum << "\t" << cogDivSSqSum << "\t" 02789 // //<< pDivSSqSum << "\t" << pCoGDivSSqSum << "\t" << invSSqSum << endl; 02790 02791 // ++planeCtr; 02792 02793 // //}//end if plane is in bounds for the window. 02794 // } //end loop over planes to find variables for fit 02795 02796 // Int_t degreesOfFreedom = planeCtr-1; 02797 // planeItr.Reset(); 02798 // planeCtr = 0; 02799 02800 // //find the values of a and b 02801 // Double_t delta = (invSSqSum * pSqDivSSqSum) - (pDivSSqSum * pDivSSqSum); 02802 // a = (1. / delta) * ((pSqDivSSqSum * cogDivSSqSum) - (pDivSSqSum * pCoGDivSSqSum)); 02803 // b = (1. / delta) * ((invSSqSum * pCoGDivSSqSum) - (pDivSSqSum * cogDivSSqSum)); 02804 // //MSG("DMX", Msg::kDebug) << "\t" << delta << "\t" << a << "\t" << b << endl; 02805 02806 // //find the chi^2 value using the typical equation for chi^2 - 02807 // //chi^2 = SUM[(y_i - y(x_i)) / sigma_i]^2 02808 02809 // Double_t chiSq = 0.; 02810 02811 // while( (plane = planeItr()) && planeCtr < leverArm){ 02812 02813 // //if(plane->GetPlaneNumber()>=firstPlane && plane->GetPlaneNumber()<=lastPlane){ 02814 // Double_t xi = plane->GetZPosition(); 02815 // Double_t weight = 100. / plane->GetPlaneCharge(); 02816 // Double_t yi = plane->GetCoG(); 02817 // if(plane->IsGolden()) weight = 0.001; 02818 02819 // if(plane->GetPlaneType() == DmxPlaneTypes::kShower && !plane->IsGolden()){ 02820 // if( planeCtr < leverArm-1 ){ 02821 // weight *= 1. / dynamic_cast<DmxShowerPlane *>(plane)->GetSetHypothesis()->GetMatedSignalRatio(); 02822 // } 02823 // else if( planeCtr == leverArm-1 && unSetPlaneHyp == 1 ){ 02824 // weight *= 1. / dynamic_cast<DmxShowerPlane *>(plane)->GetBestHypothesis()->GetMatedSignalRatio(); 02825 // } 02826 // else if( planeCtr == leverArm-1 && unSetPlaneHyp == 2 ){ 02827 // yi = dynamic_cast<DmxShowerPlane *>(plane)->GetSecondBestCoG(); 02828 // weight *= 1. / dynamic_cast<DmxShowerPlane *>(plane)->GetSecondBestHypothesis()->GetMatedSignalRatio(); 02829 // } 02830 // else if( planeCtr == leverArm-1 && unSetPlaneHyp == 3 ){ 02831 // yi = dynamic_cast<DmxShowerPlane *>(plane)->GetThirdBestCoG(); 02832 // weight *= 1. / dynamic_cast<DmxShowerPlane *>(plane)->GetThirdBestHypothesis()->GetMatedSignalRatio(); 02833 // } 02834 // } 02835 02836 // Double_t yxi = a + (b * xi); 02837 // Double_t quotient = (yi - yxi) / weight; 02838 02839 // chiSq += quotient * quotient; 02840 02841 // ++planeCtr; 02842 // //}//end if plane is in window bounds 02843 // } //end loop to find chiSq 02844 02845 02846 // prevChiSq = chiSq/(1.*degreesOfFreedom); 02847 02848 // //MSG("DMXX", Msg::kDebug) << "\tinitial fit " << prevChiSq << "\t" << a << "\t" << b << endl; 02849 02850 // planeItr.Reset(); 02851 // planeCtr = 0; 02852 02853 // //redo the fit using only the previously set planes and only if you have more than 3 planes in the set 02854 // if(leverArm > 3){ 02855 // Double_t fitA = 0.; 02856 // Double_t fitB = 0.; 02857 02858 // planeCtr = 0; 02859 // pSqDivSSqSum = 0; 02860 // cogDivSSqSum = 0; 02861 // pDivSSqSum = 0; 02862 // pCoGDivSSqSum = 0; 02863 // invSSqSum = 0; 02864 02865 // //loop over the plane iterator to fill the variables 02866 // while( (plane = planeItr()) && planeCtr < (leverArm - 1)){ 02867 02868 // //if(plane->GetPlaneNumber()>=firstPlane && plane->GetPlaneNumber()<=lastPlane){ 02869 // //use all but the last plane in the set to see what your fit is without it 02870 // Double_t x = plane->GetZPosition(); 02871 // Double_t weightSq = 10000. / (plane->GetPlaneCharge() * plane->GetPlaneCharge()); 02872 // Double_t y = plane->GetCoG(); 02873 // if(plane->IsGolden()) weightSq = 0.000001; 02874 02875 // if(plane->GetPlaneType() == DmxPlaneTypes::kShower && !plane->IsGolden()){ 02876 // weightSq *= 1. / (dynamic_cast<DmxShowerPlane *>(plane)->GetSetHypothesis()->GetMatedSignalRatio() 02877 // * dynamic_cast<DmxShowerPlane *>(plane)->GetSetHypothesis()->GetMatedSignalRatio()); 02878 // } 02879 02880 // pSqDivSSqSum += (x * x) / weightSq; 02881 // cogDivSSqSum += y / weightSq; 02882 // pDivSSqSum += x / weightSq; 02883 // pCoGDivSSqSum += (x * y) / weightSq; 02884 // invSSqSum += 1. / weightSq; 02885 // //MSG("DMX", Msg::kDebug) << "\t" << x << "\t" << y << endl; //"\t" << weightSq << "\t" 02886 // // << pSqDivSSqSum << "\t" << cogDivSSqSum << "\t" 02887 // // << pDivSSqSum << "\t" << pCoGDivSSqSum << "\t" << invSSqSum << endl; 02888 02889 // //else{ MSG("DMX", Msg::kDebug) << "\tdrop plane " << plane->GetPlaneNumber() << endl; } 02890 02891 // ++planeCtr; 02892 // //}//end if plane is in the window bounds 02893 // } //end loop over planes to find variables for fit 02894 02895 // degreesOfFreedom = planeCtr-2; 02896 // //find the values of a and b 02897 // delta = (invSSqSum * pSqDivSSqSum) - (pDivSSqSum * pDivSSqSum); 02898 // fitA = (1. / delta) * ((pSqDivSSqSum * cogDivSSqSum) - (pDivSSqSum * pCoGDivSSqSum)); 02899 // fitB = (1. / delta) * ((invSSqSum * pCoGDivSSqSum) - (pDivSSqSum * cogDivSSqSum)); 02900 02901 // //find the chi^2 value using the typical equation for chi^2 - 02902 // //chi^2 = SUM[(y_i - y(x_i)) / sigma_i]^2 02903 02904 // planeItr.Reset(); 02905 02906 // chiSq = 0.; 02907 // planeCtr = 0; 02908 02909 // bool droppedGolden = false; 02910 02911 // while( (plane = planeItr()) ){ 02912 02913 // //if(plane->GetPlaneNumber()>=firstPlane && plane->GetPlaneNumber()<=lastPlane){ 02914 // if( planeCtr < (leverArm - 1)){ 02915 // Double_t xi = plane->GetZPosition(); 02916 // Double_t weight = 100. / plane->GetPlaneCharge(); 02917 // Double_t yi = plane->GetCoG(); 02918 // if(plane->IsGolden()) weight = 0.001; 02919 02920 // if(plane->GetPlaneType() == DmxPlaneTypes::kShower && !plane->IsGolden()){ 02921 // weight *= 1. / dynamic_cast<DmxShowerPlane *>(plane)->GetSetHypothesis()->GetMatedSignalRatio(); 02922 // } 02923 02924 // Double_t yxi = fitA + (fitB * xi); 02925 // Double_t quotient = (yi - yxi) / weight; 02926 // //add the contribution to the chiSq if its not the plane you are dropping 02927 // chiSq += quotient * quotient; 02928 // } 02929 // //see if the dropped plane was a golden plane 02930 // else if( planeCtr == (leverArm - 1) && plane->IsGolden() && unSetPlaneHyp == 3){ 02931 // droppedGolden = true; 02932 02933 // //MSG("DmxAlg", Msg::kDebug) << "dropped plane " << plane->GetPlaneNumber() << " is golden " 02934 // // << (Int_t)plane->IsGolden() << "\tplane CoG = " 02935 // // << plane->GetCoG() << "fit CoG = " 02936 // // << fitA+(fitB*plane->GetZPosition()) 02937 // // << " a = " << fitA << " b = " << fitB 02938 // // << " chi^2 = " << chiSq << endl; 02939 02940 // //if this is the 3rd time through the loop and the difference in the golden CoG and the 02941 // //fitCoG without the golden plane is greater than 0.25m, and the fit is inside the detector 02942 // //then set the plane as non-Golden it just fooled the golden cut beforee 02943 // //or, go with the better fit if it is way better - ie the chi^2 is a factor of 10 02944 // //or more less than the fit with all planes, golden or not. again, only do that 02945 // //the last time through 02946 // if(TMath::Abs(fitA+(fitB*plane->GetZPosition()))<4.0 02947 // && (TMath::Abs(plane->GetCoG()-(fitA+(fitB*plane->GetZPosition())))>0.25 || prevChiSq>10.*chiSq/degreesOfFreedom)){ 02948 // plane->SetGolden(false); 02949 // //MSG("DmxAlg", Msg::kDebug) << " is golden " << (Int_t)plane->IsGolden() << endl; 02950 // droppedGolden = false; 02951 // } 02952 // }//end check of last plane is golden 02953 // ++planeCtr; 02954 // //}//end if plane is in window bounds 02955 // } //end loop to find chiSq 02956 02957 // planeCtr = 0; 02958 // chiSq /= 1.*degreesOfFreedom; 02959 // //MSG("DMXX", Msg::kDebug) << "\trefined fit " 02960 // // << "\t" << chiSq << "\t" << fitA << "\t" << fitB << endl; 02961 02962 // planeItr.Reset(); 02963 02964 // //if the fit found by dropping the last plane has a better chi^2 than the 02965 // //fit using all planes, and that last plane was not golden, then pass the 02966 // //fit from the first planes in the window out. if the last plane was initially 02967 // //golden, this only happens for the last time through. 02968 // // 02969 // if(chiSq < prevChiSq && !droppedGolden){ 02970 02971 // prevChiSq = chiSq; 02972 // a = fitA; 02973 // b = fitB; 02974 // } 02975 02976 // planeItr.Reset(); 02977 02978 // }//end for loop to improve fit by dropping a plane 02979 02980 // planeItr.ResetFirst(); 02981 // return; 02982 // } 02983 02984
1.3.9.1