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