+ Log("The input data file list from DAQ (run-level) was not found, TOF exiting from Shuttle ");
+ delete fCal;
+ fCal=0x0;
+ return 4;//return error code for failure in retrieving Ref Data
+ }
+ }
+
+
+ //Total files, with cumulative histos
+
+ TList* listTot = GetFileSources(kDAQ, "DELAYS");
+ if (listTot !=0x0 && listTot->GetEntries()!=0)
+ {
+ AliInfo("The following sources produced files with the id DELAYS");
+ listTot->Print();
+ for (Int_t jj=0;jj<listTot->GetEntries();jj++){
+ TObjString * str = dynamic_cast<TObjString*> (listTot->At(jj));
+ if (!str) {
+ AliError("dynamic_cast returned NULL");
+ return 4;
+ }
+ AliInfo(Form("found source %s", str->String().Data()));
+
+ // file with summed histos, to extract calib params
+ TString fileName = GetFile(kDAQ, "DELAYS", str->GetName());
+ if (fileName.Length()>0){
+ AliInfo(Form("Got the file %s, now we can extract some values.", fileName.Data()));
+
+ daqFile = new TFile(fileName.Data(),"READ");
+ if (h2) delete h2;
+ h2 = (TH2S*) daqFile->Get("htoftot");
+ if (!h2){
+ Log("some problems occurred:: No histo retrieved, TOF exiting from Shuttle");
+ delete listTot;
+ delete daqFile;
+ delete fCal;
+ fCal=0x0;
+ return 7; //return error code for histograms not existing/junky
+ }
+ else {
+ static const Int_t kSize=h2->GetNbinsX();
+ static const Int_t kNBins=h2->GetNbinsY();
+ static const Double_t kXBinmin=h2->GetYaxis()->GetBinLowEdge(1);
+ if (kSize != fNChannels){
+ Log(" number of bins along x different from number of pads, found only a subset of the histograms, TOF exiting from Shuttle");
+ delete listTot;
+ delete h2;
+ delete daqFile;
+ delete fCal;
+ fCal=0x0;
+ return 7; //return error code for histograms not existing/junky
+ }
+ Int_t nNotStatistics = 0; // number of channel with not enough statistics
+
+ /* FDR flag set. do not compute delays, use nominal cable delays */
+ if (fFDRFlag) {
+
+ Log(" Not computing delays according to flag set in Config entry in OCDB!");
+ FillWithCosmicCalibration(fCal);
+
+ /* check whether the new calibration is different from the previous one */
+ if (curCal) { /* well, check also whether we have a previous calibration */
+ for (Int_t i = 0; i < fNChannels; i++) {
+ if (fCal->GetDelay(i) != curCal->GetDelay(i)) {
+ updateOCDB = kTRUE;
+ break;
+ }
+ }
+ }
+ else /* otherwise update OCDB */
+ updateOCDB = kTRUE;
+
+ }
+
+ else { // computing delays if not in FDR runs
+
+ updateOCDB = kTRUE; /* always update OCDB when computing delays */
+
+ for (Int_t ich=0;ich<kSize;ich++){
+ /* check whether channel has been read out during current run.
+ * if the status is bad it means it has not been read out.
+ * in this case skip channel in order to not affect the mean */
+ if (fStatus->GetHWStatus(ich) == AliTOFChannelOnlineStatusArray::kTOFHWBad){
+ AliDebug(2,Form(" Channel %i found bad according to FEEmap, (HW status = %i), skipping from delay computing",ich, (Int_t)fStatus->GetHWStatus(ich)));
+ continue;
+ }
+ AliDebug(2,Form(" Channel %i found ok according to FEEmap, starting delay computing",ich));
+ TH1S *h1 = new TH1S("h1","h1",kNBins,kXBinmin-0.5,kNBins*1.+kXBinmin-0.5);
+ for (Int_t ibin=0;ibin<kNBins;ibin++){
+ h1->SetBinContent(ibin+1,h2->GetBinContent(ich+1,ibin+1));
+ }
+ if(h1->Integral()<integralThr) {
+ nNotStatistics++;
+ Log(Form(" Not enough statistics for bin %i, skipping this channel",ich)); // printing message only if not in FDR runs
+ delete h1;
+ h1=0x0;
+ continue;
+ }
+ Bool_t found=kFALSE;
+ Float_t minContent=h1->Integral()*thrPar;
+ Int_t nbinsX = h1->GetNbinsX();
+ Int_t startBin=1;
+ for (Int_t j=1; j<=nbinsX; j++){
+ if ((
+ h1->GetBinContent(j) +
+ h1->GetBinContent(j+1)+
+ h1->GetBinContent(j+2)+
+ h1->GetBinContent(j+3))>minContent){
+ found=kTRUE;
+ startBin=j;
+ break;
+ }
+ }
+ if(!found) AliInfo(Form("WARNING!!! no start of fit found for histo # %i",ich));
+ // Now calculate the mean over the interval.
+ Double_t mean = 0;
+ Double_t sumw2 = 0;
+ Double_t nent = 0;
+ for(Int_t k=0;k<binRangeAve;k++){
+ mean=mean+h1->GetBinCenter(startBin+k)*h1->GetBinContent(startBin+k);
+ nent=nent+h1->GetBinContent(startBin+k);
+ sumw2=sumw2+(h1->GetBinCenter(startBin+k))*(h1->GetBinCenter(startBin+k))*(h1->GetBinContent(startBin+k));
+ }
+ mean= mean/nent; //<x>
+ sumw2=sumw2/nent; //<x^2>
+ Double_t rmsmean= 0;
+ rmsmean = TMath::Sqrt((sumw2-mean*mean)/nent);
+ if (ich<fNChannels) {
+ Float_t delay = mean*AliTOFGeometry::TdcBinWidth()*1.E-3; // delay in ns
+ fCal->SetDelay(ich,delay); // delay in ns
+ AliDebug(2,Form("Setting delay %f (ns) for channel %i",delay,ich));
+ }
+ delete h1;
+ h1=0x0;
+ }
+ }
+ if (nNotStatistics!=0) Log(Form("Too little statistics for %d channels!",nNotStatistics));
+ }
+ delete h2;
+ daqFile->Close();
+ delete daqFile;
+ }
+ else{
+ Log("The Cumulative data file from DAQ does not exist, TOF exiting from Shuttle");
+ delete listTot;
+ delete fCal;
+ fCal=0x0;
+ return 6;//return error code for problems in retrieving DAQ data
+ }
+ }
+ delete listTot;
+ }
+ else{
+ Log("Problem: no list for Cumulative data file from DAQ was found, TOF exiting from Shuttle");
+ delete fCal;
+ fCal=0x0;
+ return 6; //return error code for problems in retrieving DAQ data
+ }
+
+ /* check whether we don't need to update OCDB.
+ * in this case we can return without errors and
+ * the current FEE is stored in the fStatus object. */
+ if (!updateOCDB) {
+ AliInfo("update OCDB flag not set. Do not overwrite stored file.");
+ return 0; /* return ok */
+ }
+
+ daqFile=0;
+ AliCDBMetaData metaData;
+ metaData.SetBeamPeriod(0);
+ metaData.SetResponsible("Chiara Zampolli");
+ metaData.SetComment("This preprocessor fills an AliTOFChannelOnlineArray object for online calibration - delays.");
+ AliInfo("Storing Calibration Data");
+ resultTOFPP = Store("Calib","ParOnlineDelay",fCal, &metaData,deltaStartingRun,kTRUE);
+ if(!resultTOFPP){
+ Log("Some problems occurred while storing online object resulting from DAQ data processing");
+ delete fCal;
+ fCal=0x0;
+ return 8;//return error code for problems in storing DAQ data
+ }
+
+ if (fCal){
+ delete fCal;
+ fCal = 0;
+ }
+
+ return 0;
+}
+
+//_____________________________________________________________________________
+
+UInt_t
+AliTOFPreprocessor::ProcessT0Fill()
+{
+ // Processing data from DAQ for T0-fill measurement
+
+ Log("Processing T0-fill");
+
+#if 0
+ /* instance and setup CDB manager */
+ AliCDBManager *cdb = AliCDBManager::Instance();
+ /* load geometry */
+ if (!gGeoManager) AliGeomManager::LoadGeometry();
+#endif
+
+ /* get params from OCDB */
+ AliCDBEntry *cdbe = NULL;
+
+ /*
+ * at this stage status object is not on OCDB yet
+ * since it will be stored later. nevertheless we
+ * should have the array in memory since it has been
+ * already setup by ProcessFEF.
+ */
+
+ /* check status and latency window available */
+ if (!fStatus || !fLatencyWindow){
+ AliError("No valid fStatus or fLatencyWindow found, some errors must have occurred!!");
+ return 21;
+ }
+
+ /* get offline calibration from OCDB */
+ cdbe = GetFromOCDB("Calib", "ParOffline");
+ if (!cdbe) {
+ Log("cannot get \"ParOffline\" entry from OCDB");
+ return 21;
+ }
+ TObjArray *offlineArray = (TObjArray *)cdbe->GetObject();
+ AliTOFChannelOffline *channelOffline;
+ if (!offlineArray) {
+ Log("cannot get \"ParOffline\" object from CDB entry");
+ return 21;
+ }
+ Log("got \"ParOffline\" object");
+
+ /* get deltaBC offset from OCDB */
+ cdbe = GetFromOCDB("Calib", "DeltaBCOffset");
+ if (!cdbe) {
+ Log("cannot get \"DeltaBCOffset\" entry from OCDB");
+ return 21;
+ }
+ AliTOFDeltaBCOffset *deltaBCOffsetObject = (AliTOFDeltaBCOffset *)cdbe->GetObject();
+ if (!deltaBCOffsetObject) {
+ Log("cannot get \"DeltaBCOffset\" object from CDB entry");
+ return 21;
+ }
+ Int_t deltaBCOffset = deltaBCOffsetObject->GetDeltaBCOffset();
+ Log(Form("got \"DeltaBCOffset\" object: deltaBCOffset=%d (BC bins)", deltaBCOffset));
+
+ /* get CTP latency from OCDB */
+ cdbe = GetFromOCDB("Calib", "CTPLatency");
+ if (!cdbe) {
+ Log("cannot get \"CTPLatency\" entry from OCDB");
+ return 21;
+ }
+ AliTOFCTPLatency *ctpLatencyObject = (AliTOFCTPLatency *)cdbe->GetObject();
+ if (!ctpLatencyObject) {
+ Log("cannot get \"CTPLatency\" object from CDB entry");
+ return 21;
+ }
+ Float_t ctpLatency = ctpLatencyObject->GetCTPLatency();
+ Log(Form("got \"CTPLatency\" object: ctpLatency=%f (ps)", ctpLatency));
+
+ /* get file sources from FXS */
+ TList *fileList = GetFileSources(kDAQ, "HITS");
+ if (!fileList || fileList->GetEntries() == 0) {
+ Log("cannot get DAQ source file list or empty list");
+ return 21;
+ }
+ Log(Form("got DAQ source file list: %d files", fileList->GetEntries()));
+ fileList->Print();
+
+ /* create tree chain using file sources */
+ TChain chain("hitTree");
+ for (Int_t ifile = 0; ifile < fileList->GetEntries(); ifile++) {
+ TObjString *str = (TObjString *)fileList->At(ifile);
+ TString filename = GetFile(kDAQ, "HITS", str->GetName());
+ chain.Add(filename);
+ Log(Form("file added to input chain: source=%s, filename=%s", str->String().Data(), filename.Data()));
+ }
+ Int_t nhits = chain.GetEntries();
+ Log(Form("input chain ready: %d hits", nhits));
+
+ /* setup input chain */
+ AliTOFHitField *hit = new AliTOFHitField();
+ chain.SetBranchAddress("hit", &hit);
+
+ /* create calib histo and geometry */
+ AliTOFcalibHisto calibHisto;
+ calibHisto.LoadCalibHisto();
+ AliTOFGeometry tofGeo;
+
+ /* constants */
+ Float_t c = TMath::C() * 1.e2 / 1.e12; /* cm/ps */
+ Float_t c_1 = 1. / c;
+ /* variables */
+ Int_t index, timebin, totbin, deltaBC, l0l1latency, det[5];
+ Float_t timeps, totns, corrps, length, timeexp, timezero, pos[3], latencyWindow;
+
+ /* histos */
+ TH1F *hT0Fill = new TH1F("hT0Fill", "T0 fill;t - t_{exp}^{(c)} (ps);", 2000, -24400., 24400.);
+
+ /* loop over hits */
+ for (Int_t ihit = 0; ihit < nhits; ihit++) {
+
+ /* get entry */
+ chain.GetEntry(ihit);
+
+ /* get hit info */
+ index = hit->GetIndex();
+ timebin = hit->GetTimeBin();
+ totbin = hit->GetTOTBin();
+ deltaBC = hit->GetDeltaBC();
+ l0l1latency = hit->GetL0L1Latency();
+ latencyWindow = fLatencyWindow[index] * 1.e3;
+
+ /* convert time in ps and tot in ns */
+ timeps = timebin * AliTOFGeometry::TdcBinWidth();
+ totns = totbin * AliTOFGeometry::ToTBinWidth() * 1.e-3;
+ /* get calibration correction in ps */
+
+
+ channelOffline = (AliTOFChannelOffline *)offlineArray->At(index);
+ if (totns < AliTOFGeometry::SlewTOTMin()) totns = AliTOFGeometry::SlewTOTMin();
+ if (totns > AliTOFGeometry::SlewTOTMax()) totns = AliTOFGeometry::SlewTOTMax();
+ corrps = 0.;
+ for (Int_t ipar = 0; ipar < 6; ipar++) corrps += channelOffline->GetSlewPar(ipar) * TMath::Power(totns, ipar);
+ corrps *= 1.e3;
+ /* perform time correction */
+ // timeps = timeps + (deltaBC - deltaBCOffset) * AliTOFGeometry::BunchCrossingBinWidth() + l0l1latency * AliTOFGeometry::BunchCrossingBinWidth() + ctpLatency - latencyWindow - corrps; /* deltaBC correction removed for the time being */
+ timeps = timeps + l0l1latency * AliTOFGeometry::BunchCrossingBinWidth() + ctpLatency - latencyWindow - corrps;
+ /* compute length and expected time */
+ tofGeo.GetVolumeIndices(index, det);
+ tofGeo.GetPosPar(det, pos);
+ length = 0.;
+ for (Int_t i = 0; i < 3; i++) length += pos[i] * pos[i];
+ length = TMath::Sqrt(length);
+ timeexp = length * c_1;
+ /* compute time zero */
+ timezero = timeps - timeexp;
+
+ /* fill histos */
+ hT0Fill->Fill(timezero);
+ }
+
+ /* rebin until maximum bin has required minimum entries */
+ Int_t maxBin = hT0Fill->GetMaximumBin();
+ Float_t maxBinContent = hT0Fill->GetBinContent(maxBin);
+ Float_t binWidth = hT0Fill->GetBinWidth(maxBin);
+ while (maxBinContent < 400 && binWidth < 90.) {
+ hT0Fill->Rebin(2);
+ maxBin = hT0Fill->GetMaximumBin();
+ maxBinContent = hT0Fill->GetBinContent(maxBin);
+ binWidth = hT0Fill->GetBinWidth(maxBin);
+ }
+ Float_t maxBinCenter = hT0Fill->GetBinCenter(maxBin);
+
+ /* rough fit of the edge */
+ TF1 *gaus = (TF1 *)gROOT->GetFunction("gaus");
+ gaus->SetParameter(1, maxBinCenter);
+ Float_t fitMin = maxBinCenter - 1000.; /* fit from 1 ns before max */
+ Float_t fitMax = maxBinCenter + 1000.; /* fit until 1 ns above max */
+ hT0Fill->Fit("gaus", "q0", "", fitMin, fitMax);
+ /* better fit of the edge */
+ Float_t mean, sigma;
+ for (Int_t istep = 0; istep < 10; istep++) {
+ mean = gaus->GetParameter(1);
+ sigma = gaus->GetParameter(2);
+ fitMin = mean - 3. * sigma;
+ fitMax = mean;
+ hT0Fill->Fit("gaus", "q0", "", fitMin, fitMax);
+ }
+ /* print params */
+ mean = gaus->GetParameter(1);
+ sigma = gaus->GetParameter(2);
+ Float_t meane = gaus->GetParError(1);
+ Float_t sigmae = gaus->GetParError(2);
+ Log(Form("edge fit: mean = %f +- %f ps", mean, meane));
+ Log(Form("edge fit: sigma = %f +- %f ps", sigma, sigmae));
+ /* check error */
+ if (meane > 300.) {
+ Log("error on mean is large: store default T0-fill value (0 ps)");
+ mean = 0.;
+ }
+ if (sigmae > 300.) {
+ Log("error on sigma is large: store default TOFreso value (200 ps)");
+ sigma = 200.;
+ }
+
+ /* scratch values from the fit and use max bin center as t0-fill */
+ mean = maxBinCenter;
+ sigma = -1.;
+ Log(Form("do not care about fitted value, just use max bin as t0-fill: %f ps", mean));
+
+ /* create RunParams object */
+ UInt_t timestamp[1] = {0};
+ Float_t t0[1] = {mean};
+ Float_t tofReso[1] = {sigma};
+ Float_t t0Spread[1] = {-1.};
+ AliTOFRunParams *runParamsObject = new AliTOFRunParams(1);
+ runParamsObject->SetTimestamp(timestamp);
+ runParamsObject->SetT0(t0);
+ runParamsObject->SetTOFResolution(tofReso);
+ runParamsObject->SetT0Spread(t0Spread);
+
+ /* store reference data */
+ if(fStoreRefData){
+ AliCDBMetaData metaDataHisto;
+ metaDataHisto.SetBeamPeriod(0);
+ metaDataHisto.SetResponsible("Roberto Preghenella");
+ metaDataHisto.SetComment("online T0-fill histogram");
+ if (!StoreReferenceData("Calib","T0Fill", hT0Fill, &metaDataHisto)) {
+ Log("error while storing reference data");
+ delete hT0Fill;
+ delete hit;
+ delete runParamsObject;
+ return 21;
+ }
+ Log("reference data successfully stored");
+ }
+
+ AliCDBMetaData metaData;
+ metaData.SetBeamPeriod(0);
+ metaData.SetResponsible("Roberto Preghenella");
+ metaData.SetComment("online RunParams measurement");
+ if (!Store("Calib", "RunParams", runParamsObject, &metaData, 0, kFALSE)) {
+ Log("error while storing RunParams object");
+ delete hT0Fill;
+ delete hit;
+ delete runParamsObject;
+ return 21;
+ }
+ Log("RunParams object successfully stored");
+
+ delete hT0Fill;
+ delete hit;
+ delete runParamsObject;
+ return 0;
+
+}
+
+//_____________________________________________________________________________
+
+UInt_t
+AliTOFPreprocessor::ProcessNoiseCalibTrg()
+{
+ // Processing data from DAQ using calibration triggers for noise measurement
+
+ Log("Processing Noise (calibration trigger)");
+
+ /* check status and matching window available */
+ if (!fStatus || !fMatchingWindow){
+ AliError("No valid fStatus or fMatchingWindow found, some errors must have occurred!!");
+ return 22;
+ }
+
+ Float_t noiseThr = 1000.; // setting default threshold for noise to 1000 Hz
+ // reading config map
+ AliCDBEntry *cdbEntry = GetFromOCDB("Calib","ConfigNoise");
+ if (!cdbEntry) Log(Form("No Configuration entry found in CDB, using default values: NoiseThr = %f",noiseThr));
+ else {
+ TMap *configMap = (TMap*)cdbEntry->GetObject();
+ if (!configMap) Log(Form("No map found in Config entry in CDB, using default values: NoiseThr = %f", noiseThr));
+ else {
+ TObjString *strNoiseThr = (TObjString*)configMap->GetValue("NoiseThr");
+ if (strNoiseThr) {
+ TString tmpstr = strNoiseThr->GetString();
+ noiseThr = tmpstr.Atoi();
+ }
+ else Log(Form("No NoiseThr value found in Map from ConfigNoise entry in CDB, using default value: NoiseThr = %f",noiseThr));
+ }
+ }
+
+ /* get file sources from FXS */
+ TList *fileList = GetFileSources(kDAQ, "CALIB");
+ if (!fileList || fileList->GetEntries() == 0) {
+ Log("cannot get DAQ source file list or empty list");
+ return 22;
+ }
+ Log(Form("got DAQ source file list: %d files", fileList->GetEntries()));
+ fileList->Print();
+
+ /* open input file (only one expected) */
+ TObjString *str = (TObjString *)fileList->At(0);
+ TString filename = GetFile(kDAQ, "CALIB", str->GetName());
+ Log(Form("opening input file: source=%s, filename=%s", str->String().Data(), filename.Data()));
+ TFile *filein = TFile::Open(filename.Data());
+ if (!filein || !filein->IsOpen()) {
+ Log("cannot open input file");
+ return 22;
+ }
+
+ /* get histo from input file */
+ TH1F *hCalibHit = (TH1F *)filein->Get("hCalibHit");
+ if (!hCalibHit) {
+ Log("cannot get \"hCalibHit\" histo");
+ return 22;
+ }
+
+ /* create and set noise rate histo and check rate */
+ TH1F *hNoiseRate = new TH1F("hNoiseRate", ";index;rate (Hz)", fNChannels, 0., fNChannels);
+ Float_t rate, rate_err;
+ for (Int_t ich = 0; ich < fNChannels; ich++) {
+ /* check channel enabled */
+ if (fStatus->GetHWStatus(ich) == AliTOFChannelOnlineStatusArray::kTOFHWBad) continue;
+ /* set noise rate histo */
+ rate = hCalibHit->GetBinContent(ich + 1);
+ rate_err = hCalibHit->GetBinError(ich + 1);
+ rate /= fMatchingWindow[ich] * 1.e-9;
+ rate_err /= fMatchingWindow[ich] * 1.e-9;
+ hNoiseRate->SetBinContent(ich + 1, rate);
+ hNoiseRate->SetBinError(ich + 1, rate_err);
+ /* check error */
+ if (rate_err == 0.) continue;
+ /* check noise rate and set noise flags */
+ if ((rate - 3. * rate_err) > noiseThr) {
+ Log(Form("channel %d detected as noisy: rate = (%f +- %f) Hz", ich, rate, rate_err));
+ if (fStatus->GetNoiseStatus(ich) == AliTOFChannelOnlineStatusArray::kTOFNoiseOk) {
+ Log(Form("channel %d noise status changed from Ok to Bad", ich));
+ fStatus->SetNoiseStatus(ich, AliTOFChannelOnlineStatusArray::kTOFNoiseBad);
+ fIsStatusMapChanged = kTRUE;
+ }
+ else Log(Form("channel %d noise status unchanged", ich));
+ }
+ else if ((rate + 3. * rate_err) < noiseThr) {
+ if (fStatus->GetNoiseStatus(ich) == AliTOFChannelOnlineStatusArray::kTOFNoiseBad) {
+ Log(Form("channel %d noise status changed from Bad to Ok", ich));
+ fStatus->SetNoiseStatus(ich, AliTOFChannelOnlineStatusArray::kTOFNoiseOk);
+ fIsStatusMapChanged = kTRUE;
+ }
+ }
+ }
+
+ /* store reference data */
+ if(fStoreRefData){
+ AliCDBMetaData metaDataHisto;
+ metaDataHisto.SetBeamPeriod(0);
+ metaDataHisto.SetResponsible("Roberto Preghenella");
+ metaDataHisto.SetComment("calibration trigger noise rate histogram");
+ if (!StoreReferenceData("Calib","CalibNoise", hNoiseRate, &metaDataHisto)) {
+ Log("error while storing reference data");
+ delete hNoiseRate;
+ filein->Close();
+ return 22;
+ }
+ Log("reference data successfully stored");
+ }
+
+ delete hNoiseRate;
+ filein->Close();
+ return 0;
+}
+
+//_____________________________________________________________________________
+
+UInt_t
+AliTOFPreprocessor::ProcessReadout()
+{
+ // Processing data from DAQ to compute reaodut efficiency
+
+ Log("Processing Readout");
+
+ /* get file sources from FXS */
+ TList *fileList = GetFileSources(kDAQ, "READOUT");
+ if (!fileList || fileList->GetEntries() == 0) {
+ Log("cannot get DAQ source file list or empty list");
+ return 22;
+ }
+ Log(Form("got DAQ source file list: %d files", fileList->GetEntries()));
+ fileList->Print();
+
+ /* open input file (only one expected) */
+ TObjString *str = (TObjString *)fileList->At(0);
+ TString filename = GetFile(kDAQ, "READOUT", str->GetName());
+ Log(Form("opening input file: source=%s, filename=%s", str->String().Data(), filename.Data()));
+ TFile *filein = TFile::Open(filename.Data());
+ if (!filein || !filein->IsOpen()) {
+ Log("cannot open input file");
+ return 23;
+ }
+
+ /* get histo from input file */
+ TH1F *hChainEfficiency = (TH1F *)filein->Get("hChainEfficiency");
+ if (!hChainEfficiency) {
+ Log("cannot get \"hChainEfficiency\" histo");
+ return 23;
+ }
+
+ /* fill channel efficiency histo */
+
+ /* temporarly disable warnings */
+ AliLog::EType_t logLevel = (AliLog::EType_t)AliLog::GetGlobalLogLevel();
+ AliLog::SetGlobalLogLevel(AliLog::kError);
+
+ TH1F *hChannelEfficiency = new TH1F("hChannelEfficiency", "Channel readout efficiency;index;efficiency", fNChannels, 0., fNChannels);
+ Int_t chainIndex, det[5], dummy, index;
+ Float_t effi, effi_err;
+ /* loop over DDLs */
+ for (Int_t iddl = 0; iddl < 72; iddl++) {
+ /* loop over TRMs */
+ for (Int_t itrm = 0; itrm < 10; itrm++) {
+ /* loop over chains */
+ for (Int_t ichain = 0; ichain < 2; ichain++) {
+ chainIndex = ichain + 2 * itrm + 20 * iddl;
+ effi = hChainEfficiency->GetBinContent(chainIndex + 1);
+ effi_err = hChainEfficiency->GetBinError(chainIndex + 1);
+ /* loop over TDCs */
+ for (Int_t itdc = 0; itdc < 15; itdc++) {
+ /* loop over channels */
+ for (Int_t ichannel = 0; ichannel < 8; ichannel++) {
+
+ /* get channel index */
+ AliTOFRawStream::EquipmentId2VolumeId(iddl, itrm + 3, ichain, itdc, ichannel, det);
+ dummy = det[4];
+ det[4] = det[3];
+ det[3] = dummy;
+ /* check valid index */
+ if (det[0] < 0 || det[0] > 17 ||
+ det[1] < 0 || det[1] > 5 ||
+ det[2] < 0 || det[2] > 18 ||
+ det[3] < 0 || det[3] > 1 ||
+ det[4] < 0 || det[4] > 47) continue;
+ index = AliTOFGeometry::GetIndex(det);
+
+ /* set channel efficiency */
+ hChannelEfficiency->SetBinContent(index + 1, effi);
+ hChannelEfficiency->SetBinError(index + 1, effi_err);
+