]> git.uio.no Git - u/mrichter/AliRoot.git/blame - MUON/AliMUONDigitizer.cxx
Adding AliMUONGeometryMisAligner
[u/mrichter/AliRoot.git] / MUON / AliMUONDigitizer.cxx
CommitLineData
28752ff4 1/**************************************************************************
2 * Copyright(c) 1998-2000, ALICE Experiment at CERN, All rights reserved. *
3 * *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
6 * *
7 * Permission to use, copy, modify and distribute this software and its *
8 * documentation strictly for non-commercial purposes is hereby granted *
9 * without fee, provided that the above copyright notice appears in all *
10 * copies and that both the copyright notice and this permission notice *
11 * appear in the supporting documentation. The authors make no claims *
12 * about the suitability of this software for any purpose. It is *
13 * provided "as is" without express or implied warranty. *
14 **************************************************************************/
15
88cb7938 16/* $Id$ */
ba030c0e 17
2be06f1e 18#include <assert.h>
19
cf286af7 20#include "AliRun.h"
21#include "AliRunDigitizer.h"
88cb7938 22#include "AliRunLoader.h"
88cb7938 23
24#include "AliMUONDigitizer.h"
25#include "AliMUONConstants.h"
b7ef3c96 26#include "AliMUONSegmentation.h"
88cb7938 27#include "AliMUONHitMapA1.h"
28752ff4 28#include "AliMUON.h"
30178c30 29#include "AliMUONLoader.h"
116cbefd 30#include "AliMUONConstants.h"
28752ff4 31#include "AliMUONTransientDigit.h"
ce3e25a8 32#include "AliMUONTriggerDecision.h"
8c343c7c 33#include "AliLog.h"
b7ef3c96 34#include "AliMUONGeometryTransformer.h"
edb96c6a 35#include "AliMUONGeometryModule.h"
36#include "AliMUONGeometryStore.h"
cf286af7 37
38/////////////////////////////////////////////////////////////////////////////////////
39//
40// AliMUONDigitizer should be base abstract class of all digitisers in the MUON
41// module. It implements the common functionality of looping over input streams
42// filling the fTDList and writing the fTDList to the output stream.
43// Inheriting digitizers need to override certain methods to choose and initialize
44// the correct input and output trees, apply the correct detector response if any
45// and implement how the transient digits are generated from the input stream.
46//
47/////////////////////////////////////////////////////////////////////////////////////
28752ff4 48
49ClassImp(AliMUONDigitizer)
50
51//___________________________________________
cf286af7 52AliMUONDigitizer::AliMUONDigitizer() :
53 AliDigitizer(),
54 fHitMap(0),
55 fTDList(0),
56 fTDCounter(0),
57 fMask(0),
5ac16716 58 fSignal(0)
28752ff4 59{
cf286af7 60// Default constructor.
61// Initializes all pointers to NULL.
62
30178c30 63 fRunLoader = NULL;
64 fGime = NULL;
65 fMUON = NULL;
66 fMUONData = NULL;
ce3e25a8 67 fTrigDec = NULL;
925e6570 68}
28752ff4 69
70//___________________________________________
cf286af7 71AliMUONDigitizer::AliMUONDigitizer(AliRunDigitizer* manager) :
72 AliDigitizer(manager),
73 fHitMap(0),
74 fTDList(0),
75 fTDCounter(0),
76 fMask(0),
5ac16716 77 fSignal(0)
28752ff4 78{
cf286af7 79// Constructor which should be used rather than the default constructor.
80// Initializes all pointers to NULL.
81
30178c30 82 fRunLoader = NULL;
83 fGime = NULL;
84 fMUON = NULL;
85 fMUONData = NULL;
ce3e25a8 86 fTrigDec = NULL;
925e6570 87}
28752ff4 88
11ca64ac 89//___________________________________________
90AliMUONDigitizer::AliMUONDigitizer(const AliMUONDigitizer& rhs)
91 : AliDigitizer(rhs)
92{
93// Protected copy constructor
94
8c343c7c 95 AliFatal("Not implemented.");
11ca64ac 96}
97
8789635b 98//___________________________________________
99AliMUONDigitizer::~AliMUONDigitizer()
100{
101// Destructor
ce3e25a8 102 if (fMUONData)
103 delete fMUONData;
104
105 if (fTrigDec)
106 delete fTrigDec;
8789635b 107}
108
11ca64ac 109//-------------------------------------------------------------------
110AliMUONDigitizer&
111AliMUONDigitizer::operator=(const AliMUONDigitizer& rhs)
112{
113// Protected assignement operator
114
115 if (this == &rhs) return *this;
116
8c343c7c 117 AliFatal("Not implemented.");
11ca64ac 118
119 return *this;
120}
a713db22 121
28752ff4 122//------------------------------------------------------------------------
cf286af7 123Bool_t AliMUONDigitizer::Init()
28752ff4 124{
cf286af7 125// Does nothing.
126 return kTRUE;
28752ff4 127}
128
129//------------------------------------------------------------------------
5ac16716 130void AliMUONDigitizer::Exec(Option_t* /*option*/)
28752ff4 131{
cf286af7 132// The main work loop starts here.
133// The digitization process is broken up into two steps:
134// 1) Loop over input streams and create transient digits from the input.
135// Done in GenerateTransientDigits()
136// 2) Loop over the generated transient digits and write them to the output
137// stream. Done in CreateDigits()
138
8c343c7c 139 AliDebug(1, "Running digitiser.");
cf286af7 140
141 if (fManager->GetNinputs() == 0)
142 {
8c343c7c 143 AliWarning("No inputs set, nothing to do.");
cf286af7 144 return;
925e6570 145 }
cf286af7 146
ce3e25a8 147 if (!FetchLoaders(fManager->GetInputFolderName(0), fRunLoader, fGime) ) return;
30178c30 148 if (! FetchGlobalPointers(fRunLoader) ) return;
ce3e25a8 149 if (! FetchTriggerPointer(fGime) ) return;
cf286af7 150
151 InitArrays();
152
8c343c7c 153 AliDebug(2, Form("Event Number is %d.", fManager->GetOutputEventNr()));
cf286af7 154
155 // Loop over files to merge and to digitize
156 fSignal = kTRUE;
157 for (Int_t inputFile = 0; inputFile < fManager->GetNinputs(); inputFile++)
158 {
159 fMask = fManager->GetMask(inputFile);
8c343c7c 160 AliDebug(2, Form("Digitising folder %d, with fMask = %d: %s", inputFile, fMask,
161 (const char*)fManager->GetInputFolderName(inputFile)));
cf286af7 162
163 if (inputFile != 0)
164 // If this is the first file then we already have the loaders loaded.
30178c30 165 if (! FetchLoaders(fManager->GetInputFolderName(inputFile), fRunLoader, fGime) )
cf286af7 166 continue;
167 else
168 // If this is not the first file then it is assumed to be background.
169 fSignal = kFALSE;
170
30178c30 171 if (! InitInputData(fGime) ) continue;
cf286af7 172 GenerateTransientDigits();
30178c30 173 CleanupInputData(fGime);
925e6570 174 }
cf286af7 175
30178c30 176 Bool_t ok = FetchLoaders(fManager->GetOutputFolderName(), fRunLoader, fGime);
177 if (ok) ok = InitOutputData(fGime);
cf286af7 178 if (ok) CreateDigits();
ce3e25a8 179 if (ok) CreateTrigger();
30178c30 180 if (ok) CleanupOutputData(fGime);
cf286af7 181
182 CleanupArrays();
ce3e25a8 183 CleanupTriggerArrays();
925e6570 184}
cf286af7 185
186//--------------------------------------------------------------------------
187void AliMUONDigitizer::AddOrUpdateTransientDigit(AliMUONTransientDigit* mTD)
188{
189// Checks to see if the transient digit exists in the corresponding fHitMap.
190// If it does then the digit is updated otherwise it is added.
191
192 if (ExistTransientDigit(mTD))
193 {
194 UpdateTransientDigit(mTD);
195 delete mTD; // The new digit can be deleted because it was not added.
196 }
197 else
198 AddTransientDigit(mTD);
925e6570 199}
28752ff4 200
201//------------------------------------------------------------------------
cf286af7 202void AliMUONDigitizer::UpdateTransientDigit(AliMUONTransientDigit* mTD)
28752ff4 203{
cf286af7 204// Update the transient digit that is already in the fTDList by adding the new
205// transient digits charges and track lists to the existing one.
206
8c343c7c 207 AliDebug(4,Form( "Updating transient digit 0x%X", (void*)mTD));
cf286af7 208 // Choosing the maping of the cathode plane of the chamber:
edb96c6a 209 Int_t detElemId = mTD->DetElemId();
210
211 Int_t iNchCpl= fNDetElemId[detElemId] + (mTD->Cathode()-1) * AliMUONConstants::NDetElem();
212
cf286af7 213 AliMUONTransientDigit *pdigit =
214 static_cast<AliMUONTransientDigit*>( fHitMap[iNchCpl]->GetHit(mTD->PadX(),mTD->PadY()) );
215
216 // update charge
217 pdigit->AddSignal( mTD->Signal() );
218 pdigit->AddPhysicsSignal( mTD->Physics() );
219
220 // update list of tracks
221 Int_t ntracks = mTD->GetNTracks();
222 if (ntracks > kMAXTRACKS) // Truncate the number of tracks to kMAXTRACKS if we have to.
223 {
8c343c7c 224 AliDebug(1,Form(
225 "TransientDigit returned the number of tracks to be %d, which is bigger than kMAXTRACKS.",
226 ntracks));
227 AliDebug(1,Form( "Reseting the number of tracks to be %d.", kMAXTRACKS));
cf286af7 228 ntracks = kMAXTRACKS;
925e6570 229 }
cf286af7 230
231 for (Int_t i = 0; i < ntracks; i++)
232 {
233 pdigit->UpdateTrackList( mTD->GetTrack(i), mTD->GetCharge(i) );
925e6570 234 }
235}
28752ff4 236
237//------------------------------------------------------------------------
cf286af7 238void AliMUONDigitizer::AddTransientDigit(AliMUONTransientDigit* mTD)
28752ff4 239{
cf286af7 240// Adds the transient digit to the fTDList and sets the appropriate entry
241// in the fHitMap arrays.
242
8c343c7c 243 AliDebug(4,Form( "Adding transient digit 0x%X", (void*)mTD));
cf286af7 244 // Choosing the maping of the cathode plane of the chamber:
edb96c6a 245
246 Int_t detElemId = mTD->DetElemId();
247 Int_t iNchCpl= fNDetElemId[detElemId] + (mTD->Cathode()-1) * AliMUONConstants::NDetElem();
248
cf286af7 249 fTDList->AddAtAndExpand(mTD, fTDCounter);
f5bb8cee 250 if (iNchCpl>-1 && iNchCpl<2*AliMUONConstants::NDetElem()) {
251 fHitMap[iNchCpl]->SetHit( mTD->PadX(), mTD->PadY(), fTDCounter);
252 fTDCounter++;
253 }
925e6570 254}
28752ff4 255
256//------------------------------------------------------------------------
cf286af7 257Bool_t AliMUONDigitizer::ExistTransientDigit(AliMUONTransientDigit* mTD)
28752ff4 258{
cf286af7 259// Checks if the transient digit already exists on the corresponding fHitMap.
260// i.e. is there a transient digit on the same chamber, cathode and pad position
261// as mTD. If yes then kTRUE is returned else kFASLE is returned.
262
263 // Choosing the maping of the cathode plane of the chamber:
edb96c6a 264 Int_t detElemId = mTD->DetElemId();
265
266 Int_t iNchCpl= fNDetElemId[detElemId] + (mTD->Cathode()-1) *AliMUONConstants::NDetElem() ;
267
268 // Int_t iNchCpl= mTD->Chamber() + (mTD->Cathode()-1) * AliMUONConstants::NCh();
f5bb8cee 269 if (iNchCpl>-1 && iNchCpl<2*AliMUONConstants::NDetElem())
270 return( fHitMap[iNchCpl]->TestHit(mTD->PadX(), mTD->PadY()) );
271 else return kFALSE;
925e6570 272}
28752ff4 273
cf286af7 274//-----------------------------------------------------------------------
275void AliMUONDigitizer::CreateDigits()
276{
277// Loops over the fTDList for each cathode, gets the correct signal for the
278// digit and adds the new digit to the output stream.
279
a713db22 280 fTDList->Sort(); // sort by idDE
281 AliDebug(2, "Creating digits...");
935b9895 282 // for (Int_t icat = 0; icat < 2; icat++) {
a713db22 283
2be06f1e 284 Int_t digitindex[14] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
285
a713db22 286 //
287 // Filling Digit List
288 Int_t nentries = fTDList->GetEntriesFast();
289 for (Int_t nent = 0; nent < nentries; nent++) {
290
291 AliMUONTransientDigit* td = (AliMUONTransientDigit*)fTDList->At(nent);
292 if (td == NULL) continue;
cf286af7 293
a713db22 294 // Must be the same cathode, otherwise we will fill a mixture
295 // of digits from both cathodes.
935b9895 296 //if (icat != td->Cathode() - 1) continue;
cf286af7 297
a713db22 298 AliDebug(3,Form( "Creating digit from transient digit 0x%X", (void*)td));
cf286af7 299
a713db22 300 Int_t q = GetSignalFrom(td);
2be06f1e 301 assert( 0 <= td->Chamber() && td->Chamber() <= 13 );
302 if (q > 0) AddDigit(td, q, digitindex[td->Chamber()]++);
a713db22 303 }
304 FillOutputData();
935b9895 305 // }
79d1df3f 306 fTDCounter = 0;
925e6570 307}
28752ff4 308
309//------------------------------------------------------------------------
2be06f1e 310void AliMUONDigitizer::AddDigit(
311 AliMUONTransientDigit* td, Int_t responseCharge,
b812d393 312 Int_t digitindex
2be06f1e 313 )
28752ff4 314{
cf286af7 315// Prepares the digits, track and charge arrays in preparation for a call to
316// AddDigit(Int_t, Int_t[kMAXTRACKS], Int_t[kMAXTRACKS], Int_t[6])
317// This method is called by CreateDigits() whenever a new digit needs to be added
318// to the output stream trees.
30178c30 319// The responseCharge value is used as the Signal of the new digit.
cf286af7 320// The OnWriteTransientDigit method is also called just before the adding the
321// digit to allow inheriting digitizers to be able to do some specific processing
322// at this point.
323
324 Int_t tracks[kMAXTRACKS];
325 Int_t charges[kMAXTRACKS];
a713db22 326 Int_t digits[7];
88cb7938 327
cf286af7 328 digits[0] = td->PadX();
329 digits[1] = td->PadY();
330 digits[2] = td->Cathode() - 1;
30178c30 331 digits[3] = responseCharge;
cf286af7 332 digits[4] = td->Physics();
333 digits[5] = td->Hit();
002920d1 334 digits[6] = td->DetElemId();
a713db22 335
cf286af7 336 Int_t nptracks = td->GetNTracks();
a713db22 337 if (nptracks > kMAXTRACKS) {
338
339 AliDebug(1, Form(
340 "TransientDigit returned the number of tracks to be %d, which is bigger than kMAXTRACKS.",
341 nptracks));
342 AliDebug(1, Form("Reseting the number of tracks to be %d.", kMAXTRACKS));
343 nptracks = kMAXTRACKS;
925e6570 344 }
cf286af7 345
a713db22 346 for (Int_t i = 0; i < nptracks; i++) {
347
348 tracks[i] = td->GetTrack(i);
349 charges[i] = td->GetCharge(i);
925e6570 350 }
cf286af7 351
352 // Sort list of tracks according to charge
353 SortTracks(tracks,charges,nptracks);
354
a713db22 355 if (nptracks < kMAXTRACKS ) {
356
357 for (Int_t i = nptracks; i < kMAXTRACKS; i++) {
358 tracks[i] = -1;
359 charges[i] = 0;
360 }
925e6570 361 }
cf286af7 362
8c343c7c 363 AliDebug(4,Form( "Adding digit with charge %d.", responseCharge));
cf286af7 364
365 OnWriteTransientDigit(td);
366 AddDigit(td->Chamber(), tracks, charges, digits);
2be06f1e 367 AddDigitTrigger(td->Chamber(), tracks, charges, digits, digitindex);
925e6570 368}
28752ff4 369
cf286af7 370//------------------------------------------------------------------------
371void AliMUONDigitizer::OnCreateTransientDigit(AliMUONTransientDigit* /*digit*/, TObject* /*source_object*/)
372{
373 // Does nothing.
374 //
375 // This is derived by Digitisers that want to trace which digits were made from
376 // which hits.
925e6570 377}
28752ff4 378
b8278504 379//------------------------------------------------------------------------
cf286af7 380void AliMUONDigitizer::OnWriteTransientDigit(AliMUONTransientDigit* /*digit*/)
28752ff4 381{
cf286af7 382 // Does nothing.
383 //
384 // This is derived by Digitisers that want to trace which digits were made from
385 // which hits.
925e6570 386}
cf286af7 387
388//------------------------------------------------------------------------
389Bool_t AliMUONDigitizer::FetchLoaders(const char* foldername, AliRunLoader*& runloader, AliMUONLoader*& muonloader)
390{
391// Fetches the run loader from the current folder, specified by 'foldername'.
392// The muon loader is then loaded from the fetched run loader.
393// kTRUE is returned if no error occurred otherwise kFALSE is returned.
394
8c343c7c 395 AliDebug(3, Form("Fetching run loader and muon loader from folder: %s", foldername));
cf286af7 396
397 runloader = AliRunLoader::GetRunLoader(foldername);
398 if (runloader == NULL)
399 {
8c343c7c 400 AliError(Form("RunLoader not found in folder: %s", foldername));
cf286af7 401 return kFALSE;
402 }
403 muonloader = (AliMUONLoader*) runloader->GetLoader("MUONLoader");
404 if (muonloader == NULL)
405 {
8c343c7c 406 AliError(Form("MUONLoader not found in folder: %s", foldername));
cf286af7 407 return kFALSE;
408 }
409 return kTRUE;
ce3e25a8 410
925e6570 411}
cf286af7 412
413//------------------------------------------------------------------------
414Bool_t AliMUONDigitizer::FetchGlobalPointers(AliRunLoader* runloader)
415{
416// Fetches the AliRun object into the global gAlice pointer from the specified
417// run loader. The AliRun object is loaded into memory using the run loader if
418// not yet loaded. The MUON module object is then loaded from gAlice and
419// AliMUONData fetched from the MUON module.
420// kTRUE is returned if no error occurred otherwise kFALSE is returned.
421
8c343c7c 422 AliDebug(3, Form("Fetching gAlice, MUON module and AliMUONData from runloader 0x%X.",
cf286af7 423 (void*)runloader
8c343c7c 424 ));
cf286af7 425
426 if (runloader->GetAliRun() == NULL) runloader->LoadgAlice();
427 gAlice = runloader->GetAliRun();
428 if (gAlice == NULL)
429 {
8c343c7c 430 AliError(Form("Could not find the AliRun object in runloader 0x%X.", (void*)runloader));
cf286af7 431 return kFALSE;
925e6570 432 }
30178c30 433 fMUON = (AliMUON*) gAlice->GetDetector("MUON");
434 if (fMUON == NULL)
cf286af7 435 {
8c343c7c 436 AliError(Form("Could not find the MUON module in runloader 0x%X.", (void*)runloader));
cf286af7 437 return kFALSE;
925e6570 438 }
88646004 439
440 AliMUONLoader *muonloader = (AliMUONLoader*) runloader->GetLoader("MUONLoader");
441 if (muonloader == NULL)
442 {
8c343c7c 443 AliError( "MUONLoader not found ");
88646004 444 return kFALSE;
445 }
446
447
a20e540f 448 if (fMUONData == NULL) fMUONData = new AliMUONData(muonloader,"MUON","MUON");
30178c30 449 if (fMUONData == NULL)
cf286af7 450 {
8c343c7c 451 AliError(Form("Could not find AliMUONData object in runloader 0x%X.", (void*)runloader));
cf286af7 452 return kFALSE;
925e6570 453 }
ce3e25a8 454
cf286af7 455 return kTRUE;
28752ff4 456}
ce3e25a8 457//-----------------------------------------------------------------------
458Bool_t AliMUONDigitizer::FetchTriggerPointer(AliMUONLoader* loader)
459{
460 if (fMUONData == NULL) {
8c343c7c 461 AliError("MUONData not found");
ce3e25a8 462 return kFALSE;
463 }
464
465 if (fTrigDec == NULL)
466 fTrigDec = new AliMUONTriggerDecision(loader,0,fMUONData);
467
468 return kTRUE;
469}
cf286af7 470
471//------------------------------------------------------------------------
472void AliMUONDigitizer::InitArrays()
473{
474// Creates a new fTDList object.
475// Also creates an array of 2 * chamber_number AliMUONHitMapA1 objects
476// in the fHitMaps array. Each one is set to a chamber and cathode
477// specific segmentation model.
478//
479// Note: the fTDList and fHitMap arrays must be NULL before calling this method.
480
fed772f3 481 AliDebug(2, "Initialising internal arrays.");
482 AliDebug(4, "Creating transient digits list.");
483 fTDList = new TObjArray;
cf286af7 484
fed772f3 485 // Array of pointer of the AliMUONHitMapA1:
486 // two HitMaps per chamber, or one HitMap per cahtode plane
edb96c6a 487 fHitMap = new AliMUONHitMapA1* [2*AliMUONConstants::NDetElem()];
f5bb8cee 488 for (Int_t i=0; i<2*AliMUONConstants::NDetElem(); i++) fHitMap[i] = 0x0;
002920d1 489
edb96c6a 490 Int_t k = 0;
491 Int_t idDE;
002920d1 492
edb96c6a 493 for (Int_t i = 0; i < AliMUONConstants::NCh(); i++) {
fed772f3 494
002920d1 495
496 AliDebug(4,Form( "Creating hit map for chamber %d, cathode 1.", i+1));
b7ef3c96 497 AliMUONSegmentation* segmentation = fMUON->GetSegmentation();
498 AliMUONGeometrySegmentation* c1Segmentation
499 = segmentation->GetModuleSegmentation(i, 0); // Cathode plane 1
002920d1 500 AliDebug(4,Form( "Creating hit map for chamber %d, cathode 2.", i+1));
b7ef3c96 501 AliMUONGeometrySegmentation* c2Segmentation
502 = segmentation->GetModuleSegmentation(i, 1); // Cathode plane 2
503
504 const AliMUONGeometryTransformer* kGeometryTransformer
505 = fMUON->GetGeometryTransformer();
506
507 AliMUONGeometryStore* detElements
508 = kGeometryTransformer->GetModuleTransformer(i)->GetDetElementStore();
002920d1 509
edb96c6a 510
511 // Loop over detection elements
512 for (Int_t j=0; j<detElements->GetNofEntries(); j++) {
513
514 idDE = detElements->GetEntry(j)->GetUniqueID();
515 fNDetElemId[idDE] = k;
516
517 fHitMap[k] = new AliMUONHitMapA1(idDE,c1Segmentation, fTDList);
518
519 fHitMap[k+AliMUONConstants::NDetElem()] = new AliMUONHitMapA1(idDE,c2Segmentation, fTDList);
520 k++;
521 }
522 }
925e6570 523}
cf286af7 524//------------------------------------------------------------------------
525void AliMUONDigitizer::CleanupArrays()
526{
527// The arrays fTDList and fHitMap are deleted and the pointers set to NULL.
528
8c343c7c 529 AliDebug(2, "Deleting internal arrays.");
edb96c6a 530 for(Int_t i = 0; i < 2*AliMUONConstants::NDetElem(); i++) {
cf286af7 531 delete fHitMap[i];
925e6570 532 }
cf286af7 533 delete [] fHitMap;
534 fHitMap = NULL;
535
8c343c7c 536 AliDebug(4, "Deleting transient digits list.");
cf286af7 537 fTDList->Delete();
538 delete fTDList;
539 fTDList = NULL;
ce3e25a8 540
925e6570 541}
cf286af7 542
543//------------------------------------------------------------------------
30178c30 544void AliMUONDigitizer::SortTracks(Int_t *tracks, Int_t *charges, Int_t ntr) const
cf286af7 545{
546//
547// Sort the list of tracks contributing to a given digit
548// Only the 3 most significant tracks are actually sorted
549//
550
a713db22 551 if (ntr <= 1) return;
cf286af7 552
a713db22 553 //
554 // Loop over signals, only 3 times
555 //
cf286af7 556
a713db22 557 Int_t qmax;
558 Int_t jmax;
559 Int_t idx[3] = {-2,-2,-2};
560 Int_t jch[3] = {-2,-2,-2};
561 Int_t jtr[3] = {-2,-2,-2};
562 Int_t i, j, imax;
cf286af7 563
a713db22 564 if (ntr < 3) imax = ntr;
565 else imax=3;
cf286af7 566
a713db22 567 for(i = 0; i < imax; i++)
568 {
569 qmax=0;
570 jmax=0;
571
572 for(j = 0; j < ntr; j++)
573 {
574 if ( (i == 1 && j == idx[i-1]) ||
575 (i == 2 && (j == idx[i-1] || j == idx[i-2]))
576 )
577 continue;
578
579 if(charges[j] > qmax)
580 {
581 qmax = charges[j];
582 jmax = j;
583 }
584 }
585
586 if(qmax > 0)
587 {
588 idx[i] = jmax;
589 jch[i] = charges[jmax];
590 jtr[i] = tracks[jmax];
591 }
592
593 }
594
595 for(i = 0; i < 3; i++)
596 {
597 if (jtr[i] == -2)
598 {
599 charges[i] = 0;
600 tracks[i] = 0;
601 }
602 else
603 {
604 charges[i] = jch[i];
605 tracks[i] = jtr[i];
606 }
607 }
925e6570 608}