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