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