X-Git-Url: http://git.uio.no/git/?a=blobdiff_plain;f=TRD%2FAliTRDrawData.cxx;h=bb68aa9022589ac39df274db65f29e077b90e32a;hb=ae1a1b1135e59fc3df98ebb8076897df83de506d;hp=b510e973f550a39a195f7a381b34d63db70c9675;hpb=362c9d61708912a81d77cb017e1d05fd1f9486a6;p=u%2Fmrichter%2FAliRoot.git diff --git a/TRD/AliTRDrawData.cxx b/TRD/AliTRDrawData.cxx index b510e973f55..bb68aa90225 100644 --- a/TRD/AliTRDrawData.cxx +++ b/TRD/AliTRDrawData.cxx @@ -21,40 +21,59 @@ // // /////////////////////////////////////////////////////////////////////////////// -#include +#include +#include "TClass.h" + +#include "AliDAQ.h" +#include "AliRawDataHeaderSim.h" +#include "AliRawReader.h" +#include "AliLog.h" +#include "AliFstream.h" #include "AliTRDrawData.h" #include "AliTRDdigitsManager.h" #include "AliTRDgeometry.h" #include "AliTRDdataArrayI.h" +#include "AliTRDdataArrayS.h" +#include "AliTRDrawStreamBase.h" #include "AliTRDRawStream.h" -#include "AliRawDataHeader.h" -#include "AliRawReader.h" -#include "AliTRDCommonParam.h" +#include "AliTRDRawStreamV2.h" #include "AliTRDcalibDB.h" -#include "AliDAQ.h" +#include "AliTRDSignalIndex.h" +#include "AliTRDfeeParam.h" +#include "AliTRDmcmSim.h" ClassImp(AliTRDrawData) //_____________________________________________________________________________ -AliTRDrawData::AliTRDrawData():TObject() +AliTRDrawData::AliTRDrawData() + :TObject() + ,fGeo(NULL) + ,fFee(NULL) + ,fNumberOfDDLs(0) { // // Default constructor // - fDebug = 0; + fFee = AliTRDfeeParam::Instance(); + fNumberOfDDLs = AliDAQ::NumberOfDdls("TRD"); } //_____________________________________________________________________________ -AliTRDrawData::AliTRDrawData(const AliTRDrawData &r):TObject() +AliTRDrawData::AliTRDrawData(const AliTRDrawData &r) + :TObject(r) + ,fGeo(NULL) + ,fFee(NULL) + ,fNumberOfDDLs(0) { // - // AliTRDrawData copy constructor + // Copy constructor // - ((AliTRDrawData &) r).Copy(*this); + fFee = AliTRDfeeParam::Instance(); + fNumberOfDDLs = AliDAQ::NumberOfDdls("TRD"); } @@ -68,336 +87,717 @@ AliTRDrawData::~AliTRDrawData() } //_____________________________________________________________________________ -AliTRDrawData &AliTRDrawData::operator=(const AliTRDrawData &r) +Bool_t AliTRDrawData::Digits2Raw(TTree *digitsTree, TTree *tracks ) { // - // Assignment operator + // Initialize necessary parameters and call one + // of the raw data simulator selected by SetRawVersion. + // + // Currently tracklet output is not spported yet and it + // will be supported in higher version simulator. // - if (this != &r) ((AliTRDrawData &) r).Copy(*this); - return *this; + AliTRDdigitsManager* digitsManager = new AliTRDdigitsManager(); + + if (!digitsManager->ReadDigits(digitsTree)) { + delete digitsManager; + return kFALSE; + } + + if (tracks != NULL) { + delete digitsManager; + AliError("Tracklet input is not supported yet."); + return kFALSE; + } + + fGeo = new AliTRDgeometry(); + + if (!AliTRDcalibDB::Instance()) { + AliError("Could not get calibration object"); + delete fGeo; + delete digitsManager; + return kFALSE; + } + + Int_t retval = kTRUE; + Int_t rv = fFee->GetRAWversion(); + + // Call appropriate Raw Simulator + if ( rv > 0 && rv <= 3 ) retval = Digits2Raw(digitsManager); + else { + retval = kFALSE; + AliWarning(Form("Unsupported raw version (%d).", rv)); + } + + // Cleanup + delete fGeo; + delete digitsManager; + + return retval; } //_____________________________________________________________________________ -void AliTRDrawData::Copy(TObject &r) const +Bool_t AliTRDrawData::Digits2Raw(AliTRDdigitsManager *digitsManager) { // - // Copy function + // Raw data simulator for all versions > 0. This is prepared for real data. + // This version simulate only raw data with ADC data and not with tracklet. // - ((AliTRDrawData &) r).fDebug = fDebug; + const Int_t kMaxHcWords = (fGeo->TBmax()/3) + * fGeo->ADCmax() + * fGeo->MCMmax() + * fGeo->ROBmaxC1()/2 + + 100 + 20; + + // Buffer to temporary store half chamber data + UInt_t *hcBuffer = new UInt_t[kMaxHcWords]; + + Bool_t newEvent = kFALSE; // only for correct readout tree + + // sect is same as iDDL, so I use only sect here. + for (Int_t sect = 0; sect < fGeo->Nsector(); sect++) { + + char name[1024]; + sprintf(name,"TRD_%d.ddl",sect + AliTRDRawStream::kDDLOffset); + + AliFstream* of = new AliFstream(name); + + // Write a dummy data header + AliRawDataHeaderSim header; // the event header + UInt_t hpos = of->Tellp(); + of->WriteBuffer((char *) (& header), sizeof(header)); + + // Reset payload byte size (payload does not include header). + Int_t npayloadbyte = 0; + + + + // GTU common data header (5x4 bytes per super module, shows link mask) + for( Int_t stack = 0; stack < fGeo->Nstack(); stack++ ) { + UInt_t gtuCdh = (UInt_t)(0xe << 28); + for( Int_t layer = 0; layer < fGeo->Nlayer(); layer++) { + Int_t iDet = fGeo->GetDetector(layer, stack, sect); + + // If chamber status is ok, we assume that the optical link is also OK. + // This is shown in the GTU link mask. + if ( AliTRDcalibDB::Instance()->GetChamberStatus(iDet) ) + gtuCdh = gtuCdh | (3 << (2*layer)); + } + of->WriteBuffer((char *) (& gtuCdh), sizeof(gtuCdh)); + npayloadbyte += 4; + } + + // Prepare chamber data + for( Int_t stack = 0; stack < fGeo->Nstack(); stack++) { + for( Int_t layer = 0; layer < fGeo->Nlayer(); layer++) { + + Int_t iDet = fGeo->GetDetector(layer,stack,sect); + if (iDet == 0) newEvent = kTRUE; // it is expected that each event has at least one tracklet; this is only needed for correct readout tree + // Get the digits array + AliTRDdataArrayS *digits = (AliTRDdataArrayS *) digitsManager->GetDigits(iDet); + if (digits->HasData() ) { // second part is new!! and is for indicating a new event + + digits->Expand(); + + Int_t hcwords = 0; + Int_t rv = fFee->GetRAWversion(); + + // Process A side of the chamber + if ( rv >= 1 && rv <= 2 ) { + hcwords = ProduceHcDataV1andV2(digits,0,iDet,hcBuffer,kMaxHcWords); + } + if ( rv == 3 ) { + + hcwords = ProduceHcDataV3 (digits,0,iDet,hcBuffer,kMaxHcWords,newEvent); + //hcwords = ProduceHcDataV3 (digits,0,iDet,hcBuffer,kMaxHcWords); + if(newEvent == kTRUE) newEvent = kFALSE; + } + + of->WriteBuffer((char *) hcBuffer, hcwords*4); + npayloadbyte += hcwords*4; + + // Process B side of the chamber + if ( rv >= 1 && rv <= 2 ) { + hcwords = ProduceHcDataV1andV2(digits,1,iDet,hcBuffer,kMaxHcWords); + } + if ( rv >= 3 ) { + + hcwords = ProduceHcDataV3 (digits,1,iDet,hcBuffer,kMaxHcWords,newEvent); + //hcwords = ProduceHcDataV3 (digits,1,iDet,hcBuffer,kMaxHcWords); + } + + of->WriteBuffer((char *) hcBuffer, hcwords*4); + npayloadbyte += hcwords*4; + + } + + } + } + + // Complete header + header.fSize = UInt_t(of->Tellp()) - hpos; + header.SetAttribute(0); // Valid data + of->Seekp(hpos); // Rewind to header position + of->WriteBuffer((char *) (& header), sizeof(header)); + delete of; + } + + delete [] hcBuffer; + + return kTRUE; } //_____________________________________________________________________________ -Bool_t AliTRDrawData::Digits2Raw(TTree *digitsTree) +Int_t AliTRDrawData::ProduceHcDataV1andV2(AliTRDdataArrayS *digits, Int_t side + , Int_t det, UInt_t *buf, Int_t maxSize) { // - // Convert the digits to raw data byte stream. The output is written - // into the the binary files TRD_.ddl. - // - // The pseudo raw data format is currently defined like this: + // This function simulates: 1) SM-I commissiong data Oct. 06 (Raw Version == 1). + // 2) Full Raw Production Version (Raw Version == 2) // - // DDL data header + // Produce half chamber data (= an ORI data) for the given chamber (det) and side (side) + // where // - // Subevent (= single chamber) header (8 bytes) - // FLAG - // Detector number (2 bytes) - // Number of data bytes (2 bytes) - // Number of pads with data (2 bytes) - // 1 empty byte + // side=0 means A side with ROB positions 0, 2, 4, 6. + // side=1 means B side with ROB positions 1, 3, 5, 7. // - // Data bank + // Chamber type (C0 orC1) is determined by "det" automatically. + // Appropriate size of buffer (*buf) must be prepared prior to calling this function. + // Pointer to the buffer and its size must be given to "buf" and "maxSize". + // Return value is the number of valid data filled in the buffer in unit of 32 bits + // UInt_t words. + // If buffer size if too small, the data is truncated with the buffer size however + // the function will finish without crash (this behaviour is similar to the MCM). // - const Int_t kNumberOfDDLs = AliDAQ::NumberOfDdls("TRD"); - const Int_t kSubeventHeaderLength = 8; - const Int_t kSubeventDummyFlag = 0xBB; - Int_t headerSubevent[3]; + Int_t nw = 0; // Number of written words + Int_t of = 0; // Number of overflowed words + Int_t layer = fGeo->GetLayer( det ); // Layer + Int_t stack = fGeo->GetStack( det ); // Stack + Int_t sect = fGeo->GetSector( det ); // Sector (=iDDL) + Int_t nRow = fGeo->GetRowMax( layer, stack, sect ); + Int_t nCol = fGeo->GetColMax( layer ); + const Int_t kNTBin = AliTRDcalibDB::Instance()->GetNumberOfTimeBins(); + Int_t kCtype = 0; // Chamber type (0:C0, 1:C1) + Int_t iEv = 0xA; // Event ID. Now fixed to 10, how do I get event id? + UInt_t x = 0; // General used number + Int_t rv = fFee->GetRAWversion(); + + // Check the nCol and nRow. + if ((nCol == 144) && + (nRow == 16 || nRow == 12)) { + kCtype = (nRow-12) / 4; + } + else { + AliError(Form("This type of chamber is not supported (nRow=%d, nCol=%d)." + ,nRow,nCol)); + return 0; + } - ofstream *outputFile[kNumberOfDDLs]; - UInt_t bHPosition[kNumberOfDDLs]; - Int_t ntotalbyte[kNumberOfDDLs]; - Int_t nbyte = 0; - Int_t npads = 0; - unsigned char *bytePtr; - unsigned char *headerPtr; + AliDebug(1,Form("Producing raw data for sect=%d layer=%d stack=%d side=%d" + ,sect,layer,stack,side)); - AliTRDdigitsManager* digitsManager = new AliTRDdigitsManager(); - digitsManager->SetDebug(fDebug); + // Tracklet should be processed here but not implemented yet - // Read in the digit arrays - if (!digitsManager->ReadDigits(digitsTree)) { - delete digitsManager; - return kFALSE; + // Write end of tracklet marker + if (nw < maxSize) { + buf[nw++] = kEndoftrackletmarker; + } + else { + of++; } - AliTRDgeometry *geo = new AliTRDgeometry(); - AliTRDdataArrayI *digits; - - AliTRDCommonParam* commonParam = AliTRDCommonParam::Instance(); - if (!commonParam) - { - printf(" "); - printf("Could not get common params\n"); - return 0; - } - - AliTRDcalibDB* calibration = AliTRDcalibDB::Instance(); - if (!calibration) - { - printf(" "); - printf("Could not get calibration object\n"); - return kFALSE; + // Half Chamber header + if ( rv == 1 ) { + // Now it is the same version as used in SM-I commissioning. + Int_t dcs = det+100; // DCS Serial (in simulation, it is meaningless + x = (dcs<<20) | (sect<<15) | (layer<<12) | (stack<<9) | (side<<8) | 1; + if (nw < maxSize) { + buf[nw++] = x; + } + else { + of++; + } + } + else if ( rv == 2 ) { + // h[0] (there are 3 HC header) + Int_t minorv = 0; // The minor version number + Int_t add = 2; // The number of additional header words to follow + x = (1<<31) | (rv<<24) | (minorv<<17) | (add<<14) | (sect<<9) | (layer<<6) | (stack<<3) | (side<<2) | 1; + if (nw < maxSize) { + buf[nw++] = x; + } + else { + of++; + } + // h[1] + Int_t bcCtr = 99; // bunch crossing counter. Here it is set to 99 always for no reason + Int_t ptCtr = 15; // pretrigger counter. Here it is set to 15 always for no reason + Int_t ptPhase = 11; // pretrigger phase. Here it is set to 11 always for no reason + x = (bcCtr<<16) | (ptCtr<<12) | (ptPhase<<8) | ((kNTBin-1)<<2) | 1; + if (nw < maxSize) { + buf[nw++] = x; + } + else { + of++; + } + // h[2] + Int_t pedSetup = 1; // Pedestal filter setup (0:1). Here it is always 1 for no reason + Int_t gainSetup = 1; // Gain filter setup (0:1). Here it is always 1 for no reason + Int_t tailSetup = 1; // Tail filter setup (0:1). Here it is always 1 for no reason + Int_t xtSetup = 0; // Cross talk filter setup (0:1). Here it is always 0 for no reason + Int_t nonlinSetup = 0; // Nonlinearity filter setup (0:1). Here it is always 0 for no reason + Int_t bypassSetup = 0; // Filter bypass (for raw data) setup (0:1). Here it is always 0 for no reason + Int_t commonAdditive = 10; // Digital filter common additive (0:63). Here it is always 10 for no reason + x = (pedSetup<<31) | (gainSetup<<30) | (tailSetup<<29) | (xtSetup<<28) | (nonlinSetup<<27) + | (bypassSetup<<26) | (commonAdditive<<20) | 1; + if (nw < maxSize) { + buf[nw++] = x; + } + else { + of++; + } } - - // the event header - AliRawDataHeader header; - - // Open the output files - for (Int_t iDDL = 0; iDDL < kNumberOfDDLs; iDDL++) { - char name[20]; - strcpy(name,AliDAQ::DdlFileName("TRD",iDDL)); -#ifndef __DECCXX - outputFile[iDDL] = new ofstream(name, ios::binary); -#else - outputFile[iDDL] = new ofstream(name); -#endif - // Write a dummy data header - bHPosition[iDDL] = outputFile[iDDL]->tellp(); - outputFile[iDDL]->write((char*)(&header),sizeof(header)); - ntotalbyte[iDDL] = 0; - } + // Scan for ROB and MCM + for (Int_t iRobRow = 0; iRobRow < (kCtype + 3); iRobRow++ ) { + Int_t iRob = iRobRow * 2 + side; + for (Int_t iMcm = 0; iMcm < fGeo->MCMmax(); iMcm++ ) { + Int_t padrow = iRobRow * 4 + iMcm / 4; - // Loop through all detectors - for (Int_t det = 0; det < AliTRDgeometry::Ndet(); det++) { - - Int_t cham = geo->GetChamber(det); - Int_t plan = geo->GetPlane(det); - Int_t sect = geo->GetSector(det); - Int_t rowMax = commonParam->GetRowMax(plan,cham,sect); - Int_t colMax = commonParam->GetColMax(plan); - Int_t timeTotal = calibration->GetNumberOfTimeBins(); - Int_t bufferMax = rowMax*colMax*timeTotal; - Int_t *buffer = new Int_t[bufferMax]; - - npads = 0; - nbyte = 0; - bytePtr = (unsigned char *) buffer; - - Int_t iDDL = sect; - - // Get the digits array - digits = digitsManager->GetDigits(det); - digits->Expand(); - - // Loop through the detector pixel - for (Int_t col = 0; col < colMax; col++) { - for (Int_t row = 0; row < rowMax; row++) { - - // Check whether data exists for this pad - Bool_t dataflag = kFALSE; - for (Int_t time = 0; time < timeTotal; time++) { - Int_t data = digits->GetDataUnchecked(row,col,time); - if (data) { - dataflag = kTRUE; - break; + // MCM header + x = ((iRob * fGeo->MCMmax() + iMcm) << 24) | ((iEv % 0x100000) << 4) | 0xC; + if (nw < maxSize) { + buf[nw++] = x; + } + else { + of++; + } + + // ADC data + for (Int_t iAdc = 0; iAdc < 21; iAdc++ ) { + Int_t padcol = fFee->GetPadColFromADC(iRob, iMcm, iAdc); + UInt_t aa = !(iAdc & 1) + 2; + UInt_t *a = new UInt_t[kNTBin+2]; + // 3 timebins are packed into one 32 bits word + for (Int_t iT = 0; iT < kNTBin; iT+=3) { + if ((padcol >= 0) && (padcol < nCol)) { + a[iT ] = ((iT ) < kNTBin ) ? digits->GetDataUnchecked(padrow,padcol,iT ) : 0; + a[iT+1] = ((iT + 1) < kNTBin ) ? digits->GetDataUnchecked(padrow,padcol,iT + 1) : 0; + a[iT+2] = ((iT + 2) < kNTBin ) ? digits->GetDataUnchecked(padrow,padcol,iT + 2) : 0; + } + else { + a[iT] = a[iT+1] = a[iT+2] = 0; // This happenes at the edge of chamber (should be pedestal! How?) + } + x = (a[iT+2] << 22) | (a[iT+1] << 12) | (a[iT] << 2) | aa; + if (nw < maxSize) { + buf[nw++] = x; + } + else { + of++; } } + // Diagnostics + Float_t avg = 0; + Float_t rms = 0; + for (Int_t iT = 0; iT < kNTBin; iT++) { + avg += (Float_t) (a[iT]); + } + avg /= (Float_t) kNTBin; + for (Int_t iT = 0; iT < kNTBin; iT++) { + rms += ((Float_t) (a[iT]) - avg) * ((Float_t) (a[iT]) - avg); + } + rms = TMath::Sqrt(rms / (Float_t) kNTBin); + if (rms > 1.7) { + AliDebug(2,Form("Large RMS (>1.7) (ROB,MCM,ADC)=(%02d,%02d,%02d), avg=%03.1f, rms=%03.1f" + ,iRob,iMcm,iAdc,avg,rms)); + } + delete [] a; + } + } + } - if (dataflag) { + // Write end of raw data marker + if (nw < maxSize) { + buf[nw++] = kEndofrawdatamarker; + } + else { + of++; + } + if (of != 0) { + AliWarning("Buffer overflow. Data is truncated. Please increase buffer size and recompile."); + } - npads++; + return nw; - // The pad row number - *bytePtr++ = row + 1; - // The pad column number - *bytePtr++ = col + 1; - nbyte += 2; +} - Int_t nzero = 0; - for (Int_t time = 0; time < timeTotal; time++) { +//_____________________________________________________________________________ - Int_t data = digits->GetDataUnchecked(row,col,time); +//Int_t AliTRDrawData::ProduceHcDataV3(AliTRDdataArrayS *digits, Int_t side , Int_t det, UInt_t *buf, Int_t maxSize) +Int_t AliTRDrawData::ProduceHcDataV3(AliTRDdataArrayS *digits, Int_t side , Int_t det, UInt_t *buf, Int_t maxSize, Bool_t newEvent = kFALSE) +{ + // + // This function simulates: Raw Version == 3 (Zero Suppression Prototype) + // - if (!data) { - nzero++; - if ((nzero == 256) || - (time == timeTotal-1)) { - *bytePtr++ = 0; - *bytePtr++ = nzero-1; - nbyte += 2; - nzero = 0; - } + Int_t nw = 0; // Number of written words + Int_t of = 0; // Number of overflowed words + Int_t layer = fGeo->GetLayer( det ); // Layer + Int_t stack = fGeo->GetStack( det ); // Stack + Int_t sect = fGeo->GetSector( det ); // Sector (=iDDL) + Int_t nRow = fGeo->GetRowMax( layer, stack, sect ); + Int_t nCol = fGeo->GetColMax( layer ); + const Int_t kNTBin = AliTRDcalibDB::Instance()->GetNumberOfTimeBins(); + Int_t kCtype = 0; // Chamber type (0:C0, 1:C1) + //Int_t iEv = 0xA; // Event ID. Now fixed to 10, how do I get event id? + + + + Bool_t tracklet_on = fFee->GetTracklet(); // **new** + + // Check the nCol and nRow. + if ((nCol == 144) && + (nRow == 16 || nRow == 12)) { + kCtype = (nRow-12) / 4; + } + else { + AliError(Form("This type of chamber is not supported (nRow=%d, nCol=%d)." + ,nRow,nCol)); + return 0; + } + + AliDebug(1,Form("Producing raw data for sect=%d layer=%d stack=%d side=%d" + ,sect,layer,stack,side)); + + AliTRDmcmSim** mcm = new AliTRDmcmSim*[(kCtype + 3)*(fGeo->MCMmax())]; + + // in case no tracklet-words are processed: write the tracklet-endmarker as well as all additional words immediately and write + // raw-data in one go; if tracklet-processing is enabled, first all tracklet-words of a half-chamber have to be processed before the + // additional words (tracklet-endmarker,headers,...)are written. Raw-data is written in a second loop; + + if (!tracklet_on) { + WriteIntermediateWords(buf,nw,of,maxSize,det,side); + } + + // Scan for ROB and MCM + // scanning direction such, that tracklet-words are sorted in ascending z and then in ascending y order + // ROB numbering on chamber and MCM numbering on ROB increase with decreasing z and increasing y + for (Int_t iRobRow = (kCtype + 3)-1; iRobRow >= 0; iRobRow-- ) { + Int_t iRob = iRobRow * 2 + side; + // MCM on one ROB + for (Int_t iMcmRB = 0; iMcmRB < fGeo->MCMmax(); iMcmRB++ ) { + Int_t iMcm = 16 - 4*(iMcmRB/4 + 1) + (iMcmRB%4); + Int_t entry = iRobRow*(fGeo->MCMmax()) + iMcm; + + mcm[entry] = new AliTRDmcmSim(); + mcm[entry]->Init( det, iRob, iMcm , newEvent); + //mcm[entry]->Init( det, iRob, iMcm); + if (newEvent == kTRUE) newEvent = kFALSE; // only one mcm is concerned with new event + Int_t padrow = mcm[entry]->GetRow(); + + // Copy ADC data to MCM simulator + for (Int_t iAdc = 0; iAdc < 21; iAdc++ ) { + Int_t padcol = mcm[entry]->GetCol( iAdc ); + if ((padcol >= 0) && (padcol < nCol)) { + for (Int_t iT = 0; iT < kNTBin; iT++) { + mcm[entry]->SetData( iAdc, iT, digits->GetDataUnchecked( padrow, padcol, iT) ); + } + } + else { // this means it is out of chamber, and masked ADC + mcm[entry]->SetDataPedestal( iAdc ); } - else { - if (nzero) { - *bytePtr++ = 0; - *bytePtr++ = nzero-1; - nbyte += 2; - nzero = 0; - } - // High byte (MSB always set) - *bytePtr++ = ((data >> 8) | 128); - // Low byte - *bytePtr++ = (data & 0xff); - nbyte += 2; + } + + // Simulate process in MCM + mcm[entry]->Filter(); // Apply filter + mcm[entry]->ZSMapping(); // Calculate zero suppression mapping + + if (tracklet_on) { + mcm[entry]->Tracklet(); + Int_t tempNw = mcm[entry]->ProduceTrackletStream( &buf[nw], maxSize - nw ); + //Int_t tempNw = 0; + if( tempNw < 0 ) { + of += tempNw; + nw += maxSize - nw; + AliError(Form("Buffer overflow detected. Please increase the buffer size and recompile.")); + } else { + nw += tempNw; } + } + // no tracklets: write raw-data already in this loop + else { + // Write MCM data to buffer + Int_t tempNw = mcm[entry]->ProduceRawStream( &buf[nw], maxSize - nw ); + if( tempNw < 0 ) { + of += tempNw; + nw += maxSize - nw; + AliError(Form("Buffer overflow detected. Please increase the buffer size and recompile.")); + } else { + nw += tempNw; + } + + delete mcm[entry]; + } + + - } - } + //mcm->DumpData( "trdmcmdata.txt", "RFZS" ); // debugging purpose + } + } + // if tracklets are switched on, raw-data can be written only after all tracklets + if (tracklet_on) { + WriteIntermediateWords(buf,nw,of,maxSize,det,side); + + + // Scan for ROB and MCM + for (Int_t iRobRow = (kCtype + 3)-1; iRobRow >= 0; iRobRow-- ) { + //Int_t iRob = iRobRow * 2 + side; + // MCM on one ROB + for (Int_t iMcmRB = 0; iMcmRB < fGeo->MCMmax(); iMcmRB++ ) { + Int_t iMcm = 16 - 4*(iMcmRB/4 + 1) + (iMcmRB%4); + + Int_t entry = iRobRow*(fGeo->MCMmax()) + iMcm; + + // Write MCM data to buffer + Int_t tempNw = mcm[entry]->ProduceRawStream( &buf[nw], maxSize - nw ); + if( tempNw < 0 ) { + of += tempNw; + nw += maxSize - nw; + AliError(Form("Buffer overflow detected. Please increase the buffer size and recompile.")); + } else { + nw += tempNw; + } + + delete mcm[entry]; + + } } + } - } + delete [] mcm; + + // Write end of raw data marker + if (nw < maxSize) { + buf[nw++] = kEndofrawdatamarker; + } + else { + of++; + } + if (of != 0) { + AliError("Buffer overflow. Data is truncated. Please increase buffer size and recompile."); + } - // Fill the end of the buffer with zeros - while (nbyte % 4) { - *bytePtr++ = 0; - nbyte++; - } - if (fDebug > 1) { - Info("Digits2Raw","det = %d, nbyte = %d (%d)",det,nbyte,bufferMax); - } + return nw; - // Write the subevent header - bytePtr = (unsigned char *) headerSubevent; - headerPtr = bytePtr; - *bytePtr++ = kSubeventDummyFlag; - *bytePtr++ = (det & 0xff); - *bytePtr++ = (det >> 8); - *bytePtr++ = (nbyte & 0xff); - *bytePtr++ = (nbyte >> 8); - *bytePtr++ = (nbyte >> 16); - *bytePtr++ = (npads & 0xff); - *bytePtr++ = (npads >> 8); - outputFile[iDDL]->write((char*)headerPtr,kSubeventHeaderLength); +} - // Write the buffer to the file - bytePtr = (unsigned char *) buffer; - outputFile[iDDL]->write((char*)bytePtr,nbyte); +//_____________________________________________________________________________ +AliTRDdigitsManager *AliTRDrawData::Raw2Digits(AliRawReader *rawReader) +{ + // + // Vx of the raw data reading + // - ntotalbyte[iDDL] += nbyte + kSubeventHeaderLength; + AliTRDdataArrayS *digits = 0; + AliTRDdataArrayI *track0 = 0; + AliTRDdataArrayI *track1 = 0; + AliTRDdataArrayI *track2 = 0; - delete buffer; + //AliTRDSignalIndex *indexes = 0; + // Create the digits manager + AliTRDdigitsManager* digitsManager = new AliTRDdigitsManager(); + digitsManager->CreateArrays(); - } + //AliTRDRawStream input(rawReader); + // AliTRDRawStreamV2 input(rawReader); + // input.SetRawVersion( fFee->GetRAWversion() ); + // input.Init(); - if (fDebug) { - for (Int_t iDDL = 0; iDDL < kNumberOfDDLs; iDDL++) { - Info("Digits2Raw","Total size: DDL %d = %d",iDDL,ntotalbyte[iDDL]); - } - } + AliTRDrawStreamBase *pinput = AliTRDrawStreamBase::GetRawStream(rawReader); + AliTRDrawStreamBase &input = *pinput; - // Update the data headers and close the output files - for (Int_t iDDL = 0; iDDL < kNumberOfDDLs; iDDL++) { - header.fSize = UInt_t(outputFile[iDDL]->tellp()) - bHPosition[iDDL]; - header.SetAttribute(0); // valid data - outputFile[iDDL]->seekp(bHPosition[iDDL]); - outputFile[iDDL]->write((char*)(&header),sizeof(header)); + AliInfo(Form("Stream version: %s", input.IsA()->GetName())); - outputFile[iDDL]->close(); - delete outputFile[iDDL]; - } + // Loop through the digits + Int_t det = 0; + + while (det >= 0) + { + det = input.NextChamber(digitsManager); + if (det >= 0) + { + // get... + digits = (AliTRDdataArrayS *) digitsManager->GetDigits(det); + track0 = (AliTRDdataArrayI *) digitsManager->GetDictionary(det,0); + track1 = (AliTRDdataArrayI *) digitsManager->GetDictionary(det,1); + track2 = (AliTRDdataArrayI *) digitsManager->GetDictionary(det,2); + // and compress + if (digits) digits->Compress(1,0); + if (track0) track0->Compress(1,0); + if (track1) track1->Compress(1,0); + if (track2) track2->Compress(1,0); + } + } - delete geo; - delete digitsManager; + delete pinput; + pinput = NULL; - return kTRUE; + return digitsManager; +} + +//_____________________________________________________________________________ +void AliTRDrawData::WriteIntermediateWords(UInt_t* buf, Int_t& nw, Int_t& of, const Int_t& maxSize, const Int_t& det, const Int_t& side) { + + Int_t layer = fGeo->GetLayer( det ); // Layer + Int_t stack = fGeo->GetStack( det ); // Stack + Int_t sect = fGeo->GetSector( det ); // Sector (=iDDL) + Int_t rv = fFee->GetRAWversion(); + const Int_t kNTBin = AliTRDcalibDB::Instance()->GetNumberOfTimeBins(); + UInt_t x = 0; + + // Write end of tracklet marker + if (nw < maxSize) { + buf[nw++] = kEndoftrackletmarker; + } + else { + of++; + } + + // Half Chamber header + // h[0] (there are 3 HC header) + Int_t minorv = 0; // The minor version number + Int_t add = 2; // The number of additional header words to follow + x = (1<<31) | (rv<<24) | (minorv<<17) | (add<<14) | (sect<<9) | (layer<<6) | (stack<<3) | (side<<2) | 1; + if (nw < maxSize) { + buf[nw++] = x; + } + else { + of++; + } + // h[1] + Int_t bcCtr = 99; // bunch crossing counter. Here it is set to 99 always for no reason + Int_t ptCtr = 15; // pretrigger counter. Here it is set to 15 always for no reason + Int_t ptPhase = 11; // pretrigger phase. Here it is set to 11 always for no reason + x = (bcCtr<<16) | (ptCtr<<12) | (ptPhase<<8) | ((kNTBin-1)<<2) | 1; + if (nw < maxSize) { + buf[nw++] = x; + } + else { + of++; + } + // h[2] + Int_t pedSetup = 1; // Pedestal filter setup (0:1). Here it is always 1 for no reason + Int_t gainSetup = 1; // Gain filter setup (0:1). Here it is always 1 for no reason + Int_t tailSetup = 1; // Tail filter setup (0:1). Here it is always 1 for no reason + Int_t xtSetup = 0; // Cross talk filter setup (0:1). Here it is always 0 for no reason + Int_t nonlinSetup = 0; // Nonlinearity filter setup (0:1). Here it is always 0 for no reason + Int_t bypassSetup = 0; // Filter bypass (for raw data) setup (0:1). Here it is always 0 for no reason + Int_t commonAdditive = 10; // Digital filter common additive (0:63). Here it is always 10 for no reason + x = (pedSetup<<31) | (gainSetup<<30) | (tailSetup<<29) | (xtSetup<<28) | (nonlinSetup<<27) + | (bypassSetup<<26) | (commonAdditive<<20) | 1; + if (nw < maxSize) { + buf[nw++] = x; + } + else { + of++; + } } + //_____________________________________________________________________________ -AliTRDdigitsManager* AliTRDrawData::Raw2Digits(AliRawReader* rawReader) +AliTRDdigitsManager *AliTRDrawData::Raw2DigitsOLD(AliRawReader *rawReader) { // - // Read the raw data digits and put them into the returned digits manager + // Vx of the raw data reading // - AliTRDdataArrayI *digits = 0; - AliTRDdataArrayI *track0 = 0; - AliTRDdataArrayI *track1 = 0; - AliTRDdataArrayI *track2 = 0; - - AliTRDgeometry *geo = new AliTRDgeometry(); - - AliTRDCommonParam* commonParam = AliTRDCommonParam::Instance(); - if (!commonParam) - { - printf(" "); - printf("Could not get common params\n"); - return 0; - } - - AliTRDcalibDB* calibration = AliTRDcalibDB::Instance(); - if (!calibration) - { - printf(" "); - printf("Could not get calibration object\n"); - return 0; - } + AliTRDdataArrayS *digits = 0; + AliTRDdataArrayI *track0 = 0; + AliTRDdataArrayI *track1 = 0; + AliTRDdataArrayI *track2 = 0; + AliTRDSignalIndex *indexes = 0; // Create the digits manager AliTRDdigitsManager* digitsManager = new AliTRDdigitsManager(); - digitsManager->SetDebug(fDebug); digitsManager->CreateArrays(); - AliTRDRawStream input(rawReader); + //AliTRDRawStream input(rawReader); + AliTRDRawStreamV2 input(rawReader); + input.SetRawVersion( fFee->GetRAWversion() ); + input.Init(); + + AliInfo(Form("Stream version: %s", input.IsA()->GetName())); // Loop through the digits + Int_t lastdet = -1; + Int_t det = 0; + Int_t it = 0; while (input.Next()) { - Int_t det = input.GetDetector(); - Int_t npads = input.GetNPads(); - - if (input.IsNewDetector()) { - - if (digits) digits->Compress(1,0); - if (track0) track0->Compress(1,0); - if (track1) track1->Compress(1,0); - if (track2) track2->Compress(1,0); - - if (fDebug > 2) { - Info("Raw2Digits","Subevent header:"); - Info("Raw2Digits","\tdet = %d",det); - Info("Raw2Digits","\tnpads = %d",npads); - } - - // Create the data buffer - Int_t cham = geo->GetChamber(det); - Int_t plan = geo->GetPlane(det); - Int_t sect = geo->GetSector(det); - Int_t rowMax = commonParam->GetRowMax(plan,cham,sect); - Int_t colMax = commonParam->GetColMax(plan); - Int_t timeTotal = calibration->GetNumberOfTimeBins(); - - // Add a container for the digits of this detector - digits = digitsManager->GetDigits(det); - track0 = digitsManager->GetDictionary(det,0); - track1 = digitsManager->GetDictionary(det,1); - track2 = digitsManager->GetDictionary(det,2); - // Allocate memory space for the digits buffer - if (digits->GetNtime() == 0) { - digits->Allocate(rowMax,colMax,timeTotal); - track0->Allocate(rowMax,colMax,timeTotal); - track1->Allocate(rowMax,colMax,timeTotal); - track2->Allocate(rowMax,colMax,timeTotal); - } - - } + det = input.GetDet(); + + if (det != lastdet) { // If new detector found + + lastdet = det; + + if (digits) digits->Compress(1,0); + if (track0) track0->Compress(1,0); + if (track1) track1->Compress(1,0); + if (track2) track2->Compress(1,0); + + // Add a container for the digits of this detector + digits = (AliTRDdataArrayS *) digitsManager->GetDigits(det); + track0 = (AliTRDdataArrayI *) digitsManager->GetDictionary(det,0); + track1 = (AliTRDdataArrayI *) digitsManager->GetDictionary(det,1); + track2 = (AliTRDdataArrayI *) digitsManager->GetDictionary(det,2); + + // Allocate memory space for the digits buffer + if (digits->GetNtime() == 0) + { + digits->Allocate(input.GetMaxRow(),input.GetMaxCol(), input.GetNumberOfTimeBins()); + track0->Allocate(input.GetMaxRow(),input.GetMaxCol(), input.GetNumberOfTimeBins()); + track1->Allocate(input.GetMaxRow(),input.GetMaxCol(), input.GetNumberOfTimeBins()); + track2->Allocate(input.GetMaxRow(),input.GetMaxCol(), input.GetNumberOfTimeBins()); + } - digits->SetDataUnchecked(input.GetRow(),input.GetColumn(), - input.GetTime(),input.GetSignal()); - track0->SetDataUnchecked(input.GetRow(),input.GetColumn(), - input.GetTime(), -1); - track1->SetDataUnchecked(input.GetRow(),input.GetColumn(), - input.GetTime(), -1); - track2->SetDataUnchecked(input.GetRow(),input.GetColumn(), - input.GetTime(), -1); + indexes = digitsManager->GetIndexes(det); + indexes->SetSM(input.GetSM()); + indexes->SetStack(input.GetStack()); + indexes->SetLayer(input.GetLayer()); + indexes->SetDetNumber(det); + if (indexes->IsAllocated() == kFALSE) + indexes->Allocate(input.GetMaxRow(), input.GetMaxCol(), input.GetNumberOfTimeBins()); + } + + // 3 timebin data are stored per word + for (it = 0; it < 3; it++) + { + if ( input.GetTimeBin() + it < input.GetNumberOfTimeBins() ) + { + if (input.GetSignals()[it] > 0) + { + digits->SetDataUnchecked(input.GetRow(), input.GetCol(), + input.GetTimeBin() + it, input.GetSignals()[it]); + + indexes->AddIndexTBin(input.GetRow(), input.GetCol(), + input.GetTimeBin() + it); + track0->SetDataUnchecked(input.GetRow(), input.GetCol(), + input.GetTimeBin() + it, 0); + track1->SetDataUnchecked(input.GetRow(), input.GetCol(), + input.GetTimeBin() + it, 0); + track2->SetDataUnchecked(input.GetRow(), input.GetCol(), + input.GetTimeBin() + it, 0); + } + } + } } if (digits) digits->Compress(1,0); @@ -405,8 +805,6 @@ AliTRDdigitsManager* AliTRDrawData::Raw2Digits(AliRawReader* rawReader) if (track1) track1->Compress(1,0); if (track2) track2->Compress(1,0); - delete geo; - return digitsManager; }