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