]> git.uio.no Git - u/mrichter/AliRoot.git/blame - MUON/AliMUONDigitizer.cxx
Check the chambers by assert only in case of signal
[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);
bd713d65 301 if (q > 0) {
302 assert( 0 <= td->Chamber() && td->Chamber() <= 13 );
303 AddDigit(td, q, digitindex[td->Chamber()]++);
304 }
a713db22 305 }
306 FillOutputData();
935b9895 307 // }
79d1df3f 308 fTDCounter = 0;
925e6570 309}
28752ff4 310
311//------------------------------------------------------------------------
2be06f1e 312void AliMUONDigitizer::AddDigit(
313 AliMUONTransientDigit* td, Int_t responseCharge,
b812d393 314 Int_t digitindex
2be06f1e 315 )
28752ff4 316{
cf286af7 317// Prepares the digits, track and charge arrays in preparation for a call to
318// AddDigit(Int_t, Int_t[kMAXTRACKS], Int_t[kMAXTRACKS], Int_t[6])
319// This method is called by CreateDigits() whenever a new digit needs to be added
320// to the output stream trees.
30178c30 321// The responseCharge value is used as the Signal of the new digit.
cf286af7 322// The OnWriteTransientDigit method is also called just before the adding the
323// digit to allow inheriting digitizers to be able to do some specific processing
324// at this point.
325
326 Int_t tracks[kMAXTRACKS];
327 Int_t charges[kMAXTRACKS];
a713db22 328 Int_t digits[7];
88cb7938 329
cf286af7 330 digits[0] = td->PadX();
331 digits[1] = td->PadY();
332 digits[2] = td->Cathode() - 1;
30178c30 333 digits[3] = responseCharge;
cf286af7 334 digits[4] = td->Physics();
335 digits[5] = td->Hit();
002920d1 336 digits[6] = td->DetElemId();
a713db22 337
cf286af7 338 Int_t nptracks = td->GetNTracks();
a713db22 339 if (nptracks > kMAXTRACKS) {
340
341 AliDebug(1, Form(
342 "TransientDigit returned the number of tracks to be %d, which is bigger than kMAXTRACKS.",
343 nptracks));
344 AliDebug(1, Form("Reseting the number of tracks to be %d.", kMAXTRACKS));
345 nptracks = kMAXTRACKS;
925e6570 346 }
cf286af7 347
a713db22 348 for (Int_t i = 0; i < nptracks; i++) {
349
350 tracks[i] = td->GetTrack(i);
351 charges[i] = td->GetCharge(i);
925e6570 352 }
cf286af7 353
354 // Sort list of tracks according to charge
355 SortTracks(tracks,charges,nptracks);
356
a713db22 357 if (nptracks < kMAXTRACKS ) {
358
359 for (Int_t i = nptracks; i < kMAXTRACKS; i++) {
360 tracks[i] = -1;
361 charges[i] = 0;
362 }
925e6570 363 }
cf286af7 364
8c343c7c 365 AliDebug(4,Form( "Adding digit with charge %d.", responseCharge));
cf286af7 366
367 OnWriteTransientDigit(td);
368 AddDigit(td->Chamber(), tracks, charges, digits);
2be06f1e 369 AddDigitTrigger(td->Chamber(), tracks, charges, digits, digitindex);
925e6570 370}
28752ff4 371
cf286af7 372//------------------------------------------------------------------------
373void AliMUONDigitizer::OnCreateTransientDigit(AliMUONTransientDigit* /*digit*/, TObject* /*source_object*/)
374{
375 // Does nothing.
376 //
377 // This is derived by Digitisers that want to trace which digits were made from
378 // which hits.
925e6570 379}
28752ff4 380
b8278504 381//------------------------------------------------------------------------
cf286af7 382void AliMUONDigitizer::OnWriteTransientDigit(AliMUONTransientDigit* /*digit*/)
28752ff4 383{
cf286af7 384 // Does nothing.
385 //
386 // This is derived by Digitisers that want to trace which digits were made from
387 // which hits.
925e6570 388}
cf286af7 389
390//------------------------------------------------------------------------
391Bool_t AliMUONDigitizer::FetchLoaders(const char* foldername, AliRunLoader*& runloader, AliMUONLoader*& muonloader)
392{
393// Fetches the run loader from the current folder, specified by 'foldername'.
394// The muon loader is then loaded from the fetched run loader.
395// kTRUE is returned if no error occurred otherwise kFALSE is returned.
396
8c343c7c 397 AliDebug(3, Form("Fetching run loader and muon loader from folder: %s", foldername));
cf286af7 398
399 runloader = AliRunLoader::GetRunLoader(foldername);
400 if (runloader == NULL)
401 {
8c343c7c 402 AliError(Form("RunLoader not found in folder: %s", foldername));
cf286af7 403 return kFALSE;
404 }
405 muonloader = (AliMUONLoader*) runloader->GetLoader("MUONLoader");
406 if (muonloader == NULL)
407 {
8c343c7c 408 AliError(Form("MUONLoader not found in folder: %s", foldername));
cf286af7 409 return kFALSE;
410 }
411 return kTRUE;
ce3e25a8 412
925e6570 413}
cf286af7 414
415//------------------------------------------------------------------------
416Bool_t AliMUONDigitizer::FetchGlobalPointers(AliRunLoader* runloader)
417{
418// Fetches the AliRun object into the global gAlice pointer from the specified
419// run loader. The AliRun object is loaded into memory using the run loader if
420// not yet loaded. The MUON module object is then loaded from gAlice and
421// AliMUONData fetched from the MUON module.
422// kTRUE is returned if no error occurred otherwise kFALSE is returned.
423
8c343c7c 424 AliDebug(3, Form("Fetching gAlice, MUON module and AliMUONData from runloader 0x%X.",
cf286af7 425 (void*)runloader
8c343c7c 426 ));
cf286af7 427
428 if (runloader->GetAliRun() == NULL) runloader->LoadgAlice();
429 gAlice = runloader->GetAliRun();
430 if (gAlice == NULL)
431 {
8c343c7c 432 AliError(Form("Could not find the AliRun object in runloader 0x%X.", (void*)runloader));
cf286af7 433 return kFALSE;
925e6570 434 }
30178c30 435 fMUON = (AliMUON*) gAlice->GetDetector("MUON");
436 if (fMUON == NULL)
cf286af7 437 {
8c343c7c 438 AliError(Form("Could not find the MUON module in runloader 0x%X.", (void*)runloader));
cf286af7 439 return kFALSE;
925e6570 440 }
88646004 441
442 AliMUONLoader *muonloader = (AliMUONLoader*) runloader->GetLoader("MUONLoader");
443 if (muonloader == NULL)
444 {
8c343c7c 445 AliError( "MUONLoader not found ");
88646004 446 return kFALSE;
447 }
448
449
a20e540f 450 if (fMUONData == NULL) fMUONData = new AliMUONData(muonloader,"MUON","MUON");
30178c30 451 if (fMUONData == NULL)
cf286af7 452 {
8c343c7c 453 AliError(Form("Could not find AliMUONData object in runloader 0x%X.", (void*)runloader));
cf286af7 454 return kFALSE;
925e6570 455 }
ce3e25a8 456
cf286af7 457 return kTRUE;
28752ff4 458}
ce3e25a8 459//-----------------------------------------------------------------------
460Bool_t AliMUONDigitizer::FetchTriggerPointer(AliMUONLoader* loader)
461{
462 if (fMUONData == NULL) {
8c343c7c 463 AliError("MUONData not found");
ce3e25a8 464 return kFALSE;
465 }
466
467 if (fTrigDec == NULL)
468 fTrigDec = new AliMUONTriggerDecision(loader,0,fMUONData);
469
470 return kTRUE;
471}
cf286af7 472
473//------------------------------------------------------------------------
474void AliMUONDigitizer::InitArrays()
475{
476// Creates a new fTDList object.
477// Also creates an array of 2 * chamber_number AliMUONHitMapA1 objects
478// in the fHitMaps array. Each one is set to a chamber and cathode
479// specific segmentation model.
480//
481// Note: the fTDList and fHitMap arrays must be NULL before calling this method.
482
fed772f3 483 AliDebug(2, "Initialising internal arrays.");
484 AliDebug(4, "Creating transient digits list.");
485 fTDList = new TObjArray;
cf286af7 486
fed772f3 487 // Array of pointer of the AliMUONHitMapA1:
488 // two HitMaps per chamber, or one HitMap per cahtode plane
edb96c6a 489 fHitMap = new AliMUONHitMapA1* [2*AliMUONConstants::NDetElem()];
f5bb8cee 490 for (Int_t i=0; i<2*AliMUONConstants::NDetElem(); i++) fHitMap[i] = 0x0;
002920d1 491
edb96c6a 492 Int_t k = 0;
493 Int_t idDE;
002920d1 494
edb96c6a 495 for (Int_t i = 0; i < AliMUONConstants::NCh(); i++) {
fed772f3 496
002920d1 497
498 AliDebug(4,Form( "Creating hit map for chamber %d, cathode 1.", i+1));
b7ef3c96 499 AliMUONSegmentation* segmentation = fMUON->GetSegmentation();
500 AliMUONGeometrySegmentation* c1Segmentation
501 = segmentation->GetModuleSegmentation(i, 0); // Cathode plane 1
002920d1 502 AliDebug(4,Form( "Creating hit map for chamber %d, cathode 2.", i+1));
b7ef3c96 503 AliMUONGeometrySegmentation* c2Segmentation
504 = segmentation->GetModuleSegmentation(i, 1); // Cathode plane 2
505
506 const AliMUONGeometryTransformer* kGeometryTransformer
507 = fMUON->GetGeometryTransformer();
508
509 AliMUONGeometryStore* detElements
510 = kGeometryTransformer->GetModuleTransformer(i)->GetDetElementStore();
002920d1 511
edb96c6a 512
513 // Loop over detection elements
514 for (Int_t j=0; j<detElements->GetNofEntries(); j++) {
515
516 idDE = detElements->GetEntry(j)->GetUniqueID();
517 fNDetElemId[idDE] = k;
518
519 fHitMap[k] = new AliMUONHitMapA1(idDE,c1Segmentation, fTDList);
520
521 fHitMap[k+AliMUONConstants::NDetElem()] = new AliMUONHitMapA1(idDE,c2Segmentation, fTDList);
522 k++;
523 }
524 }
925e6570 525}
cf286af7 526//------------------------------------------------------------------------
527void AliMUONDigitizer::CleanupArrays()
528{
529// The arrays fTDList and fHitMap are deleted and the pointers set to NULL.
530
8c343c7c 531 AliDebug(2, "Deleting internal arrays.");
edb96c6a 532 for(Int_t i = 0; i < 2*AliMUONConstants::NDetElem(); i++) {
cf286af7 533 delete fHitMap[i];
925e6570 534 }
cf286af7 535 delete [] fHitMap;
536 fHitMap = NULL;
537
8c343c7c 538 AliDebug(4, "Deleting transient digits list.");
cf286af7 539 fTDList->Delete();
540 delete fTDList;
541 fTDList = NULL;
ce3e25a8 542
925e6570 543}
cf286af7 544
545//------------------------------------------------------------------------
30178c30 546void AliMUONDigitizer::SortTracks(Int_t *tracks, Int_t *charges, Int_t ntr) const
cf286af7 547{
548//
549// Sort the list of tracks contributing to a given digit
550// Only the 3 most significant tracks are actually sorted
551//
552
a713db22 553 if (ntr <= 1) return;
cf286af7 554
a713db22 555 //
556 // Loop over signals, only 3 times
557 //
cf286af7 558
a713db22 559 Int_t qmax;
560 Int_t jmax;
561 Int_t idx[3] = {-2,-2,-2};
562 Int_t jch[3] = {-2,-2,-2};
563 Int_t jtr[3] = {-2,-2,-2};
564 Int_t i, j, imax;
cf286af7 565
a713db22 566 if (ntr < 3) imax = ntr;
567 else imax=3;
cf286af7 568
a713db22 569 for(i = 0; i < imax; i++)
570 {
571 qmax=0;
572 jmax=0;
573
574 for(j = 0; j < ntr; j++)
575 {
576 if ( (i == 1 && j == idx[i-1]) ||
577 (i == 2 && (j == idx[i-1] || j == idx[i-2]))
578 )
579 continue;
580
581 if(charges[j] > qmax)
582 {
583 qmax = charges[j];
584 jmax = j;
585 }
586 }
587
588 if(qmax > 0)
589 {
590 idx[i] = jmax;
591 jch[i] = charges[jmax];
592 jtr[i] = tracks[jmax];
593 }
594
595 }
596
597 for(i = 0; i < 3; i++)
598 {
599 if (jtr[i] == -2)
600 {
601 charges[i] = 0;
602 tracks[i] = 0;
603 }
604 else
605 {
606 charges[i] = jch[i];
607 tracks[i] = jtr[i];
608 }
609 }
925e6570 610}