+
+Bool_t AliTPCAltroEmulator::WriteEvent(Int_t ievent) {
+ //
+ // Write event to the DDL data folders
+ //
+
+ for (Int_t ddlID=0;ddlID<216;++ddlID) {
+ Bool_t *channelsDDL=fChannels+ddlID*4096 ;
+ Short_t *adcsDDL =fADCs +ddlID*4096*1024;
+ UInt_t *cdhDDL =fCDHs +ddlID*8 ;
+ UInt_t *trailerDDL =fTrailers+ddlID*9 ;
+
+ FILE *file=fopen(Form("%s/raw%d/TPC_%03d.ddl",
+ fDDLFolderName.Data(),ievent,768+ddlID),
+ "wb");
+ if (!file) return kFALSE;
+ Int_t i32;
+ // write CDH (first word to be altered later)
+ for (i32=0;i32<8;++i32)
+ fRawData[i32]=cdhDDL[i32];
+
+ // process payload
+ for (Int_t hwaddr=0;hwaddr<4096;++hwaddr) if (channelsDDL[hwaddr]) {
+ Short_t *adcsChannel=adcsDDL+hwaddr*1024;
+ // merge custers
+ // TODO: acqusition window
+ for (Int_t it=0;it<1024-3;++it) {
+ if (adcsChannel[it]>=0&&adcsChannel[it+3]>=0) {
+ if (adcsChannel[it+1]<0) {
+ // printf("merge");
+ adcsChannel[it+1]=0;
+ }
+ if (adcsChannel[it+2]<0) {
+ // printf("merge");
+ adcsChannel[it+2]=0;
+ }
+ }
+ }
+ Int_t i10=3;
+ Int_t icw=0;
+ Int_t its=1;
+ Int_t cw =0;
+ Int_t ts =0;
+ for (Int_t it=1023;it>=0;--it) {
+ Short_t w10=adcsChannel[it];
+ if (w10>=0) {
+ if (cw<0) {
+ icw=i10++;
+ its=i10++;
+ cw =0 ;
+ ts=it ;
+ }
+ fRawData[i32+i10/3]|=w10<<(10*(2-i10%3));
+ ++i10;
+ ++cw;
+ }
+ else {
+ if (cw>=0) {
+ cw+=2;
+ fRawData[i32+icw/3]|=cw <<(10*(2-icw%3));
+ fRawData[i32+its/3]|=ts <<(10*(2-its%3));
+ cw=-1;
+ }
+ }
+ }
+ fRawData[i32]=0x1<<30|(i10-3)<<16|hwaddr;
+ i32+=(i10+2)/3;
+
+ // clean up
+ for (Int_t i=0;i<1024;++i) adcsChannel[i]=-1;
+ channelsDDL[hwaddr]=kFALSE;
+ }
+
+ // write RCU trailer
+ fRawData[i32]=0x2<<30|(i32-8);i32++;
+ for (Int_t i=0;i<8;++i)
+ fRawData[i32++]=trailerDDL[i];
+
+ // write first word of CDH
+ fRawData[0]=i32*4;
+
+ Int_t nwritten=fwrite(fRawData,sizeof(UInt_t),i32,file);
+ if (nwritten!=i32) return kFALSE;
+
+ // clean up
+ do {fRawData[--i32]=0;} while (i32>0);
+
+ fclose(file);
+ }
+ return kTRUE;
+}
+
+Bool_t AliTPCAltroEmulator::GDC2DDLs(AliRawVEvent *gdc,Int_t ievent) {
+ //
+ // Converte GDC data to DDL format
+ //
+ for(Int_t iLDC=0;iLDC<gdc->GetNSubEvents();++iLDC) {
+ AliRawVEvent *ldc=gdc->GetSubEvent(iLDC);
+ for(Int_t iEq=0;iEq<ldc->GetNEquipments();++iEq) {
+ AliRawVEquipment *eq=ldc->GetEquipment(iEq);
+ AliRawEquipmentHeader *eqHeader=eq->GetEquipmentHeader();
+ Int_t eqSize=eqHeader->GetEquipmentSize();
+ if (eqSize>0) {
+ Int_t ddlIndex;
+ Int_t detId=AliDAQ::DetectorIDFromDdlID(eqHeader->GetId(),ddlIndex);
+ Int_t nwritten=0;
+ FILE *ddlFile=fopen(Form("%s/raw%d/%s",
+ fDDLFolderName.Data(),
+ ievent,
+ AliDAQ::DdlFileName(detId,ddlIndex)),
+ "wb");
+ AliRawData *rawData=eq->GetRawData();
+ if (ddlFile) {
+ nwritten=fwrite(rawData->GetBuffer(),1,rawData->GetSize(),ddlFile);
+ fclose(ddlFile);
+ }
+ if (nwritten<rawData->GetSize()) return kFALSE;
+ }
+ }
+ }
+ return kTRUE;
+}
+
+
+Bool_t AliTPCAltroEmulator::ConvertRawFilesToDate(Int_t nevents) {
+ //
+ // Convertes Raw files to Date format
+ //
+
+ // from $ALICE_ROOT/STEER/AliSimulation.cxx
+
+ char command[100];
+ FILE *pipe;
+ if (fReader->GetRunNumber()>0)
+ pipe=gSystem->OpenPipe(Form("dateStream -c -s -D -o %s -C -# %d -run %d",
+ fOutputDateFileName.Data(),
+ nevents,
+ fReader->GetRunNumber()),
+ "w");
+ else
+ pipe=gSystem->OpenPipe(Form("dateStream -c -s -D -o %s -C -# %d",
+ fOutputDateFileName.Data(),
+ nevents),
+ "w");
+ if (!pipe) {
+ fprintf(stderr,"error: cannot execute command: %s",command);
+ return kFALSE;
+ }
+
+ for (Int_t ievent=0;ievent<nevents;++ievent) {
+ UInt_t detectorPattern = 0xFFFFFFFF;
+ fprintf(pipe, "GDC DetectorPattern %u\n", detectorPattern);
+
+ Float_t ldc = 0;
+ Int_t prevLDC = -1;
+
+ // loop over detectors and DDLs
+ for (Int_t iDet = 0; iDet < AliDAQ::kNDetectors; iDet++) {
+ if (!(iDet<=5 || iDet==17 )) continue;
+ for (Int_t iDDL = 0; iDDL < AliDAQ::NumberOfDdls(iDet); iDDL++) {
+ // printf("iDet=%d, iDDL=%d, filenmae=%s\n",iDet,iDDL,filename);
+ Int_t ddlID = AliDAQ::DdlID(iDet,iDDL);
+ Int_t ldcID = Int_t(ldc + 0.0001);
+ ldc += AliDAQ::NumberOfLdcs(iDet) / AliDAQ::NumberOfDdls(iDet);
+
+ // check existence and size of raw data file
+ FILE* file = fopen(Form("%s/raw%d/%s",
+ fDDLFolderName.Data(),
+ ievent,
+ AliDAQ::DdlFileName(iDet,iDDL)),
+ "rb");
+ if (!file) continue;
+ fseek(file, 0, SEEK_END);
+ unsigned long size = ftell(file);
+ fclose(file);
+ if (!size) continue;
+
+ if (ldcID != prevLDC) {
+ fprintf(pipe, " LDC Id %d\n", ldcID);
+ prevLDC = ldcID;
+ }
+ fprintf(pipe,Form(" Equipment Id %d Payload %s/raw%d/%s\n",
+ ddlID,
+ fDDLFolderName.Data(),
+ ievent,
+ AliDAQ::DdlFileName(iDet,iDDL))
+ );
+ }
+ }
+ }
+ Int_t result = gSystem->ClosePipe(pipe);
+ return (result == 0);
+}
+
+void AliTPCAltroEmulator::InitBuffers() {
+ //
+ // Initialization of the Buffers
+ //
+ if (!fChannels) fChannels=new Bool_t [216*4096 ];
+ if (!fCDHs ) fCDHs =new UInt_t [216*8 ];
+ if (!fADCs ) fADCs =new Short_t[216*4096*1024];
+ if (!fTrailers) fTrailers=new UInt_t [216*9 ];
+ if (!fRawData ) fRawData =new UInt_t [ 1*4096*1024]; // be save...
+
+ for (Int_t i=0;i<216*4096 ;++i) fChannels[i]=kFALSE;
+ // no need to init CDHs
+ for (Int_t i=0;i<216*4096*1024;++i) fADCs [i]=-1 ;
+ // no need to init trailers
+ for (Int_t i=0;i< 1*4096*1024;++i) fRawData [i]= 0 ;
+}
+
+Bool_t AliTPCAltroEmulator::ConvertDateToRoot() {
+ //
+ // convert a DATE file to a root file with the program "alimdc"
+ //
+
+ // from $ALICE_ROOT/STEER/AliSimulation.cxx
+
+ // ALIMDC setup
+ const Int_t kDBSize = 2000000000; //2GB
+ const Int_t kTagDBSize = 1000000000;
+ const Bool_t kFilter = kFALSE;
+ const Int_t kCompression = 1;
+
+ // AliInfo(Form("converting DATE file %s to root file %s",
+ // dateFileName, rootFileName));
+
+ const char* rawDBFS[2] = { "/tmp/mdc1", "/tmp/mdc2" };
+ const char* tagDBFS = "/tmp/mdc1/tags";
+
+ // User defined file system locations
+ if (gSystem->Getenv("ALIMDC_RAWDB1"))
+ rawDBFS[0] = gSystem->Getenv("ALIMDC_RAWDB1");
+ if (gSystem->Getenv("ALIMDC_RAWDB2"))
+ rawDBFS[1] = gSystem->Getenv("ALIMDC_RAWDB2");
+ if (gSystem->Getenv("ALIMDC_TAGDB"))
+ tagDBFS = gSystem->Getenv("ALIMDC_TAGDB");
+
+ gSystem->Exec(Form("rm -rf %s",rawDBFS[0]));
+ gSystem->Exec(Form("rm -rf %s",rawDBFS[1]));
+ gSystem->Exec(Form("rm -rf %s",tagDBFS));
+
+ gSystem->Exec(Form("mkdir %s",rawDBFS[0]));
+ gSystem->Exec(Form("mkdir %s",rawDBFS[1]));
+ gSystem->Exec(Form("mkdir %s",tagDBFS));
+
+ Int_t result = gSystem->Exec(Form("alimdc %d %d %d %d %s",
+ kDBSize, kTagDBSize, kFilter, kCompression, fOutputDateFileName.Data()));
+ gSystem->Exec(Form("mv %s/*.root %s", rawDBFS[0],fOutputRootFileName.Data()));
+
+ gSystem->Exec(Form("rm -rf %s",rawDBFS[0]));
+ gSystem->Exec(Form("rm -rf %s",rawDBFS[1]));
+ gSystem->Exec(Form("rm -rf %s",tagDBFS));
+
+ return (result == 0);
+}
+
+void AliTPCAltroEmulator::RunEmulationOnRAWdata(AliRawReader *reader, Int_t plotFlag) {
+ //
+ // Run the Altro Emulation on a full Raw data set (AliRawReader)
+ // plus write the outcome in a RAW data format
+ //
+
+ if (!reader) {
+ printf("ERROR cant run Altro Emulation: AliRawReader is zero. No RAW data file.\n");
+ return;
+ }
+
+ fReader=reader;
+ if (fDecoder) delete fDecoder;
+ fDecoder=new AliTPCRawStreamV3(reader);
+
+ InitBuffers();
+
+ TH1F hisO("DINO","DINO",1014,0,1014);
+ TH1F his("DIN","DIN",1014,0,1014);
+ TCanvas c1("c1","c1");
+ Int_t chanCount=0;
+ his.GetYaxis()->SetRangeUser(-20,90);
+ Short_t *data = new Short_t[1014];
+
+
+ // event loop
+ Int_t ievent=0;
+ while (fReader->NextEvent()) {
+
+ gSystem->Exec(Form("mkdir -p %s/raw%d/",fDDLFolderName.Data(),ievent));
+ GDC2DDLs(const_cast<AliRawVEvent*>(fReader->GetEvent()),ievent);
+
+ Int_t ddlC =0;
+ while (fDecoder->NextDDL()) {
+ Int_t ddlID=fDecoder->GetDDLNumber();
+ printf("ddl: %d (%d)\n",ddlID,ddlC++);
+
+ Bool_t *channelsDDL=fChannels+ddlID*4096 ;
+ Short_t *adcsDDL =fADCs +ddlID*4096*1024;
+ UInt_t *cdhDDL =fCDHs +ddlID*8 ;
+ UInt_t *trailerDDL =fTrailers+ddlID*9 ;
+
+ // CDH
+ for (Int_t i=0;i<8;++i)
+ // just to show how ugly it is...
+ cdhDDL[i]=reinterpret_cast<UInt_t*>(const_cast<AliRawDataHeader*>(fReader->GetDataHeader()))[i];
+
+ // PAYLOAD
+ while (fDecoder->NextChannel()) {
+ Int_t hwaddr=fDecoder->GetHWAddress();
+ Short_t *adcsChannel=adcsDDL+hwaddr*1024;
+ while (fDecoder->NextBunch()) {
+ UInt_t ts =fDecoder->GetStartTimeBin();
+ Int_t cw =fDecoder->GetBunchLength() ;
+ const UShort_t *signals=fDecoder->GetSignals() ;
+ for (Int_t ci=0;ci<cw;++ci) {
+ Short_t s=signals[ci];
+ Int_t t=ts-ci;
+ // TODO aqcuisition window
+ if (20<=t&&t<=1014) {
+ channelsDDL[hwaddr]=kTRUE;
+ if (adcsChannel[t]<0)
+ adcsChannel[t]=s;
+ else
+ adcsChannel[t]+=s;
+ if (adcsChannel[t]>0x3ff)
+ adcsChannel[t]=0x3ff;
+ }
+ }
+ }
+
+
+ if (1) {
+
+ // search start of aquisition
+ Int_t t0 = 0; while (adcsChannel[t0]==-1) t0++;
+ // search end of aquisition
+ Int_t tE = 1014; while (adcsChannel[tE]==-1) tE--;
+ // printf("S:%d E:%d\n",t0,tE);
+
+ // SR TEST:
+ // channel is complete - Perform Altro Emulation
+ if (plotFlag && !(chanCount%1000)) {
+ for (Int_t t=0; t<1014; t++) {
+ his.SetBinContent(t+1,adcsChannel[t]);
+ }
+ his.SetStats(0); his.GetXaxis()->SetTitle("timebin");
+ his.DrawCopy();
+ }
+ // FEED THE ALTRO EMULATOR WITH CLEAN SIGNAL (not aquisition window ghosts)
+ Int_t timebins = tE-t0;
+
+ for (Int_t t=t0;t<(t0+timebins);t++)
+ data[t-t0]=adcsChannel[t];
+ //SetChannelData(timebins, adcsChannel);//data);
+ SetChannelData(timebins,data);
+ RunEmulation(); // emulation on single channel
+ for (Int_t t=t0;t<(t0+timebins);t++)
+ adcsChannel[t]=data[t-t0];
+
+ // SR TEST:
+ if (plotFlag && !(chanCount%1000) ) {
+ for (Int_t t=0; t<1014; t++)
+ hisO.SetBinContent(t+1,adcsChannel[t]);
+ hisO.SetStats(0); hisO.SetLineColor(2);
+ hisO.DrawCopy("same");
+
+ c1.SaveAs(Form("/tmp/chanCount_%07d.png",chanCount));
+
+ his.Reset();
+ hisO.Reset();
+
+ }
+ chanCount++;
+ }
+
+ }
+
+ // TRAILER
+ UChar_t *rcuTrailer;
+ fDecoder->GetRCUTrailerData(rcuTrailer);
+ for (Int_t i=0;i<= /* (!) */ fDecoder->GetRCUTrailerSize()/4;++i)
+ trailerDDL[i]=reinterpret_cast<UInt_t*>(rcuTrailer)[i]; // again: UGLY!
+
+ }
+
+ WriteEvent(ievent++);
+ }
+
+ delete data; // free space
+
+ // convert to date and back
+ ConvertRawFilesToDate(ievent);
+ ConvertDateToRoot();
+
+
+}