]>
Commit | Line | Data |
---|---|---|
1 | /************************************************************************** | |
2 | * Copyright(c) 1998-2003, ALICE Experiment at CERN, All rights reserved. * | |
3 | * * | |
4 | * Author: The ALICE Off-line Project. * | |
5 | * Contributors are mentioned in the code where appropriate. * | |
6 | * * | |
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 | **************************************************************************/ | |
15 | ||
16 | /* $Id$ */ | |
17 | ||
18 | ||
19 | //This class contains all the necessary methods to create the Raw Data | |
20 | //files (slides) for the ITS data challenges for: | |
21 | //SPD | |
22 | //SDD | |
23 | //SSD | |
24 | ||
25 | #include <stdlib.h> | |
26 | //#include <Riostream.h> | |
27 | #include <TClonesArray.h> | |
28 | #include <TTree.h> | |
29 | #include "AliITSdigit.h" | |
30 | #include "AliITSDDLRawData.h" | |
31 | #include "AliRawDataHeaderSim.h" | |
32 | #include "AliITSRawStreamSPD.h" | |
33 | #include "AliITSRawStreamSDD.h" | |
34 | #include "AliITSDDLModuleMapSDD.h" | |
35 | #include "AliITSRawStreamSSD.h" | |
36 | #include "AliITSIntMap.h" | |
37 | #include "AliBitPacking.h" | |
38 | #include "AliDAQ.h" | |
39 | #include "AliFstream.h" | |
40 | #include "AliITSFOSignalsSPD.h" | |
41 | ||
42 | using std::ofstream; | |
43 | using std::ios; | |
44 | using std::endl; | |
45 | ClassImp(AliITSDDLRawData) | |
46 | ||
47 | //////////////////////////////////////////////////////////////////////////////////////// | |
48 | AliITSDDLRawData::AliITSDDLRawData(): | |
49 | fVerbose(0), | |
50 | fIndex(-1), | |
51 | fHalfStaveModule(-1), | |
52 | fSDDRawFormat(7){ | |
53 | //Default constructor | |
54 | ||
55 | } | |
56 | ||
57 | //////////////////////////////////////////////////////////////////////////////////////// | |
58 | ||
59 | AliITSDDLRawData::AliITSDDLRawData(const AliITSDDLRawData &source) : | |
60 | TObject(source), | |
61 | fVerbose(source.fVerbose), | |
62 | fIndex(source.fIndex), | |
63 | fHalfStaveModule(source.fHalfStaveModule), | |
64 | fSDDRawFormat(source.fSDDRawFormat){ | |
65 | //Copy Constructor | |
66 | } | |
67 | ||
68 | //////////////////////////////////////////////////////////////////////////////////////// | |
69 | ||
70 | AliITSDDLRawData& AliITSDDLRawData::operator=(const AliITSDDLRawData &source){ | |
71 | //Assigment operator | |
72 | if(this==&source) return *this; | |
73 | fIndex=source.fIndex; | |
74 | fHalfStaveModule=source.fHalfStaveModule; | |
75 | fVerbose=source.fVerbose; | |
76 | fSDDRawFormat=source.fSDDRawFormat; | |
77 | return *this; | |
78 | } | |
79 | ||
80 | //////////////////////////////////////////////////////////////////////////////////////// | |
81 | //STRIP | |
82 | // | |
83 | ||
84 | void AliITSDDLRawData::GetDigitsSSD(TClonesArray *ITSdigits,Int_t mod,Int_t modR,Int_t ddl,UInt_t *buf){ | |
85 | //This method packs the SSD digits in a proper 32 bits structure | |
86 | // Revised by Enrico Fragiacomo | |
87 | Int_t ix; | |
88 | Int_t iz; | |
89 | Int_t is; | |
90 | UInt_t word; | |
91 | UInt_t baseWord; | |
92 | Int_t ndigits = ITSdigits->GetEntries(); | |
93 | AliITSdigit *digs; | |
94 | ofstream ftxt; | |
95 | if(ndigits){ | |
96 | if (fVerbose==2){ | |
97 | ftxt.open("SSDdigits.txt",ios::app); | |
98 | } | |
99 | for (Int_t digit=0;digit<ndigits;digit++) { | |
100 | digs = (AliITSdigit*)ITSdigits->UncheckedAt(digit); | |
101 | iz=digs->GetCoord1(); // If iz==0, O side and if iz=1 N side | |
102 | ix=digs->GetCoord2(); // Strip Number | |
103 | is=digs->GetCompressedSignal(); // ADC Signal | |
104 | // cout<<" Module:"<<mod-500<<" N/P side:"<<iz<<" Strip Number:"<<ix<<" Amplidute:"<<is-1<<endl; | |
105 | if(is<0) is = 0; | |
106 | if(is>4095) is = 4095; | |
107 | if (fVerbose==2) | |
108 | ftxt<<"DDL:"<<ddl<<" Mod: "<<modR<<" N/P: "<<iz<<" Strip: "<<ix<<" Value: "<<is-1<<endl; | |
109 | ||
110 | baseWord=0; | |
111 | ||
112 | word=is; | |
113 | AliBitPacking::PackWord(word,baseWord,0,11);//ADC data | |
114 | ||
115 | word = (iz==0) ? ix : 1535-ix ; // on N-side 1535-768 -> 0-767 | |
116 | AliBitPacking::PackWord(word,baseWord,12,22);//Strip Number | |
117 | ||
118 | word = mod%12; // ADC-number (12 ADCs per AD module) | |
119 | word += ( word<6 ) ? 0 : 2; // ADC range 0-5 and 8-13 | |
120 | AliBitPacking::PackWord(word,baseWord,24,27);//ADC Channel | |
121 | ||
122 | word = mod/12+1; // AD-number (AD module index ranges 1-9) | |
123 | AliBitPacking::PackWord(word,baseWord,28,31);//AD slot | |
124 | fIndex++; | |
125 | buf[fIndex]=baseWord; | |
126 | }//end for | |
127 | }//end if | |
128 | if (fVerbose==2) | |
129 | ftxt.close(); | |
130 | return; | |
131 | }//end GetDigitsSSD | |
132 | ||
133 | //////////////////////////////////////////////////////////////////////////////////////// | |
134 | //Silicon Drift Detector | |
135 | // | |
136 | ||
137 | void AliITSDDLRawData::GetDigitsSDDCompressed(TClonesArray *ITSdigits, Int_t mod, UInt_t *buf){ | |
138 | //This method packs the SDD digits in the compressed format (32 bit per digit) | |
139 | // see AliITSRawStreamSDDCompressed for details on the dta format | |
140 | ||
141 | UInt_t dataWord=0; | |
142 | Int_t ndigits = ITSdigits->GetEntries(); | |
143 | AliITSdigit *digs; | |
144 | if(ndigits){ | |
145 | for (Int_t digit=0;digit<ndigits;digit++) { | |
146 | digs = (AliITSdigit*)ITSdigits->UncheckedAt(digit); | |
147 | Int_t iz=digs->GetCoord1(); // Anode | |
148 | Int_t ix=digs->GetCoord2(); // Time | |
149 | Int_t is=digs->GetCompressedSignal(); // ADC Signal - 8 bit | |
150 | dataWord=mod<<27; | |
151 | Int_t sid=0; | |
152 | if(iz>=256){ | |
153 | sid=1; | |
154 | iz-=256; | |
155 | } | |
156 | dataWord+=sid<<26; | |
157 | dataWord+=iz<<18; | |
158 | dataWord+=ix<<10; | |
159 | UInt_t adcEncoded=0; | |
160 | Int_t shift=0; | |
161 | if(is < 8) shift=2; | |
162 | else if(is<16) shift=3; | |
163 | else if(is<32) shift=4; | |
164 | else if(is<64) shift=5; | |
165 | else if(is<128) shift=6; | |
166 | else shift=7; | |
167 | adcEncoded=shift+((is-(1<<shift))<<3); | |
168 | dataWord+=adcEncoded; | |
169 | fIndex++; | |
170 | buf[fIndex]=dataWord; | |
171 | } | |
172 | } | |
173 | UInt_t finalWord=UInt_t(15)<<28; | |
174 | finalWord+=mod; | |
175 | fIndex++; | |
176 | buf[fIndex]=finalWord; | |
177 | } | |
178 | ||
179 | //______________________________________________________________________ | |
180 | ||
181 | void AliITSDDLRawData::GetDigitsSDD(TClonesArray *ITSdigits,Int_t mod,Int_t modR,Int_t ddl,UInt_t *buf){ | |
182 | //This method packs the SDD digits in a proper 32 bits structure | |
183 | Int_t ix; | |
184 | Int_t iz; | |
185 | Int_t is; | |
186 | UInt_t word=0; | |
187 | UInt_t baseWord=0; | |
188 | Int_t ndigits = ITSdigits->GetEntries(); | |
189 | AliITSdigit *digs; | |
190 | ofstream ftxt; | |
191 | Int_t digarr[512][256]; | |
192 | for(Int_t i=0;i<512;i++){ | |
193 | for(Int_t j=0;j<256;j++){ | |
194 | digarr[i][j]=0; | |
195 | } | |
196 | } | |
197 | //word to select the 12 carlos for the 12 modules | |
198 | UInt_t carlosid=0x30000000+mod; | |
199 | ||
200 | fIndex++; | |
201 | buf[fIndex]=carlosid; | |
202 | Int_t first=0; | |
203 | Int_t last=0; | |
204 | Int_t diff=0; | |
205 | Int_t nbit=0; | |
206 | UInt_t word2=0; | |
207 | Bool_t flag = kFALSE; | |
208 | baseWord=0; | |
209 | Int_t bitinfo1[4] = {3,8,3,7}; //vector with info on bit for timebin info | |
210 | Int_t wordinfo1[4]= {0,0,0,0}; //vector with word info for timebin info | |
211 | Int_t bitinfo2[2] = {3,18}; //vector with info on bit for EOR (end of row) info | |
212 | Int_t wordinfo2[3]= {1,65593}; //vector with word info for anode info | |
213 | ||
214 | /* for time bin info: word n bits meaning | |
215 | 0 3 next info is timebin | |
216 | 8 3 next word is 8 bit long | |
217 | tb value 8 timebin value | |
218 | n (2->7) 3 next info is n bit long | |
219 | signal n signal value | |
220 | ||
221 | for anode info: 1 3 next 18 bits are for EOR | |
222 | increments the anode value | |
223 | ||
224 | EOR 18 error codes + other info | |
225 | */ | |
226 | ||
227 | if(ndigits){ | |
228 | if (fVerbose==2) | |
229 | ftxt.open("SDDdigits.txt",ios::app); | |
230 | for (Int_t digit=0;digit<ndigits;digit++) { | |
231 | digs = (AliITSdigit*)ITSdigits->UncheckedAt(digit); | |
232 | iz=digs->GetCoord1(); // Anode | |
233 | ix=digs->GetCoord2(); // Time | |
234 | is=digs->GetCompressedSignal(); // ADC Signal | |
235 | digarr[iz][ix]=is; | |
236 | if (fVerbose==2) | |
237 | ftxt<<"DDL:"<<ddl<<" MID:"<<modR<<" An:"<<iz<<" T:"<<ix<<" A:"<<is<<endl; | |
238 | if (is>255){Error("GetDigitsSDD", "bits words is needed)!!!");} | |
239 | } | |
240 | ||
241 | for(Int_t anode=0;anode<512;anode++){ | |
242 | if(flag){ | |
243 | last = first+diff-1; | |
244 | AliBitPacking::PackWord(word2,baseWord,first,last); | |
245 | flag = kFALSE; | |
246 | first = last+1; | |
247 | diff=0; | |
248 | } | |
249 | if(anode == 256){ | |
250 | last = 0; | |
251 | first = 0; | |
252 | flag = kFALSE; | |
253 | diff = 0; | |
254 | word2=0; | |
255 | } | |
256 | ||
257 | for(Int_t tb=0;tb<256;tb++){ | |
258 | if(digarr[anode][tb]!=0){ | |
259 | if(flag){ | |
260 | last = first+diff-1; | |
261 | AliBitPacking::PackWord(word2,baseWord,first,last); | |
262 | flag = kFALSE; | |
263 | first = last+1; | |
264 | diff=0; | |
265 | } | |
266 | wordinfo1[1] = tb; | |
267 | //non lossy compression as it is done in Carlos | |
268 | //(data are already 10to8bit compressed by AMBRA | |
269 | ||
270 | /* if value < 8 value = value - (1 << 2) (word is 2 bit long) | |
271 | if value < 16 value = value - (1 << 3) (word is 3 bit long) | |
272 | if value < 32 value = value - (1 << 4) (word is 4 bit long) | |
273 | if value < 64 value = value - (1 << 5) (word is 5 bit long) | |
274 | if value <128 value = value - (1 << 6) (word is 6 bit long) | |
275 | if value >=128value = value - (1 << 7) (word is 7 bit long) | |
276 | ||
277 | */ | |
278 | //if(digarr[anode][tb]<4) continue; // not write <4 cnts above tL | |
279 | if(digarr[anode][tb]<8){ | |
280 | bitinfo1[3] = 2; | |
281 | wordinfo1[2] = 2; | |
282 | wordinfo1[3] = digarr[anode][tb]-(1 << bitinfo1[3]); | |
283 | } | |
284 | if(digarr[anode][tb]>=8 && digarr[anode][tb]<16){ | |
285 | bitinfo1[3] = 3; | |
286 | wordinfo1[2] = 3; | |
287 | wordinfo1[3] = digarr[anode][tb]-(1 << bitinfo1[3]); | |
288 | } | |
289 | if(digarr[anode][tb]>=16 && digarr[anode][tb]<32){ | |
290 | bitinfo1[3] = 4; | |
291 | wordinfo1[2] = 4; | |
292 | wordinfo1[3] = digarr[anode][tb]-(1 << bitinfo1[3]); | |
293 | } | |
294 | if(digarr[anode][tb]>=32 && digarr[anode][tb]<64){ | |
295 | bitinfo1[3] = 5; | |
296 | wordinfo1[2] = 5; | |
297 | wordinfo1[3] = digarr[anode][tb]-(1 << bitinfo1[3]); | |
298 | } | |
299 | if(digarr[anode][tb]>=64 && digarr[anode][tb]<128){ | |
300 | bitinfo1[3] = 6; | |
301 | wordinfo1[2] = 6; | |
302 | wordinfo1[3] = digarr[anode][tb]-(1 << bitinfo1[3]); | |
303 | } | |
304 | if(digarr[anode][tb]>=128){ | |
305 | bitinfo1[3] = 7; | |
306 | wordinfo1[2] = 7; | |
307 | wordinfo1[3] = digarr[anode][tb]-(1 << bitinfo1[3]); | |
308 | } | |
309 | ||
310 | for(Int_t ie=0;ie<4;ie++){ | |
311 | ||
312 | if(flag){ | |
313 | last = first+diff-1; | |
314 | AliBitPacking::PackWord(word2,baseWord,first,last); | |
315 | flag = kFALSE; | |
316 | first = last+1; | |
317 | diff=0; | |
318 | } | |
319 | last = first+bitinfo1[ie]-1; | |
320 | if(first < 30 && last < 30){ | |
321 | AliBitPacking::PackWord(wordinfo1[ie],baseWord,first,last); | |
322 | first = last+1; | |
323 | } | |
324 | else{ | |
325 | if(first<=29){ | |
326 | UInt_t w = AliBitPacking::UnpackWord(wordinfo1[ie],0,29-first); | |
327 | AliBitPacking::PackWord(w,baseWord,first,29); | |
328 | Int_t lb = 29-first+1; | |
329 | diff = bitinfo1[ie]-lb; | |
330 | word2 = AliBitPacking::UnpackWord(wordinfo1[ie],lb,lb+diff-1); | |
331 | flag = kTRUE; | |
332 | if(anode<256) word = 2;//channel 0 of carlos | |
333 | else word = 3; //channel 1 of carlos | |
334 | AliBitPacking::PackWord(word,baseWord,30,31); | |
335 | fIndex++; | |
336 | buf[fIndex]=baseWord; | |
337 | first=0; | |
338 | last = 0; | |
339 | baseWord=0; | |
340 | word = 0; | |
341 | } | |
342 | else{ | |
343 | word2 = wordinfo1[ie]; | |
344 | diff = bitinfo1[ie]; | |
345 | flag = kTRUE; | |
346 | if(anode<256) word = 2; //channel 0 of carlos | |
347 | else word = 3; //channel 1 of carlos | |
348 | AliBitPacking::PackWord(word,baseWord,30,31); | |
349 | fIndex++; | |
350 | buf[fIndex]=baseWord; | |
351 | first=0; | |
352 | last=0; | |
353 | baseWord=0; | |
354 | word = 0; | |
355 | } | |
356 | } | |
357 | } | |
358 | ||
359 | }//END IF | |
360 | ||
361 | }//end loop on tb | |
362 | ||
363 | for(Int_t i=0;i<2;i++){ | |
364 | if(flag){ | |
365 | last = first+diff-1; | |
366 | AliBitPacking::PackWord(word2,baseWord,first,last); | |
367 | flag = kFALSE; | |
368 | first = last+1; | |
369 | diff=0; | |
370 | } | |
371 | ||
372 | word = wordinfo2[i]; | |
373 | nbit = bitinfo2[i]; | |
374 | last = first+nbit-1; | |
375 | if(first < 30 && last < 30){ | |
376 | AliBitPacking::PackWord(word,baseWord,first,last); //3 bit code =1 -> next 18 bits for EOR | |
377 | first = last+1; | |
378 | } | |
379 | ||
380 | else{ | |
381 | if(first<=29){ | |
382 | UInt_t w = AliBitPacking::UnpackWord(word,0,29-first); | |
383 | AliBitPacking::PackWord(w,baseWord,first,29); | |
384 | Int_t lb = 29-first+1; | |
385 | diff = nbit-lb; | |
386 | word2 = AliBitPacking::UnpackWord(word,lb,lb+diff-1); | |
387 | flag = kTRUE; | |
388 | if(anode<256) word = 2; | |
389 | else word = 3; | |
390 | AliBitPacking::PackWord(word,baseWord,30,31); | |
391 | fIndex++; | |
392 | buf[fIndex]=baseWord; | |
393 | first=0; | |
394 | last = 0; | |
395 | baseWord=0; | |
396 | if(anode==255){ | |
397 | flag=kFALSE; | |
398 | word2=0; | |
399 | } | |
400 | } | |
401 | else{ | |
402 | word2 = word; | |
403 | diff = nbit; | |
404 | flag = kTRUE; | |
405 | if(anode<256) word = 2; | |
406 | else word = 3; | |
407 | AliBitPacking::PackWord(word,baseWord,30,31); | |
408 | fIndex++; | |
409 | buf[fIndex]=baseWord; | |
410 | first=0; | |
411 | last=0; | |
412 | baseWord=0; | |
413 | if(anode==255){ | |
414 | flag=kFALSE; | |
415 | word2=0; | |
416 | } | |
417 | } | |
418 | } | |
419 | } | |
420 | } //end for | |
421 | ||
422 | } | |
423 | if(fVerbose==2) | |
424 | ftxt.close(); | |
425 | return; | |
426 | }//end GetDigitsSDD | |
427 | ||
428 | //////////////////////////////////////////////////////////////////////////////////////// | |
429 | //PIXEL | |
430 | // | |
431 | ||
432 | void AliITSDDLRawData::GetDigitsSPD(TClonesArray *ITSdigits,Int_t mod,Int_t ddl, UInt_t *buf, AliITSFOSignalsSPD* foSignals){ | |
433 | //This method packs the SPD digits in a proper 32 structure | |
434 | //Since data is zero suppressed,the coordinates for the chip having zero digits | |
435 | //doesn't get listed in the galice.root file. However the SPD format requires | |
436 | //the empty chip to be written with chip header and chip trailer. | |
437 | ||
438 | Int_t chipLow = AliITSRawStreamSPD::GetOnlineChipFromOffline(mod,0); | |
439 | Int_t chipHigh = AliITSRawStreamSPD::GetOnlineChipFromOffline(mod,159); | |
440 | ||
441 | if (chipLow>chipHigh) {chipLow -= 4; chipHigh += 4;} | |
442 | UInt_t eq = AliITSRawStreamSPD::GetOnlineEqIdFromOffline(mod); | |
443 | UInt_t hs = AliITSRawStreamSPD::GetOnlineHSFromOffline(mod); | |
444 | ||
445 | // create int map to later hold all digits sorted | |
446 | AliITSIntMap* digMap = new AliITSIntMap(); | |
447 | ||
448 | UInt_t baseWord=0; | |
449 | ||
450 | Int_t ndigits = ITSdigits->GetEntries(); //number of digits in the current module | |
451 | //cout<<" Number of digits in the current module:"<<ndigits<<" module:"<<mod<<endl; | |
452 | ||
453 | // _______________________________________________________________________ | |
454 | // Preprocess the digits - sort them in integer map (Henrik Tydesjo) | |
455 | // Needed to have exact same order as in real raw data | |
456 | AliITSdigit *digs; | |
457 | ofstream ftxt; | |
458 | if (ndigits) { | |
459 | //loop over digits | |
460 | if (fVerbose==2) ftxt.open("SPDdigits.txt",ios::app); | |
461 | for (Int_t digit=0; digit<ndigits; digit++) { | |
462 | digs = (AliITSdigit*) ITSdigits->UncheckedAt(digit); | |
463 | /*--------------------------------------------------------------------------- | |
464 | * Each module contains 5 read out chips of 256 rows and 32 columns. | |
465 | * So, the cell number in Z direction varies from 0 to 159. | |
466 | * ---------------------------------------------------------------------*/ | |
467 | Int_t iz=digs->GetCoord1(); // Cell number in Z direction | |
468 | Int_t ix=digs->GetCoord2(); // Cell number in X direction | |
469 | ||
470 | if(fVerbose==2) ftxt<<"DDL:"<<ddl<<" Mod:"<<mod<<" Row:"<<ix<<" Col:"<<iz<<endl; | |
471 | UInt_t dummyDDL, dummyHS, chip, col, row; | |
472 | AliITSRawStreamSPD::OfflineToOnline(mod,iz,ix,dummyDDL,dummyHS,chip,col,row); | |
473 | ||
474 | // insert digit into map... | |
475 | // (reverse order of cols and rows as in real raw data) | |
476 | digMap->Insert(chip*256*32+(31-col)*256+(255-row),row); | |
477 | } | |
478 | } | |
479 | ||
480 | // _______________________________________________________________________ | |
481 | // Procedure for writing raw data (Henrik Tydesjo) | |
482 | // Reimplemented because of unreadability (5 Mar 2009) | |
483 | // Now also with fast-or signals | |
484 | Int_t previousChip = chipLow-1; | |
485 | Int_t chip = chipLow-1; | |
486 | UInt_t chipHitCount = 0; | |
487 | ||
488 | ||
489 | UInt_t nrHits = digMap->GetNrEntries(); | |
490 | for (UInt_t nHit=0; nHit<nrHits; nHit++) { | |
491 | ||
492 | Int_t key = digMap->GetKeyIndex(nHit); | |
493 | chip = key/(256*32); | |
494 | Int_t col = 31 - (key%(256*32))/256; | |
495 | Int_t row = digMap->GetValIndex(nHit); | |
496 | ||
497 | // add trailer for previous chip (if there was one...) | |
498 | if (chip>previousChip && previousChip>chipLow-1) { | |
499 | WriteChipTrailer(buf, chipHitCount, foSignals->GetSignal(eq,hs,previousChip), baseWord); | |
500 | } | |
501 | ||
502 | // add headers/trailers for chips without hits (if any) | |
503 | for (Int_t ch=previousChip+1; ch<chip; ch++) { | |
504 | WriteChipHeader(ch, hs, baseWord); | |
505 | WriteChipTrailer(buf, 0, foSignals->GetSignal(eq,hs,ch), baseWord); | |
506 | } | |
507 | ||
508 | // if new chip, add header | |
509 | if (chip>previousChip) { | |
510 | WriteChipHeader(chip, hs, baseWord); | |
511 | chipHitCount = 0; | |
512 | previousChip = chip; | |
513 | } | |
514 | ||
515 | chipHitCount++; | |
516 | ||
517 | // add pixel hit | |
518 | WriteHit(buf,row,col,baseWord); | |
519 | ||
520 | } | |
521 | ||
522 | // add trailer for last chip (if there was one...) | |
523 | if (chip>chipLow-1) { | |
524 | WriteChipTrailer(buf, chipHitCount, foSignals->GetSignal(eq,hs,chip), baseWord); | |
525 | } | |
526 | ||
527 | // add REMAINING headers/trailers for chips without hits (if any) | |
528 | for (Int_t ch=chip+1; ch<=chipHigh; ch++) { | |
529 | WriteChipHeader(ch, hs, baseWord); | |
530 | WriteChipTrailer(buf, 0, foSignals->GetSignal(eq,hs,ch), baseWord); | |
531 | } | |
532 | // _______________________________________________________________________ | |
533 | ||
534 | ||
535 | delete digMap; | |
536 | ||
537 | if(fVerbose==2) | |
538 | ftxt.close(); | |
539 | return; | |
540 | }//end GetDigitsSPD | |
541 | ||
542 | ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |
543 | ||
544 | Int_t AliITSDDLRawData::RawDataSPD(TBranch* branch, AliITSFOSignalsSPD* foSignals){ | |
545 | //This method creates the Raw data files for SPD detectors | |
546 | const Int_t kSize=21000; //256*32*5=40960 max number of digits per module | |
547 | UInt_t buf[kSize]; //One buffer cell can contain 2 digits | |
548 | fIndex=-1; | |
549 | ||
550 | TClonesArray*& digits = * (TClonesArray**) branch->GetAddress(); | |
551 | TString fileName; | |
552 | AliFstream* outfile; // logical name of the output file | |
553 | AliRawDataHeaderSim header; | |
554 | ||
555 | //loop over DDLs | |
556 | for(Int_t ddl=0;ddl<AliDAQ::NumberOfDdls("ITSSPD");ddl++){ | |
557 | fileName.Form("%s",AliDAQ::DdlFileName("ITSSPD",ddl)); //The name of the output file. | |
558 | outfile = new AliFstream(fileName.Data()); | |
559 | //write Dummy DATA HEADER | |
560 | UInt_t dataHeaderPosition=outfile->Tellp(); | |
561 | outfile->WriteBuffer((char*)(&header),sizeof(header)); | |
562 | //Loops over Modules of a particular DDL | |
563 | for (Int_t mod=0; mod<AliITSRawStreamSPD::kModulesPerDDL; mod++){ | |
564 | Int_t moduleNumber = AliITSRawStreamSPD::GetModuleNumber(ddl, mod); | |
565 | digits->Clear(); | |
566 | branch->GetEvent(moduleNumber); | |
567 | //For each Module, buf contains the array of data words in Binary format | |
568 | //fIndex gives the number of 32 bits words in the buffer for each module | |
569 | GetDigitsSPD(digits, moduleNumber, ddl, buf, foSignals); | |
570 | outfile->WriteBuffer((char *)buf,((fIndex+1)*sizeof(UInt_t))); | |
571 | for(Int_t i=0;i<(fIndex+1);i++){ | |
572 | buf[i]=0; | |
573 | }//end for | |
574 | fIndex=-1; | |
575 | }//end for | |
576 | ||
577 | //Write REAL DATA HEADER | |
578 | UInt_t currentFilePosition=outfile->Tellp(); | |
579 | outfile->Seekp(dataHeaderPosition); | |
580 | header.fSize=currentFilePosition-dataHeaderPosition; | |
581 | outfile->WriteBuffer((char*)(&header),sizeof(header)); | |
582 | delete outfile; | |
583 | }//end for | |
584 | ||
585 | return 0; | |
586 | } | |
587 | ||
588 | ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |
589 | ||
590 | Int_t AliITSDDLRawData::RawDataSSD(TBranch* branch){ | |
591 | ||
592 | //This method creates the Raw data files for SSD detectors | |
593 | const Int_t kSize=1536;//768*2 Number of stripe * number of sides(N and P) | |
594 | UInt_t buf[kSize]; | |
595 | fIndex=-1; | |
596 | ||
597 | TClonesArray*& digits = * (TClonesArray**) branch->GetAddress(); | |
598 | TString fileName; | |
599 | AliFstream* outfile; // logical name of the output file | |
600 | AliRawDataHeaderSim header; | |
601 | ||
602 | //loop over DDLs | |
603 | for(Int_t i=0;i<AliDAQ::NumberOfDdls("ITSSSD");i++){ | |
604 | fileName.Form("%s",AliDAQ::DdlFileName("ITSSSD",i)); //The name of the output file. | |
605 | outfile = new AliFstream(fileName.Data()); | |
606 | //write Dummy DATA HEADER | |
607 | UInt_t dataHeaderPosition=outfile->Tellp(); | |
608 | outfile->WriteBuffer((char*)(&header),sizeof(header)); | |
609 | ||
610 | //Loops over Modules of a particular DDL | |
611 | for (Int_t mod=0; mod<AliITSRawStreamSSD::kModulesPerDDL; mod++){ | |
612 | Int_t moduleNumber = AliITSRawStreamSSD::GetModuleNumber(i, mod); | |
613 | if(moduleNumber!=-1){ | |
614 | digits->Clear(); | |
615 | branch->GetEvent(moduleNumber); | |
616 | //For each Module, buf contains the array of data words in Binary format | |
617 | //fIndex gives the number of 32 bits words in the buffer for each module | |
618 | GetDigitsSSD(digits,mod,moduleNumber,i,buf); | |
619 | outfile->WriteBuffer((char *)buf,((fIndex+1)*sizeof(UInt_t))); | |
620 | fIndex=-1; | |
621 | }//end if | |
622 | }//end for | |
623 | ||
624 | //Write REAL DATA HEADER | |
625 | UInt_t currentFilePosition=outfile->Tellp(); | |
626 | outfile->Seekp(dataHeaderPosition); | |
627 | header.fSize=currentFilePosition-dataHeaderPosition; | |
628 | header.SetAttribute(0); // valid data | |
629 | outfile->WriteBuffer((char*)(&header),sizeof(header)); | |
630 | delete outfile; | |
631 | }//end for | |
632 | ||
633 | return 0; | |
634 | } | |
635 | ||
636 | ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |
637 | ||
638 | Int_t AliITSDDLRawData::RawDataSDD(TBranch* branch, const AliITSDDLModuleMapSDD* ddlsdd){ | |
639 | //This method creates the Raw data files for SDD detectors | |
640 | const Int_t kSize=131072; //256*512 | |
641 | UInt_t buf[kSize]; | |
642 | fIndex=-1; | |
643 | ||
644 | TClonesArray*& digits = * (TClonesArray**) branch->GetAddress(); | |
645 | TString fileName; | |
646 | AliFstream* outfile; // logical name of the output file | |
647 | AliRawDataHeaderSim header; | |
648 | ||
649 | if(fSDDRawFormat!=0){ | |
650 | for(Int_t ibit=0; ibit<8; ibit++) header.SetAttribute(ibit); | |
651 | }else{ | |
652 | for(Int_t ibit=0; ibit<5; ibit++) header.SetAttribute(ibit); | |
653 | for(Int_t ibit=5; ibit<8; ibit++) header.ResetAttribute(ibit); | |
654 | } | |
655 | UInt_t skippedword=0; | |
656 | UInt_t carlosFooterWord=0; | |
657 | UInt_t fifoFooterWord=0; | |
658 | UInt_t jitterWord=0; | |
659 | Bool_t retcode; | |
660 | retcode = AliBitPacking::PackWord(0x3FFFFFFF,carlosFooterWord,0,31); | |
661 | if(!retcode)AliError("AliBitPacking error\n"); | |
662 | retcode = AliBitPacking::PackWord(0x3F1F1F1F,fifoFooterWord,0,31); | |
663 | if(fSDDRawFormat!=0) retcode = AliBitPacking::PackWord(0x7F000000,jitterWord,0,31); | |
664 | else retcode = AliBitPacking::PackWord(0x80000000,jitterWord,0,31); | |
665 | ||
666 | //loop over DDLs | |
667 | for(Int_t i=0;i<AliDAQ::NumberOfDdls("ITSSDD");i++){ | |
668 | fileName.Form("%s",AliDAQ::DdlFileName("ITSSDD",i)); //The name of the output file. | |
669 | outfile = new AliFstream(fileName.Data()); | |
670 | //write Dummy DATA HEADER | |
671 | UInt_t dataHeaderPosition=outfile->Tellp(); | |
672 | outfile->WriteBuffer((char*)(&header),sizeof(header)); | |
673 | ||
674 | ||
675 | //first 1 "dummy" word to be skipped | |
676 | if(fSDDRawFormat!=0){ | |
677 | retcode = AliBitPacking::PackWord(0xFFFFFFFF,skippedword,0,31); | |
678 | outfile->WriteBuffer((char*)(&skippedword),sizeof(skippedword)); | |
679 | } | |
680 | ||
681 | //Loops over Modules of a particular DDL | |
682 | for (Int_t mod=0; mod<AliITSRawStreamSDD::kModulesPerDDL; mod++){ | |
683 | Int_t moduleNumber = ddlsdd->GetModuleNumber(i, mod); | |
684 | if(moduleNumber!=-1){ | |
685 | digits->Clear(); | |
686 | branch->GetEvent(moduleNumber); | |
687 | ||
688 | //For each Module, buf contains the array of data words in Binary format | |
689 | //fIndex gives the number of 32 bits words in the buffer for each module | |
690 | // cout<<"MODULE NUMBER:"<<mapSDD[i][mod]<<endl; | |
691 | if(fSDDRawFormat==0){ | |
692 | GetDigitsSDDCompressed(digits,mod,buf); | |
693 | outfile->WriteBuffer((char *)buf,((fIndex+1)*sizeof(UInt_t))); | |
694 | }else{ | |
695 | GetDigitsSDD(digits,mod,moduleNumber,i,buf); | |
696 | outfile->WriteBuffer((char *)buf,((fIndex+1)*sizeof(UInt_t))); | |
697 | for(Int_t iw=0;iw<3;iw++) outfile->WriteBuffer((char*)(&carlosFooterWord),sizeof(carlosFooterWord)); | |
698 | } | |
699 | fIndex=-1; | |
700 | }//end if | |
701 | }//end for | |
702 | // 12 words with FIFO footers (=4 FIFO x 3 3F1F1F1F words per DDL) | |
703 | if(fSDDRawFormat!=0){ | |
704 | for(Int_t iw=0;iw<12;iw++) outfile->WriteBuffer((char*)(&fifoFooterWord),sizeof(fifoFooterWord)); | |
705 | } | |
706 | outfile->WriteBuffer((char*)(&jitterWord),sizeof(jitterWord)); | |
707 | //Write REAL DATA HEADER | |
708 | UInt_t currentFilePosition=outfile->Tellp(); | |
709 | outfile->Seekp(dataHeaderPosition); | |
710 | header.fSize=currentFilePosition-dataHeaderPosition; | |
711 | header.SetAttribute(0); // valid data | |
712 | outfile->WriteBuffer((char*)(&header),sizeof(header)); | |
713 | delete outfile; | |
714 | }//end for | |
715 | ||
716 | return 0; | |
717 | } | |
718 | ||
719 | ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |
720 | ||
721 | void AliITSDDLRawData::WriteChipHeader(Int_t ChipAddr,Int_t halfStave,UInt_t &BaseWord){ | |
722 | //This method writes a chip header | |
723 | //cout<<"Chip: "<<ChipAddr<<" Half Stave module:"<<halfStave<<endl; | |
724 | BaseWord=0; | |
725 | AliBitPacking::PackWord(ChipAddr,BaseWord,16,19); | |
726 | // At the moment the event count is always 0 (bits 20-26) | |
727 | AliBitPacking::PackWord(0,BaseWord,20,26); | |
728 | AliBitPacking::PackWord(halfStave,BaseWord,27,29); | |
729 | AliBitPacking::PackWord(0x1,BaseWord,30,31); | |
730 | return; | |
731 | }//end WriteChipHeader | |
732 | ||
733 | ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |
734 | ||
735 | void AliITSDDLRawData::WriteChipTrailer(UInt_t *buf, Int_t ChipHitCount, Bool_t foBit, UInt_t &BaseWord){ | |
736 | //This method writes a chip trailer | |
737 | //pixel fill word | |
738 | if((ChipHitCount%2)!=0){ | |
739 | AliBitPacking::PackWord(0xC000,BaseWord,16,31); | |
740 | } | |
741 | AliBitPacking::PackWord(ChipHitCount,BaseWord,0,11); | |
742 | AliBitPacking::PackWord(0x0,BaseWord,12,12); | |
743 | AliBitPacking::PackWord(foBit,BaseWord,13,13); | |
744 | AliBitPacking::PackWord(0x0,BaseWord,14,15); | |
745 | fIndex++; | |
746 | buf[fIndex]=BaseWord; | |
747 | BaseWord=0; | |
748 | return; | |
749 | }//end WriteChipTrailer | |
750 | ||
751 | ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |
752 | ||
753 | void AliITSDDLRawData::WriteHit(UInt_t *buf,Int_t RowAddr,Int_t HitAddr,UInt_t &BaseWord){ | |
754 | //This method writs an hit | |
755 | if(!BaseWord){ | |
756 | AliBitPacking::PackWord(HitAddr,BaseWord,16,20); | |
757 | AliBitPacking::PackWord(RowAddr,BaseWord,21,28); | |
758 | AliBitPacking::PackWord(2,BaseWord,30,31); | |
759 | }//end if | |
760 | else{ | |
761 | AliBitPacking::PackWord(HitAddr,BaseWord,0,4); | |
762 | AliBitPacking::PackWord(RowAddr,BaseWord,5,12); | |
763 | AliBitPacking::PackWord(2,BaseWord,14,15); | |
764 | fIndex++; | |
765 | buf[fIndex]=BaseWord; | |
766 | BaseWord=0; | |
767 | }//end else | |
768 | return; | |
769 | }//end WriteHit | |
770 |