+ const Int_t nTowersPerSM = AliEMCALGeoParams::fgkEMCALRows * AliEMCALGeoParams::fgkEMCALCols; // number of towers in a SuperModule; 24x48
+ const Int_t nRows = AliEMCALGeoParams::fgkEMCALRows; // number of rows per SuperModule
+ const Int_t nStripsPerSM = AliEMCALGeoParams::fgkEMCALLEDRefs; // number of strips per SuperModule
+ const Int_t n2x2PerSM = AliEMCALGeoParams::fgkEMCALTRUsPerSM * AliEMCALGeoParams::fgkEMCAL2x2PerTRU; // number of TRU 2x2's per SuperModule
+ const Int_t n2x2PerTRU = AliEMCALGeoParams::fgkEMCAL2x2PerTRU;
+ const Int_t nTot2x2 = fSuperModules * n2x2PerSM; // total TRU channel
+
+ // SM counters; decl. should be safe, assuming we don't get more than expected SuperModules..
+ Int_t nTotalSMLG[AliEMCALGeoParams::fgkEMCALModules] = {0};
+ Int_t nTotalSMHG[AliEMCALGeoParams::fgkEMCALModules] = {0};
+ Int_t nTotalSMTRU[AliEMCALGeoParams::fgkEMCALModules] = {0};
+ Int_t nTotalSMLGLEDMon[AliEMCALGeoParams::fgkEMCALModules] = {0};
+ Int_t nTotalSMHGLEDMon[AliEMCALGeoParams::fgkEMCALModules] = {0};
+
+ const Int_t nTRUL0ChannelBits = 10; // used for L0 trigger bits checks
+ int firstL0TimeBin = 999;
+ int triggers[nTot2x2][24]; //auxiliary array for L0 trigger - TODO remove hardcoded 24
+ memset(triggers, 0, sizeof(int) * 24 * nTot2x2);
+
+ Int_t iSM = 0; // SuperModule index
+ // start loop over input stream
+ while (in.NextDDL()) {
+ Int_t iRCU = in.GetDDLNumber() % 2; // RCU0 or RCU1, within SuperModule
+ Int_t iDDL = in.GetDDLNumber();
+ fRawAnalyzer->SetIsZeroSuppressed( in.GetZeroSupp() );
+
+ while (in.NextChannel()) {
+ Int_t iBranch = in.GetBranch();
+
+ iSM = in.GetModule(); // SuperModule
+ //prInt_tf("iSM %d DDL %d", iSM, in.GetDDLNumber());
+ if (iSM>=0 && iSM<fSuperModules) { // valid module reading
+
+ Int_t nsamples = 0;
+ vector<AliCaloBunchInfo> bunchlist;
+ while (in.NextBunch()) {
+ nsamples += in.GetBunchLength();
+ bunchlist.push_back( AliCaloBunchInfo(in.GetStartTimeBin(), in.GetBunchLength(), in.GetSignals() ) );
+ }
+
+ if (nsamples > 0) { // this check is needed for when we have zero-supp. on, but not sparse readout
+ Float_t time = 0.;
+ Float_t amp = 0.;
+ // indices for pedestal calc.
+ Int_t firstPedSample = 0;
+ Int_t lastPedSample = 0;
+ bool isTRUL0IdData = false;
+
+ if (! in.IsTRUData() ) { // high gain, low gain, LED Mon data - all have the same shaper/sampling
+ AliCaloFitResults fitResults = fRawAnalyzer->Evaluate( bunchlist, in.GetAltroCFG1(), in.GetAltroCFG2());
+ amp = fitResults.GetAmp();
+ time = fitResults.GetTof();
+ firstPedSample = fFirstPedestalSample;
+ lastPedSample = fLastPedestalSample;
+ }
+ else { // TRU data is special, needs its own analyzer
+ AliCaloFitResults fitResults = fRawAnalyzerTRU->Evaluate( bunchlist, in.GetAltroCFG1(), in.GetAltroCFG2());
+ amp = fitResults.GetAmp();
+ time = fitResults.GetTof();
+ firstPedSample = fFirstPedestalSampleTRU;
+ lastPedSample = fLastPedestalSampleTRU;
+ if (in.GetColumn() >= n2x2PerTRU) {
+ isTRUL0IdData = true;
+ }
+ }
+
+ // pedestal samples
+ Int_t nPed = 0;
+ vector<Int_t> pedSamples;
+
+ // select earliest bunch
+ unsigned int bunchIndex = 0;
+ unsigned int startBin = bunchlist.at(0).GetStartBin();
+ if (bunchlist.size() > 0) {
+ for(unsigned int ui=1; ui < bunchlist.size(); ui++ ) {
+ if (startBin > bunchlist.at(ui).GetStartBin() ) {
+ startBin = bunchlist.at(ui).GetStartBin();
+ bunchIndex = ui;
+ }
+ }
+ }
+
+ // check bunch for entries in the pedestal sample range
+ Int_t bunchLength = bunchlist.at(bunchIndex).GetLength();
+ const UShort_t *sig = bunchlist.at(bunchIndex).GetData();
+ Int_t timebin = 0;
+
+ if (! isTRUL0IdData) { // regular data, can look at pedestals
+ for (Int_t i = 0; i<bunchLength; i++) {
+ timebin = startBin--;
+ if ( firstPedSample<=timebin && timebin<=lastPedSample ) {
+ pedSamples.push_back( sig[i] );
+ nPed++;
+ }
+ } // i
+ }
+ else { // TRU L0 Id Data
+ // which TRU the channel belongs to?
+ Int_t iTRUId = in.GetModule()*3 + (iRCU*in.GetBranch() + iRCU);
+
+ for (Int_t i = 0; i< bunchLength; i++) {
+ for( Int_t j = 0; j < nTRUL0ChannelBits; j++ ){
+ // check if the bit j is 1
+ if( (sig[i] & ( 1 << j )) > 0 ){
+ Int_t iTRUIdInSM = (in.GetColumn() - n2x2PerTRU)*nTRUL0ChannelBits+j;
+ if(iTRUIdInSM < n2x2PerTRU) {
+ Int_t iTRUAbsId = iTRUIdInSM + n2x2PerTRU * iTRUId;
+ // Fill the histograms
+ Int_t globTRUCol, globTRURow;
+ GetTruChannelPosition(globTRURow, globTRUCol, iSM, iDDL, iBranch, iTRUIdInSM );
+
+ FillRawsData(kNL0TRU, globTRUCol, globTRURow);
+ FillRawsData(kTimeL0TRU, globTRUCol, globTRURow, startBin);
+ triggers[iTRUAbsId][startBin] = 1;
+
+ if((int)startBin < firstL0TimeBin) firstL0TimeBin = startBin;
+ }
+ }
+ }
+ startBin--;
+ } // i
+ } // TRU L0 Id data
+
+ // fill histograms
+ if ( in.IsLowGain() || in.IsHighGain() ) { // regular towers
+ Int_t towerId = iSM*nTowersPerSM + in.GetColumn()*nRows + in.GetRow();
+ if ( in.IsLowGain() ) {
+ nTotalSMLG[iSM]++;
+ if ( (amp > fMinSignalLG) && (amp < fMaxSignalLG) ) {
+ FillRawsData(kSigLG,towerId, amp);
+ FillRawsData(kTimeLG,towerId, time);
+ }
+ if (nPed > 0) {
+ for (Int_t i=0; i<nPed; i++) {
+ FillRawsData(kPedLG,towerId, pedSamples[i]);
+ }
+ }
+ } // gain==0
+ else if ( in.IsHighGain() ) {
+ nTotalSMHG[iSM]++;
+ if ( (amp > fMinSignalHG) && (amp < fMaxSignalHG) ) {
+ FillRawsData(kSigHG,towerId, amp);
+ FillRawsData(kTimeHG,towerId, time);
+ }
+ if (nPed > 0) {
+ for (Int_t i=0; i<nPed; i++) {
+ FillRawsData(kPedHG,towerId, pedSamples[i]);
+ }
+ }
+ } // gain==1
+ } // low or high gain
+ // TRU
+ else if ( in.IsTRUData() && in.GetColumn()<AliEMCALGeoParams::fgkEMCAL2x2PerTRU) {
+ // for TRU data, the mapping class holds the TRU Int_ternal 2x2 number (0..95) in the Column var..
+ Int_t iTRU = (iRCU*in.GetBranch() + iRCU); //TRU0 is from RCU0, TRU1 from RCU1, TRU2 is from branch B on RCU1
+ Int_t iTRU2x2Id = iSM*n2x2PerSM + iTRU*AliEMCALGeoParams::fgkEMCAL2x2PerTRU
+ + in.GetColumn();
+ nTotalSMTRU[iSM]++;
+ if ( (amp > fMinSignalTRU) && (amp < fMaxSignalTRU) ) {
+ FillRawsData(kSigTRU,iTRU2x2Id, amp);
+ //FillRawsData(kTimeTRU,iTRU2x2Id, time);
+ }
+ //if (nPed > 0) {
+ //for (Int_t i=0; i<nPed; i++) {
+ //FillRawsData(kPedTRU,iTRU2x2Id, pedSamples[i]);
+ //}
+ //}
+ }
+ // LED Mon
+ else if ( in.IsLEDMonData() ) {
+ // for LED Mon data, the mapping class holds the gain info in the Row variable
+ // and the Strip number in the Column..
+ Int_t gain = in.GetRow();
+ Int_t stripId = iSM*nStripsPerSM + in.GetColumn();
+
+ if ( gain == 0 ) {
+ nTotalSMLGLEDMon[iSM]++;
+ if ( (amp > fMinSignalLGLEDMon) && (amp < fMaxSignalLGLEDMon) ) {
+ FillRawsData(kSigLGLEDMon,stripId, amp);
+ FillRawsData(kTimeLGLEDMon,stripId, time);
+ }
+ if (nPed > 0) {
+ for (Int_t i=0; i<nPed; i++) {
+ FillRawsData(kPedLGLEDMon,stripId, pedSamples[i]);
+ }
+ }
+ } // gain==0
+ else if ( gain == 1 ) {
+ nTotalSMHGLEDMon[iSM]++;
+ if ( (amp > fMinSignalHGLEDMon) && (amp < fMaxSignalHGLEDMon) ) {
+ FillRawsData(kSigHGLEDMon,stripId, amp);
+ FillRawsData(kTimeHGLEDMon,stripId, time);
+ }
+ if (nPed > 0) {
+ for (Int_t i=0; i<nPed; i++) {
+ FillRawsData(kPedHGLEDMon,stripId, pedSamples[i]);
+ }
+ }
+ } // low or high gain
+ } // LEDMon
+
+ } // SM index OK
+
+ } // nsamples>0 check, some data found for this channel; not only trailer/header
+ }// end while over channel
+
+ }//end while over DDL's, of input stream
+ //filling some L0 trigger histos
+ if( firstL0TimeBin < 999 ){
+ for(Int_t i = 0; i < nTot2x2; i++) {
+ if( triggers[i][firstL0TimeBin] > 0 ) {
+ //histo->Fill(i,j);
+ FillRawsData(kNL0FirstTRU, i);
+ FillRawsData(kTimeL0FirstTRU, i, firstL0TimeBin);
+ }
+ }
+ }
+
+ //calculate the ratio of the amplitude and fill the histograms, only if the events type is Calib
+ // RS: operation on the group of histos kSigHG,k2DRatioAmp,kRatioDist,kLEDMonRatio,kLEDMonRatio,kSigLGLEDMon
+ const int hGrp[] = {kSigHG,k2DRatioAmp,kRatioDist,kLEDMonRatio,kLEDMonRatioDist,kSigLGLEDMon};
+ if ( rawReader->GetType() == AliRawEventHeaderBase::kCalibrationEvent &&
+ CheckCloningConsistency(fRawsQAList, hGrp, sizeof(hGrp)/sizeof(int)) ) { // RS converting original code to loop over all matching triggers
+ int nTrig =IsClonedPerTrigClass(kSigHG,fRawsQAList) ? GetNEventTrigClasses() : 0; // loop over triggers only if histos were cloned
+ //
+ for (int itr=-1;itr<nTrig;itr++) { // start from -1 to acknowledge original histos if they were kept
+ TObjArray* trArr = GetMatchingRawsHistosSet(hGrp, sizeof(hGrp)/sizeof(int) ,itr);
+ if (!trArr) continue; // no histos for current trigger
+ //
+ Double_t binContent = 0.;
+ TProfile* prSigHG = (TProfile *)trArr->At(0); //kSigHG
+ TH1* th2DRatioAmp = (TH1*) trArr->At(1); //k2DRatioAmp
+ TH1* thRatioDist = (TH1*) trArr->At(2); //kRatioDist
+ TH1* thLEDMonRatio = (TH1*) trArr->At(3); //kLEDMonRatio
+ TH1* thLEDMonRatioDist = (TH1*) trArr->At(4); //kLEDMonRatio
+ TH1* hSigLGLEDMon = (TH1*) trArr->At(5); //kSigLGLEDMon
+ th2DRatioAmp->Reset("ICE");
+ thRatioDist->Reset("ICE");
+ thLEDMonRatio->Reset("ICE");
+ thLEDMonRatioDist->Reset("ICE");
+ th2DRatioAmp->ResetStats();
+ thRatioDist->ResetStats();
+ thLEDMonRatio->ResetStats();
+ thLEDMonRatioDist->ResetStats();
+ ConvertProfile2H(prSigHG, fHighEmcHistoH2F);
+ //
+ for(Int_t ix = 1; ix <= fHighEmcHistoH2F->GetNbinsX(); ix++) {
+ for(Int_t iy = 1; iy <= fHighEmcHistoH2F->GetNbinsY(); iy++) {
+ if(fCalibRefHistoH2F->GetBinContent(ix, iy))
+ binContent = fHighEmcHistoH2F->GetBinContent(ix, iy)/fCalibRefHistoH2F->GetBinContent(ix, iy);
+ th2DRatioAmp->SetBinContent(ix, iy, binContent);
+ thRatioDist->Fill(binContent);
+ }
+ }
+ //
+ //Now for LED monitor system, to calculate the ratio as well
+ Double_t binError = 0. ;
+ // for the binError, we add the relative errors, squared
+ Double_t relativeErrorSqr = 0. ;
+ //
+ for(int ib = 1; ib <= fLEDMonRefHistoPro->GetNbinsX(); ib++) {
+ //
+ if(fLEDMonRefHistoPro->GetBinContent(ib) != 0) {
+ binContent = hSigLGLEDMon->GetBinContent(ib) / fLEDMonRefHistoPro->GetBinContent(ib);
+
+ relativeErrorSqr = TMath::Power( (fLEDMonRefHistoPro->GetBinError(ib) / fLEDMonRefHistoPro->GetBinContent(ib)), 2);
+ if( hSigLGLEDMon->GetBinContent(ib) != 0) {
+ relativeErrorSqr += TMath::Power( (hSigLGLEDMon->GetBinError(ib)/hSigLGLEDMon->GetBinContent(ib)), 2);
+ }
+ }
+ else { // ref. run info is zero
+ binContent = -1;
+ relativeErrorSqr = 1;
+ }
+ thLEDMonRatio->SetBinContent(ib, binContent);
+
+ binError = sqrt(relativeErrorSqr) * binContent;
+ thLEDMonRatio->SetBinError(ib, binError);
+ thLEDMonRatioDist->Fill(thLEDMonRatio->GetBinContent(ib));
+ }
+ } // loop over eventual trigger clones
+ }
+ // let's also fill the SM and event counter histograms
+ Int_t nTotalHG = 0;
+ Int_t nTotalLG = 0;
+ Int_t nTotalTRU = 0;
+ Int_t nTotalHGLEDMon = 0;
+ Int_t nTotalLGLEDMon = 0;
+ for (iSM=0; iSM<fSuperModules; iSM++) {
+ nTotalLG += nTotalSMLG[iSM];
+ nTotalHG += nTotalSMHG[iSM];
+ nTotalTRU += nTotalSMTRU[iSM];
+ nTotalLGLEDMon += nTotalSMLGLEDMon[iSM];
+ nTotalHGLEDMon += nTotalSMHGLEDMon[iSM];
+ FillRawsData(kNsmodLG,iSM, nTotalSMLG[iSM]);
+ FillRawsData(kNsmodHG,iSM, nTotalSMHG[iSM]);
+ FillRawsData(kNsmodTRU,iSM, nTotalSMTRU[iSM]);
+ FillRawsData(kNsmodLGLEDMon,iSM, nTotalSMLGLEDMon[iSM]);
+ FillRawsData(kNsmodHGLEDMon,iSM, nTotalSMHGLEDMon[iSM]);
+ }
+
+ FillRawsData(kNtotLG,nTotalLG);
+ FillRawsData(kNtotHG,nTotalHG);
+ FillRawsData(kNtotTRU,nTotalTRU);
+ FillRawsData(kNtotLGLEDMon,nTotalLGLEDMon);
+ FillRawsData(kNtotHGLEDMon,nTotalHGLEDMon);
+
+ IncEvCountCycleESDs();
+ IncEvCountTotalESDs();
+ SetEventSpecie(saveSpecie) ;
+
+ MakeRawsSTU(rawReader);
+
+ // just in case the next rawreader consumer forgets to reset; let's do it here again..
+ rawReader->Reset() ;
+ return;
+}
+
+//____________________________________________________________________________
+void AliEMCALQADataMakerRec::MakeDigits()
+{
+ // makes data from Digits
+ FillDigitsData(1,fDigitsArray->GetEntriesFast()) ;
+ TIter next(fDigitsArray) ;
+ AliEMCALDigit * digit ;
+ while ( (digit = dynamic_cast<AliEMCALDigit *>(next())) ) {
+ FillDigitsData(0, digit->GetAmplitude()) ;
+ }