1 /**************************************************************************
2 * Copyright(c) 1998-2000, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
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 **************************************************************************/
19 Class for creating of the sumable digits and digits from MC data
21 The input : ideal signals (Hits->Diffusion->Attachment -Ideal signal)
22 The output: "raw digits"
25 1. Pad by pad gain map
27 3. The dead channels identified - zerro noise for corresponding pads
28 In this case the outpu equal zerro
37 #include <TObjArray.h>
39 #include <TDirectory.h>
40 #include <Riostream.h>
41 #include <TParameter.h>
43 #include "AliTPCDigitizer.h"
46 #include "AliTPCParam.h"
47 #include "AliTPCParamSR.h"
49 #include "AliLoader.h"
51 #include "AliDigitizationInput.h"
52 #include "AliSimDigits.h"
55 #include "AliTPCcalibDB.h"
56 #include "AliTPCCalPad.h"
57 #include "AliTPCCalROC.h"
58 #include "TTreeStream.h"
59 #include "AliTPCReconstructor.h"
60 #include <TGraphErrors.h>
65 ClassImp(AliTPCDigitizer)
67 //___________________________________________
68 AliTPCDigitizer::AliTPCDigitizer() :AliDigitizer(),fDebug(0), fDebugStreamer(0)
71 // Default ctor - don't use it
76 //___________________________________________
77 AliTPCDigitizer::AliTPCDigitizer(AliDigitizationInput* digInput)
78 :AliDigitizer(digInput),fDebug(0), fDebugStreamer(0)
81 // ctor which should be used
83 AliDebug(2,"(AliDigitizationInput* digInput) was processed");
84 if (AliTPCReconstructor::StreamLevel()>0) fDebugStreamer = new TTreeSRedirector("TPCDigitDebug.root");
88 //------------------------------------------------------------------------
89 AliTPCDigitizer::~AliTPCDigitizer()
92 if (fDebugStreamer) delete fDebugStreamer;
97 //------------------------------------------------------------------------
98 Bool_t AliTPCDigitizer::Init()
106 //------------------------------------------------------------------------
107 void AliTPCDigitizer::Digitize(Option_t* option)
109 DigitizeFast(option);
111 //------------------------------------------------------------------------
112 void AliTPCDigitizer::DigitizeFast(Option_t* option)
115 // merge input tree's with summable digits
116 //output stored in TreeTPCD
119 TString optionString = option;
120 if (!strcmp(optionString.Data(),"deb")) {
121 cout<<"AliTPCDigitizer:::DigitizeFast called with option deb "<<endl;
124 //get detector and geometry
127 AliRunLoader *rl, *orl;
128 AliLoader *gime, *ogime;
132 Warning("DigitizeFast","gAlice is NULL. Loading from input 0");
133 rl = AliRunLoader::GetRunLoader(fDigInput->GetInputFolderName(0));
136 Error("DigitizeFast","Can not find Run Loader for input 0. Can not proceed.");
142 AliTPC *pTPC = (AliTPC *) gAlice->GetModule("TPC");
143 AliTPCParam * param = pTPC->GetParam();
145 //sprintf(s,param->GetTitle());
146 snprintf(s,100,"%s",param->GetTitle());
147 //sprintf(ss,"75x40_100x60");
148 snprintf(ss,100,"75x40_100x60");
150 printf("2 pad-length geom hits with 3 pad-lenght geom digits...\n");
152 param=new AliTPCParamSR();
155 //sprintf(ss,"75x40_100x60_150x60");
156 snprintf(ss,100,"75x40_100x60_150x60");
157 if(strcmp(s,ss)!=0) {
158 printf("No TPC parameters found...\n");
163 pTPC->GenerNoise(500000); //create table with noise
165 Int_t nInputs = fDigInput->GetNinputs();
166 Int_t * masks = new Int_t[nInputs];
167 for (Int_t i=0; i<nInputs;i++)
168 masks[i]= fDigInput->GetMask(i);
169 Short_t **pdig= new Short_t*[nInputs]; //pointers to the expanded digits array
170 Int_t **ptr= new Int_t*[nInputs]; //pointers to the expanded tracks array
171 Bool_t *active= new Bool_t[nInputs]; //flag for active input segments
174 //create digits array for given sectors
177 //create branch's in TPC treeD
178 orl = AliRunLoader::GetRunLoader(fDigInput->GetOutputFolderName());
179 ogime = orl->GetLoader("TPCLoader");
180 TTree * tree = ogime->TreeD();
181 AliSimDigits * digrow = new AliSimDigits;
185 ogime->MakeTree("D");
186 tree = ogime->TreeD();
188 tree->Branch("Segment","AliSimDigits",&digrow);
190 AliSimDigits ** digarr = new AliSimDigits*[nInputs];
191 for (Int_t i1=0;i1<nInputs; i1++)
195 rl = AliRunLoader::GetRunLoader(fDigInput->GetInputFolderName(i1));
196 gime = rl->GetLoader("TPCLoader");
197 gime->LoadSDigits("read");
198 TTree * treear = gime->TreeS();
202 cerr<<"AliTPCDigitizer: Input tree with SDigits not found in"
203 <<" input "<< i1<<endl;
204 for (Int_t i2=0;i2<i1+1; i2++){
206 if(digarr[i2]) delete digarr[i2];
216 //sprintf(phname,"lhcphase%d",i1);
217 snprintf(phname,100,"lhcphase%d",i1);
218 TParameter<float> *ph = (TParameter<float>*)treear->GetUserInfo()
219 ->FindObject("lhcphase0");
221 cerr<<"AliTPCDigitizer: LHC phase not found in"
222 <<" input "<< i1<<endl;
223 for (Int_t i2=0;i2<i1+1; i2++){
224 if(digarr[i2]) delete digarr[i2];
233 tree->GetUserInfo()->Add(new TParameter<float>(phname,ph->GetVal()));
235 if (treear->GetIndex()==0)
236 treear->BuildIndex("fSegmentID","fSegmentID");
237 treear->GetBranch("Segment")->SetAddress(&digarr[i1]);
245 param->SetZeroSup(2);
247 Int_t zerosup = param->GetZeroSup();
248 AliTPCCalPad * gainTPC = AliTPCcalibDB::Instance()->GetDedxGainFactor();
249 AliTPCCalPad * noiseTPC = AliTPCcalibDB::Instance()->GetPadNoise();
251 //Loop over segments of the TPC
253 for (Int_t segmentID=0; segmentID<param->GetNRowsTotal(); segmentID++)
255 Int_t sector, padRow;
256 if (!param->AdjustSectorRow(segmentID,sector,padRow))
258 cerr<<"AliTPC warning: invalid segment ID ! "<<segmentID<<endl;
261 AliTPCCalROC * gainROC = gainTPC->GetCalROC(sector); // pad gains per given sector
262 AliTPCCalROC * noiseROC = noiseTPC->GetCalROC(sector); // noise per given sector
263 digrow->SetID(segmentID);
268 Bool_t digitize = kFALSE;
269 for (Int_t i=0;i<nInputs; i++)
272 rl = AliRunLoader::GetRunLoader(fDigInput->GetInputFolderName(i));
273 gime = rl->GetLoader("TPCLoader");
275 if (gime->TreeS()->GetEntryWithIndex(segmentID,segmentID) >= 0) {
276 digarr[i]->ExpandBuffer();
277 digarr[i]->ExpandTrackBuffer();
278 nTimeBins = digarr[i]->GetNRows();
279 nPads = digarr[i]->GetNCols();
281 if (!GetRegionOfInterest() || (i == 0)) digitize = kTRUE;
285 if (GetRegionOfInterest() && !digitize) break;
287 if (!digitize) continue;
289 digrow->Allocate(nTimeBins,nPads);
290 digrow->AllocateTrack(3);
293 Int_t label[1000]; //stack for 300 events
296 Int_t nElems = nTimeBins*nPads;
298 for (Int_t i=0;i<nInputs; i++)
300 pdig[i] = digarr[i]->GetDigits();
301 ptr[i] = digarr[i]->GetTracks();
304 Short_t *pdig1= digrow->GetDigits();
305 Int_t *ptr1= digrow->GetTracks() ;
309 for (Int_t elem=0;elem<nElems; elem++)
315 for (Int_t i=0;i<nInputs; i++) if (active[i])
317 // q += digarr[i]->GetDigitFast(rows,col);
320 for (Int_t tr=0;tr<3;tr++)
322 // Int_t lab = digarr[i]->GetTrackIDFast(rows,col,tr);
323 Int_t lab = ptr[i][tr*nElems];
324 if ( (lab > 1) && *(pdig[i])>zerosup)
326 label[labptr]=lab+masks[i];
333 q/=16.; //conversion factor
334 Float_t gain = gainROC->GetValue(padRow,elem/nTimeBins); // get gain for given - pad-row pad
336 //printf("problem\n");
339 Float_t noisePad = noiseROC->GetValue(padRow,elem/nTimeBins);
340 // Float_t noise = gRandom->Gaus(0,param->GetNoise()*param->GetNoiseNormFac());
341 Float_t noise = pTPC->GetNoise();
346 if(q >= param->GetADCSat()) q = (Short_t)(param->GetADCSat() - 1);
347 //digrow->SetDigitFast((Short_t)q,rows,col);
349 for (Int_t tr=0;tr<3;tr++)
352 ptr1[tr*nElems] = label[tr];
361 digrow->GlitchFilter();
363 digrow->CompresBuffer(1,zerosup);
364 digrow->CompresTrackBuffer(1);
366 if (fDebug>0) cerr<<sector<<"\t"<<padRow<<"\n";
367 } //for (Int_t n=0; n<param->GetNRowsTotal(); n++)
370 orl = AliRunLoader::GetRunLoader(fDigInput->GetOutputFolderName());
371 ogime = orl->GetLoader("TPCLoader");
372 ogime->WriteDigits("OVERWRITE");
374 //fDigInput->GetTreeDTPC()->Write(0,TObject::kOverwrite);
377 for (Int_t i1=0;i1<nInputs; i1++) delete digarr[i1];
387 //------------------------------------------------------------------------
388 void AliTPCDigitizer::DigitizeSave(Option_t* option)
391 // Merge input tree's with summable digits
392 // Output digits stored in TreeTPCD
394 // Not active for long time.
395 // Before adding modification (for ion tail calucation and for the crorsstalk) it should be
396 // checked one by one with currenlty used AliTPCDigitizer::DigitizeFast
398 TString optionString = option;
399 if (!strcmp(optionString.Data(),"deb")) {
400 cout<<"AliTPCDigitizer::Digitize: called with option deb "<<endl;
403 //get detector and geometry
404 AliRunLoader *rl, *orl;
405 AliLoader *gime, *ogime;
408 orl = AliRunLoader::GetRunLoader(fDigInput->GetOutputFolderName());
409 ogime = orl->GetLoader("TPCLoader");
411 rl = AliRunLoader::GetRunLoader(fDigInput->GetInputFolderName(0));
412 //gime = rl->GetLoader("TPCLoader");
413 rl->GetLoader("TPCLoader");
415 AliRun* alirun = rl->GetAliRun();
417 AliTPC *pTPC = (AliTPC *) alirun->GetModule("TPC");
418 AliTPCParam * param = pTPC->GetParam();
419 pTPC->GenerNoise(500000); //create teble with noise
420 printf("noise %f \n", param->GetNoise()*param->GetNoiseNormFac());
422 Int_t nInputs = fDigInput->GetNinputs();
423 // stupid protection...
424 if (nInputs <= 0) return;
426 Int_t * masks = new Int_t[nInputs];
427 for (Int_t i=0; i<nInputs;i++)
428 masks[i]= fDigInput->GetMask(i);
430 AliSimDigits ** digarr = new AliSimDigits*[nInputs];
431 for(Int_t ii=0;ii<nInputs;ii++) digarr[ii]=0;
433 for (Int_t i1=0;i1<nInputs; i1++)
437 rl = AliRunLoader::GetRunLoader(fDigInput->GetInputFolderName(i1));
438 gime = rl->GetLoader("TPCLoader");
440 TTree * treear = gime->TreeS();
443 cerr<<" TPC - not existing input = \n"<<i1<<" ";
445 for(Int_t i=0; i<nInputs; i++) delete digarr[i];
450 TBranch * br = treear->GetBranch("fSegmentID");
451 if (br) br->GetFile()->cd();
452 treear->GetBranch("Segment")->SetAddress(&digarr[i1]);
455 rl = AliRunLoader::GetRunLoader(fDigInput->GetInputFolderName(0));
456 gime = rl->GetLoader("TPCLoader");
457 Stat_t nentries = gime->TreeS()->GetEntries();
460 //create branch's in TPC treeD
461 AliSimDigits * digrow = new AliSimDigits;
462 TTree * tree = ogime->TreeD();
464 tree->Branch("Segment","AliSimDigits",&digrow);
465 param->SetZeroSup(2);
467 Int_t zerosup = param->GetZeroSup();
468 //Loop over segments of the TPC
470 AliTPCCalPad * gainTPC = AliTPCcalibDB::Instance()->GetDedxGainFactor();
471 AliTPCCalPad * noiseTPC = AliTPCcalibDB::Instance()->GetPadNoise();
472 for (Int_t n=0; n<nentries; n++) {
473 rl = AliRunLoader::GetRunLoader(fDigInput->GetInputFolderName(0));
474 gime = rl->GetLoader("TPCLoader");
475 gime->TreeS()->GetEvent(n);
477 digarr[0]->ExpandBuffer();
478 digarr[0]->ExpandTrackBuffer();
481 for (Int_t i=1;i<nInputs; i++){
482 // fDigInput->GetInputTreeTPCS(i)->GetEntryWithIndex(digarr[0]->GetID(),digarr[0]->GetID());
483 rl = AliRunLoader::GetRunLoader(fDigInput->GetInputFolderName(i));
484 gime = rl->GetLoader("TPCLoader");
485 gime->TreeS()->GetEntryWithIndex(digarr[0]->GetID(),digarr[0]->GetID());
486 digarr[i]->ExpandBuffer();
487 digarr[i]->ExpandTrackBuffer();
488 if ((digarr[0]->GetID()-digarr[i]->GetID())>0)
493 Int_t sector, padRow;
494 if (!param->AdjustSectorRow(digarr[0]->GetID(),sector,padRow)) {
495 cerr<<"AliTPC warning: invalid segment ID ! "<<digarr[0]->GetID()<<endl;
499 AliTPCCalROC * gainROC = gainTPC->GetCalROC(sector); // pad gains per given sector
500 AliTPCCalROC * noiseROC = noiseTPC->GetCalROC(sector); // noise per given sector
501 digrow->SetID(digarr[0]->GetID());
503 Int_t nTimeBins = digarr[0]->GetNRows();
504 Int_t nPads = digarr[0]->GetNCols();
505 digrow->Allocate(nTimeBins,nPads);
506 digrow->AllocateTrack(3);
509 Int_t label[1000]; //stack for 300 events
514 for (Int_t iTimeBin=0;iTimeBin<nTimeBins; iTimeBin++){ // iTimeBin
515 for (Int_t iPad=0;iPad<nPads; iPad++){ // pad
520 for (Int_t i=0;i<nInputs; i++){
521 q += digarr[i]->GetDigitFast(iTimeBin,iPad);
524 for (Int_t tr=0;tr<3;tr++) {
525 Int_t lab = digarr[i]->GetTrackIDFast(iTimeBin,iPad,tr);
526 //Int_t lab = ptr[i][tr*nElems];
528 label[labptr]=lab+masks[i];
536 q/=16.; //conversion factor
537 // Float_t noise = gRandom->Gaus(0,param->GetNoise()*param->GetNoiseNormFac());
538 Float_t gain = gainROC->GetValue(padRow,iPad);
540 Float_t noisePad = noiseROC->GetValue(padRow, iPad);
542 Float_t noise = pTPC->GetNoise();
545 // here we can get digits from past and add signal
548 //for (Int_t jTimeBin=0; jTimeBin<iTimeBin; jTimeBin++)
555 if(q >= param->GetADCSat()) q = (Short_t)(param->GetADCSat() - 1);
556 digrow->SetDigitFast((Short_t)q,iTimeBin,iPad);
557 // *pdig1 =Short_t(q);
558 for (Int_t tr=0;tr<3;tr++){
560 ((AliSimDigits*)digrow)->SetTrackIDFast(label[tr],iTimeBin,iPad,tr);
561 //ptr1[tr*nElems] = label[tr];
563 // ((AliSimDigits*)digrow)->SetTrackIDFast(-1,iTimeBin,iPad,tr);
564 // ptr1[tr*nElems] = 1;
572 digrow->CompresBuffer(1,zerosup);
573 digrow->CompresTrackBuffer(1);
575 if (fDebug>0) cerr<<sector<<"\t"<<padRow<<"\n";
577 // printf("end TPC merging - end -Tree %s\t%p\n",fDigInput->GetInputTreeH(0)->GetName(),fDigInput->GetInputTreeH(0)->GetListOfBranches()->At(3));
578 //fDigInput->GetTreeDTPC()->Write(0,TObject::kOverwrite);
579 ogime->WriteDigits("OVERWRITE");
581 for (Int_t i=1;i<nInputs; i++)
583 rl = AliRunLoader::GetRunLoader(fDigInput->GetInputFolderName(i));
584 gime = rl->GetLoader("TPCLoader");
585 gime->UnloadSDigits();
587 ogime->UnloadDigits();
590 for (Int_t i1=0;i1<nInputs; i1++) delete digarr[i1];
601 //------------------------------------------------------------------------
602 void AliTPCDigitizer::DigitizeWithTailAndCrossTalk(Option_t* option)
604 // Modified version of the digitization function
605 // Modification: adding the ion tail and crosstalk:
607 // pcstream used in order to visually inspect data
610 // Crosstalk simulation:
611 // 1.) Calculate per time bin mean charge (per pad) within anode wire segment
612 // 2.) Subsract for the clusters at given time bin fraction of (mean charge) normalized by add hoc constant
613 // AliTPCRecoParam::GetCrosstalkCorrection() (0 if not crosstalk, 1 if ideal crosstalk)
614 // for simplicity we are assuming that wire segents are related to pad-rows
615 // Wire segmentationn is obtatined from the
616 // AliTPCParam::GetWireSegment(Int_t sector, Int_t row); // to be implemented
617 // AliTPCParam::GetNPadsPerSegment(Int_t segmentID); // to be implemented
619 // Ion tail simulation:
620 // 1.) Needs signal from pad+-1, taking signal from history
621 // merge input tree's with summable digits
622 // output stored in TreeTPCD
628 TString optionString = option;
629 if (!strcmp(optionString.Data(),"deb")) {
630 cout<<"AliTPCDigitizer:::DigitizeFast called with option deb "<<endl;
634 // ======== get detector and geometry =======
636 AliRunLoader *rl, *orl;
637 AliLoader *gime, *ogime;
641 Warning("DigitizeFast","gAlice is NULL. Loading from input 0");
642 rl = AliRunLoader::GetRunLoader(fDigInput->GetInputFolderName(0));
645 Error("DigitizeFast","Can not find Run Loader for input 0. Can not proceed.");
651 AliTPC *pTPC = (AliTPC *) gAlice->GetModule("TPC");
652 AliTPCParam * param = pTPC->GetParam();
654 //sprintf(s,param->GetTitle());
655 snprintf(s,100,"%s",param->GetTitle());
656 //sprintf(ss,"75x40_100x60");
657 snprintf(ss,100,"75x40_100x60");
659 printf("2 pad-length geom hits with 3 pad-lenght geom digits...\n");
661 param=new AliTPCParamSR();
663 //sprintf(ss,"75x40_100x60_150x60");
664 snprintf(ss,100,"75x40_100x60_150x60");
665 if(strcmp(s,ss)!=0) {
666 printf("No TPC parameters found...\n");
671 pTPC->GenerNoise(500000); //create table with noise
673 Int_t nInputs = fDigInput->GetNinputs();
674 Int_t * masks = new Int_t[nInputs];
675 for (Int_t i=0; i<nInputs;i++)
676 masks[i]= fDigInput->GetMask(i);
677 Short_t **pdig= new Short_t*[nInputs]; //pointers to the expanded digits array
678 Int_t **ptr= new Int_t*[nInputs]; //pointers to the expanded tracks array
679 Bool_t *active= new Bool_t[nInputs]; //flag for active input segments
682 //create digits array for given sectors
685 //create branch's in TPC treeD
686 orl = AliRunLoader::GetRunLoader(fDigInput->GetOutputFolderName());
687 ogime = orl->GetLoader("TPCLoader");
688 TTree * tree = ogime->TreeD();
689 AliSimDigits * digrow = new AliSimDigits;
693 ogime->MakeTree("D");
694 tree = ogime->TreeD();
696 tree->Branch("Segment","AliSimDigits",&digrow);
698 AliSimDigits ** digarr = new AliSimDigits*[nInputs];
699 for (Int_t i1=0;i1<nInputs; i1++)
703 rl = AliRunLoader::GetRunLoader(fDigInput->GetInputFolderName(i1));
704 gime = rl->GetLoader("TPCLoader");
705 gime->LoadSDigits("read");
706 TTree * treear = gime->TreeS();
710 cerr<<"AliTPCDigitizer: Input tree with SDigits not found in"
711 <<" input "<< i1<<endl;
712 for (Int_t i2=0;i2<i1+1; i2++){
714 if(digarr[i2]) delete digarr[i2];
724 //sprintf(phname,"lhcphase%d",i1);
725 snprintf(phname,100,"lhcphase%d",i1);
726 TParameter<float> *ph = (TParameter<float>*)treear->GetUserInfo()
727 ->FindObject("lhcphase0");
730 cerr<<"AliTPCDigitizer: LHC phase not found in"
731 <<" input "<< i1<<endl;
732 for (Int_t i2=0;i2<i1+1; i2++){
733 if(digarr[i2]) delete digarr[i2];
742 tree->GetUserInfo()->Add(new TParameter<float>(phname,ph->GetVal()));
744 if (treear->GetIndex()==0)
745 treear->BuildIndex("fSegmentID","fSegmentID");
746 treear->GetBranch("Segment")->SetAddress(&digarr[i1]);
753 // zero supp, take gain and noise map of TPC from OCDB
754 param->SetZeroSup(2);
755 Int_t zerosup = param->GetZeroSup();
756 AliTPCCalPad * gainTPC = AliTPCcalibDB::Instance()->GetDedxGainFactor();
757 AliTPCCalPad * noiseTPC = AliTPCcalibDB::Instance()->GetPadNoise();
761 // Cache the ion tail objects form OCDB
764 TObjArray timeResFunc(nROCs);
765 for (Int_t isec = 0;isec<nROCs;isec++){ //loop overs sectors
767 // Array of TGraphErrors for a given sector
768 TGraphErrors ** graphRes = new TGraphErrors *[20];
769 Float_t * indexAmpGraphs = new Float_t[20];
770 for (Int_t icache=0; icache<20; icache++)
772 graphRes[icache] = NULL;
773 indexAmpGraphs[icache] = 0;
775 ///////////////////////////// --> position fo sie loop
776 if (!AliTPCcalibDB::Instance()->GetTailcancelationGraphs(isec,graphRes,indexAmpGraphs)) continue;
778 // fill all TGraphErrors of trfs of a given sector to a TObjArray
779 TObjArray *timeResArr = new TObjArray(20); timeResArr -> SetOwner(kTRUE);
780 for (Int_t ires = 0;ires<20;ires++) timeResArr->AddAt(graphRes[ires],ires);
782 // Fill all trfs into a single TObjArray
783 timeResFunc.AddAt(timeResArr,isec);
790 // 1.) Make first loop to calculate mean amplitude per pad per segment for cross talk
793 TObjArray crossTalkSignalArray(nROCs); // for 36 sectors
794 TVectorD * qTotSectorOld = new TVectorD(nROCs);
795 TVectorD * qTotSectorNew = new TVectorD(nROCs);
796 Float_t qTotTPC = 0.;
797 Int_t nTimeBinsAll = 1100;
798 Int_t nWireSegments=11;
799 // 1.a) crorstalk matrix initialization
800 for (Int_t sector=0; sector<nROCs; sector++){
801 TMatrixD *pcrossTalkSignal = new TMatrixD(nWireSegments,nTimeBinsAll);
802 for (Int_t imatrix = 0; imatrix<11; imatrix++)
803 for (Int_t jmatrix = 0; jmatrix<nTimeBinsAll; jmatrix++){
804 (*pcrossTalkSignal)[imatrix][jmatrix]=0.;
806 crossTalkSignalArray.AddAt(pcrossTalkSignal,sector);
809 // main loop over rows of whole TPC
810 for (Int_t globalRowID=0; globalRowID<param->GetNRowsTotal(); globalRowID++) {
811 Int_t sector, padRow;
812 if (!param->AdjustSectorRow(globalRowID,sector,padRow)) {
813 cerr<<"AliTPC warning: invalid segment ID ! "<<globalRowID<<endl;
816 // Calculate number of pads in a anode wire segment for normalization
817 Int_t anodeSegmentID = param->GetWireSegment(sector,padRow);
818 Int_t nPadsPerSegment = param->GetNPadsPerSegment(anodeSegmentID);
819 // structure with mean signal per pad to be filled for each timebin in first loop (11 anodeWireSegment and 1100 timebin)
820 TMatrixD &crossTalkSignal = *((TMatrixD*)crossTalkSignalArray.At(sector));
821 AliTPCCalROC * gainROC = gainTPC->GetCalROC(sector); // pad gains per given sector
822 digrow->SetID(globalRowID);
825 Bool_t digitize = kFALSE;
826 for (Int_t i=0;i<nInputs; i++){ //here we can have more than one input - merging of separate events, signal1+signal2+background
827 rl = AliRunLoader::GetRunLoader(fDigInput->GetInputFolderName(i));
828 gime = rl->GetLoader("TPCLoader");
829 if (gime->TreeS()->GetEntryWithIndex(globalRowID,globalRowID) >= 0) {
830 digarr[i]->ExpandBuffer();
831 digarr[i]->ExpandTrackBuffer();
832 nTimeBins = digarr[i]->GetNRows();
833 nPads = digarr[i]->GetNCols();
835 if (!GetRegionOfInterest() || (i == 0)) digitize = kTRUE;
839 if (GetRegionOfInterest() && !digitize) break;
841 if (!digitize) continue;
842 digrow->Allocate(nTimeBins,nPads);
844 Int_t label[1000]; //stack for 300 events
846 Int_t nElems = nTimeBins*nPads; // element is a unit of a given row's pad-timebin space
847 for (Int_t i=0;i<nInputs; i++)
849 pdig[i] = digarr[i]->GetDigits();
851 // loop over elements i.e pad-timebin space of a row
852 // padNumber=elem/nTimeBins
853 // timeBin=elem%nTimeBins
854 for (Int_t elem=0;elem<nElems; elem++) {
858 for (Int_t i=0;i<nInputs; i++) if (active[i]) {
862 Int_t padNumber = elem/nTimeBins;
863 Int_t timeBin = elem%nTimeBins;
864 q/=16.; //conversion factor
865 Float_t gain = gainROC->GetValue(padRow,padNumber); // get gain for given - pad-row pad
868 crossTalkSignal[anodeSegmentID][timeBin]+= q; // Qtot per segment for a given timebin
869 qTotSectorOld -> GetMatrixArray()[sector] += q; // Qtot for each sector
870 qTotTPC += q; // Qtot for whole TPC
872 } // end of global row loop
876 // 2.) Loop over segments (padrows) of the TPC
878 for (Int_t globalRowID=0; globalRowID<param->GetNRowsTotal(); globalRowID++) {
879 Int_t sector, padRow;
880 if (!param->AdjustSectorRow(globalRowID,sector,padRow)) {
881 cerr<<"AliTPC warning: invalid segment ID ! "<<globalRowID<<endl;
885 AliTPCCalROC * gainROC = gainTPC->GetCalROC(sector); // pad gains per given sector
886 AliTPCCalROC * noiseROC = noiseTPC->GetCalROC(sector); // noise per given sector
887 digrow->SetID(globalRowID);
892 Bool_t digitize = kFALSE;
893 for (Int_t i=0;i<nInputs; i++) {
894 rl = AliRunLoader::GetRunLoader(fDigInput->GetInputFolderName(i));
895 gime = rl->GetLoader("TPCLoader");
897 if (gime->TreeS()->GetEntryWithIndex(globalRowID,globalRowID) >= 0) {
898 digarr[i]->ExpandBuffer();
899 digarr[i]->ExpandTrackBuffer();
900 nTimeBins = digarr[i]->GetNRows();
901 nPads = digarr[i]->GetNCols();
903 if (!GetRegionOfInterest() || (i == 0)) digitize = kTRUE;
907 if (GetRegionOfInterest() && !digitize) break;
909 if (!digitize) continue;
911 digrow->Allocate(nTimeBins,nPads);
912 digrow->AllocateTrack(3);
915 Int_t label[1000]; //stack for 300 events
918 Int_t nElems = nTimeBins*nPads; // element is a unit of a given row's pad-timebin space
920 for (Int_t i=0;i<nInputs; i++)
922 pdig[i] = digarr[i]->GetDigits();
923 ptr[i] = digarr[i]->GetTracks();
926 Short_t *pdig1= digrow->GetDigits();
927 Int_t *ptr1= digrow->GetTracks() ;
930 // loop over elements i.e pad-timebin space of a row
931 for (Int_t elem=0;elem<nElems; elem++)
933 // padNumber=elem/nTimeBins
934 // timeBin=elem%nTimeBins
938 for (Int_t i=0;i<nInputs; i++) if (active[i])
940 // q += digarr[i]->GetDigitFast(rows,col);
943 for (Int_t tr=0;tr<3;tr++)
945 // Int_t lab = digarr[i]->GetTrackIDFast(rows,col,tr);
946 Int_t lab = ptr[i][tr*nElems];
947 if ( (lab > 1) && *(pdig[i])>zerosup)
949 label[labptr]=lab+masks[i];
956 Int_t padNumber=elem/nTimeBins;
958 q/=16.; //conversion factor
959 Float_t gain = gainROC->GetValue(padRow,padNumber); // get gain for given - pad-row pad
961 //printf("problem\n");
964 // Crosstalk correction:
965 // Double_t qCrossTalk=crossTalkSignal(wireSegment,timeBin); // signal matrix from per sector array
968 // Ion tail correction:
969 // padNumber=elem/nTimeBins
970 // timeBin=elem%nTimeBins
971 // elem=padNumber*nTimeBins+timeBin;
972 // lowerElem=elem-nIonTailBins;
973 // if (lowerElem<0) lowerElem=0;
974 // if (lowerElem in previospad) lowerElem = padNumber*nTimeBins;
976 // for (Int_t celem=elem-1; celem>lowerElem; celem--){
977 // Int_t deltaT=elem-celem
981 Float_t noisePad = noiseROC->GetValue(padRow,padNumber);
982 // Float_t noise = gRandom->Gaus(0,param->GetNoise()*param->GetNoiseNormFac());
983 Float_t noise = pTPC->GetNoise();
985 q=TMath::Nint(q); // round to the nearest integer
987 fill infor to check consistency of the data
989 if (AliTPCReconstructor::StreamLevel()==1) {
990 TTreeSRedirector &cstream = *fDebugStreamer;
991 // if (gRandom->Rndm() > 0.999){
992 cstream<<"ionTailXtalk"<<
994 "row=" << qTotArray[icl0] <<
995 "pad=" << qMaxArray[icl0] <<
997 "qsec.=" << nclSector <<
1004 }// dump the results to the debug streamer if in debug mode
1010 if(q >= param->GetADCSat()) q = (Short_t)(param->GetADCSat() - 1);
1011 //digrow->SetDigitFast((Short_t)q,rows,col);
1013 for (Int_t tr=0;tr<3;tr++)
1016 ptr1[tr*nElems] = label[tr];
1025 digrow->GlitchFilter();
1027 digrow->CompresBuffer(1,zerosup);
1028 digrow->CompresTrackBuffer(1);
1030 if (fDebug>0) cerr<<sector<<"\t"<<padRow<<"\n";
1031 } //for (Int_t n=0; n<param->GetNRowsTotal(); n++)
1034 orl = AliRunLoader::GetRunLoader(fDigInput->GetOutputFolderName());
1035 ogime = orl->GetLoader("TPCLoader");
1036 ogime->WriteDigits("OVERWRITE");
1038 //fDigInput->GetTreeDTPC()->Write(0,TObject::kOverwrite);
1041 for (Int_t i1=0;i1<nInputs; i1++) delete digarr[i1];