/* $Id$ */
//_________________________________________________________________________
-// Short description
+// Class designed to convert raw data to aliroot format. We assume, that
+// prototype is situated in the center of 3 PHOS module and convert prototype
+// outpur to AliPHOSDigits. In addition, we fill branch of TreeE with
+// AliPHOSBeamTestEvent, contaning description of event(triggers etc).
+// Note, that one byte per channel in raw data is transvormed to class
+// AliPHOSDigit, so finale zise increase ~ 100 times. So output can be split
+// into peases of reasonable size: each file can not contain more than
+// fMaxPerFile: if there are still events in raw file, then new directory
+// is created and header+digits files are written to it.
+//
+// Use Case:
+// AliPHOSRaw2Digits * r = new AliPHOSRaw2Digits("path/input.file") ;
+// //note, that it can be gzipped file!
+// //Set position of the target in the given run.
+// //Z axis along beam direction, from target to prototype (0-surface of prototype)
+// //X axis along columns of prototype (0-center of prototype)
+// //Y axis along raws of prototype (0-center of prototype)
+// Double_t pos[3]={0,0,-452.} ;
+// r->SetTargetPosition(pos) ;
+// //Read/create connection Table:
+// TFile f("ConTableDB.root") ;
+// AliPHOSConTableDB * cdb = f.Get("AliPHOSConTableDB") ;
+// f.Close() ;
+// r->SetConTableDB(cdb) ;
+// r->ExecuteTask() ;
+//
+// As a result files galice.root and PHOS.Digits.root should be produced in
+// current dir, and, possibly, dirs 1,2,3... each with galice.root and PHOS.Digits.root,
+// where the rest of data are written.
//
/*-- Author: Maxim Volkov (RRC KI)
Dmitri Peressounko (RRC KI & SUBATECH)
#include "TClonesArray.h"
#include "TFile.h"
#include "TTree.h"
+#include "TSystem.h"
+//#include "Bytes.h"
// --- Standard library ---
-#include <iostream.h>
-//#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include <ctype.h>
-#include <stdio.h>
-#include <stdlib.h>
+
#include <unistd.h>
-#include <string.h>
-#include <netinet/in.h>
// --- AliRoot header files ---
#include "AliPHOSDigit.h"
//____________________________________________________________________________
AliPHOSRaw2Digits::AliPHOSRaw2Digits():TTask()
{
+ //As one can easily see, this is constructor.
fInName="";
fMK1 = 0x0123CDEF ;
fMK2 = 0x80708070 ;
fMK4 = 0x80618061 ;
fCKW = 0x4640E400 ;
fDebug = kFALSE; // Debug flag
+ fToSplit = kFALSE ;
fIsInitialized = kFALSE ;
fTarget[0] = 0 ;
fTarget[1] = 0 ;
fTarget[2] = 0 ;
fDigits = 0 ;
+ fHeaderFile = 0 ;
+ fDigitsFile = 0 ;
fPHOSHeader =0 ;
+ fMaxPerFile = 20000 ; //Maximal number of events in root file.
fEvent = 0 ;
fctdb = 0;
}
//____________________________________________________________________________
- AliPHOSRaw2Digits::AliPHOSRaw2Digits(const char * filename):TTask("Default","")
+ AliPHOSRaw2Digits::AliPHOSRaw2Digits(const char * filename,Bool_t toSplit):TTask("Default","")
{
+ //this constructor should be normally used. Parameters: imput file and should we produce output in split mode.
fInName=filename;
- TString outname(fInName) ;
- outname.ToLower() ;
- outname.ReplaceAll(".fz",".root") ;
- outname.ReplaceAll(".gz","") ;
+ fToSplit = toSplit ;
+ TString outname("") ;
+ if(fToSplit)
+ outname = "galice.root" ;
+ else{
+ outname =fInName ;
+ outname.ToLower() ;
+ outname.ReplaceAll(".fz",".root") ;
+ outname.ReplaceAll(".gz","") ;
+ }
SetTitle(outname) ;
fMK1 = 0x0123CDEF ;
fTarget[2] = 0 ;
fDigits = 0 ;
fPHOSHeader =0 ;
+ fHeaderFile = 0 ;
+ fDigitsFile = 0 ;
+ fMaxPerFile = 20000 ;
fEvent = 0 ;
fctdb = 0;
}
+//____________________________________________________________________________
+AliPHOSRaw2Digits::AliPHOSRaw2Digits(AliPHOSRaw2Digits & r2d):TTask(r2d.GetName(), r2d.GetTitle())
+{
+ fInName=r2d.fInName ;
+ fToSplit = r2d.fToSplit ;
+
+ fMK1 = r2d.fMK1 ;
+ fMK2 = r2d.fMK2 ;
+ fMK3 = r2d.fMK3 ;
+ fMK4 = r2d.fMK4 ;
+ fCKW = r2d.fCKW ;
+ fDebug = kFALSE; // Debug flag
+ fIsInitialized = kFALSE ;
+ fTarget[0] = r2d.fTarget[0] ;
+ fTarget[1] = r2d.fTarget[1] ;
+ fTarget[2] = r2d.fTarget[2] ;
+ fDigits = r2d.fDigits ;
+ fPHOSHeader = r2d.fPHOSHeader ;
+ fHeaderFile = new TFile( (r2d.fHeaderFile)->GetName(), "new" ) ;
+ fDigitsFile = new TFile( (r2d.fDigitsFile)->GetName(), "new" ) ;
+ fMaxPerFile = r2d.fMaxPerFile ;
+ fEvent = r2d.fEvent ;
+ fctdb = new AliPHOSConTableDB( *(r2d.fctdb) ) ;
+}
//____________________________________________________________________________
AliPHOSRaw2Digits::~AliPHOSRaw2Digits()
{
+//destructor
if(fPHOSHeader)
fPHOSHeader->Delete() ;
if(fDigits){
ProcessRawFile() ;
- FinishRun() ;
}
//____________________________________________________________________________
Bool_t AliPHOSRaw2Digits::Init(void){
- //Create PHOS geometry, sets magnetic field to zero,
- //create Generator - to store target position,
- //opens out file, creates TreeE and make initialization of contaniers
-
+ //Makes initialization of contaniers
if(fIsInitialized)
return kTRUE;
+ //Make container for digits
+ fDigits = new TClonesArray("AliPHOSDigit",1000) ;
+ fPHOSHeader = new AliPHOSBeamTestEvent() ;
+ fIsInitialized = kTRUE ;
+ return StartRootFiles() ;
+
+}
+//____________________________________________________________________________
+Bool_t AliPHOSRaw2Digits::StartRootFiles(void ){
+ //Create PHOS geometry, sets magnetic field to zero,
+ //create Generator - to store target position,
+ //opens out file, creates TreeE
+
+ //create gAlice if nececcary
+ if(!gAlice)
+ new AliRun("gAlice","The ALICE Off-line Simulation Framework") ;
+
//Create PHOS
- new AliPHOSv1("PHOS","GPS2") ;
+ if(!gAlice->GetModule("PHOS"))
+ new AliPHOSv1("PHOS","GPS2") ;
//Set Magnetic field
gAlice->SetField(0,2);
//Set positin of the virtex
- AliGenBox *gener = new AliGenBox(1);
+ AliGenerator * gener = gAlice->Generator() ;
+ if(!gener)
+ gener = new AliGenBox(1);
Float_t ox = fTarget[1];
- Float_t oy = fTarget[2]-460.;
+ Float_t oy = fTarget[2]+460.;
Float_t oz = fTarget[0];
gener->SetOrigin(ox, oy, oz);
+ //make directory
+ Int_t nRootFile = (fEvent+1)/fMaxPerFile ;
+ if(nRootFile){
+ char dname[20];
+ sprintf(dname,"%d",nRootFile) ;
+ if(gSystem->AccessPathName(dname)) //strange return: 0 if exists
+ if(gSystem->MakeDirectory(dname)!=0)
+ Fatal("StartRootFiles","Can not make directory %s \n",dname) ;
+
+ if(!gSystem->ChangeDirectory(dname))
+ Fatal("StartRootFiles","Can not cd to %s\n",dname) ;
+ }
+
// Create the output file
TString outname("") ;
if(strstr(GetTitle(),"root")){
outname.ToLower() ;
outname.ReplaceAll(".fz",".root") ;
}
- TFile *rootfile = new TFile(outname,"recreate");
- rootfile->SetCompressionLevel(2);
+ fHeaderFile = new TFile(outname,"recreate");
+ fHeaderFile->SetCompressionLevel(2);
+
// Create the Root Trees
gAlice->MakeTree("E") ;
-
- //Make container for digits
- fDigits = new TClonesArray("AliPHOSDigit",1000) ;
-
+
//Fill now TreeE
- fPHOSHeader = new AliPHOSBeamTestEvent() ;
Int_t splitlevel = 0 ;
Int_t bufferSize = 32000 ;
TBranch * headerBranch = gAlice->TreeE()->Branch("AliPHOSBeamTestEvent",
&fPHOSHeader,bufferSize,splitlevel);
headerBranch->SetName("AliPHOSBeamTestEvent") ;
- fIsInitialized = kTRUE ;
+ if(fToSplit){
+ fDigitsFile = new TFile("PHOS.Digits.root","recreate") ;
+ fDigitsFile->SetCompressionLevel(2) ;
+ }
return kTRUE ;
}
//____________________________________________________________________________
-Bool_t AliPHOSRaw2Digits::ProcessRawFile(){
+Bool_t AliPHOSRaw2Digits::CloseRootFiles(void ){
+ //cleans everething to start next root file
+ if(fHeaderFile){
+ printf("writing gAlice \n") ;
+ fHeaderFile->cd() ;
+ gAlice->Write(0,TObject::kOverwrite);
+ gAlice->TreeE()->Write(0,TObject::kOverwrite);
+ }
+ delete gAlice ;
+
+ if(fHeaderFile){
+ fHeaderFile->Close() ;
+ delete fHeaderFile ;
+ fHeaderFile = 0;
+ }
+
+ if(fDigitsFile){
+ fDigitsFile->Close() ;
+ delete fDigitsFile ;
+ fDigitsFile = 0 ;
+ }
+
+ Int_t nRootFile = (fEvent-1)/fMaxPerFile ;
+ if(nRootFile){
+ if(!gSystem->ChangeDirectory("../")){
+ Fatal("CloseRootFile","Can not return to initial dir \n") ;
+ return kFALSE ;
+ }
+ }
+ return kTRUE ;
+}
+//____________________________________________________________________________
+Bool_t AliPHOSRaw2Digits::ProcessRawFile(){
+
//Method opens zebra file and reads successively bytes from it,
//filling corresponding fields in header and digits.
-
-
+
+
fStatus= -3 ;
//First of all, open file and check if it is a zebra file
-
+
char command[256];
sprintf(command,"zcat %s",fInName.Data());
FILE *dataFile = popen(command, "r");
if (dataFile == NULL) {
- cout << " Can not open file " << fInName.Data() << endl ;
+ Warning("ProcessRawFile", " Cannot open file %s\n", fInName.Data() ) ;
perror(fInName.Data()) ;
fStatus = -1 ;
return kFALSE ;
}
- printf("Open pipe: %s\n",command);
// Check if byte ordering is little-endian
UInt_t w = 0x12345678;
Int_t swapo = memcmp(&w, "\x78\x56\x34\x12", sizeof(UInt_t)) == 0;
if(fDebug)
- cout << "swapo=" << swapo << endl;
+ Info("ProcessRawFile", "swapo=%f\n", swapo ) ;
UInt_t recBuf[300] ;
if (n < 0 )
perror(fInName.Data());
else
- cout << "Could not read physical record control words" << endl;
+ Error("ProcessRawFile", "Could not read physical record control words" ) ;
fStatus = -2 ;
return kFALSE;
}
if(fDebug)
- cout << "recbuf[0] = " << recBuf[0] << endl ;
+ Info("ProcessRawFile", "recbuf[0] = %d\n", recBuf[0] );
// Check if it is a ZEBRA file and if the words are swapped
UInt_t swapi = 0 ;
if (recBuf[0] != fMK1) {
Swab4(recBuf, &w, 1);
if (w != fMK1) {
- cout << "Does not look like a ZEBRA file\n";
+ Error("ProcessRawFile", "Does not look like a ZEBRA file\n" ) ;
pclose(dataFile) ;
fStatus = -2 ;
return kFALSE;
}
if(fDebug){
- cout << " w = " << w << endl ;;
- cout << " swapi = " << swapi << endl ;;
+ TString message ;
+ message = " w = %f\n" ;
+ message += " swapi = %f\n" ;
+ Info("ProcessRawFile", message.Data(), w, swapi ) ;
}
// Get number of words in physical record
// StartNewEvent() ;
fDigits->Delete() ;
- gAlice->SetEvent(fEvent) ;
+ if((fEvent%fMaxPerFile == 0) && fEvent ){
+ CloseRootFiles() ;
+ StartRootFiles() ;
+ }
+ gAlice->SetEvent(fEvent%fMaxPerFile) ;
+
+ //Set Beam Energy
+ fPHOSHeader->SetBeamEnergy(fBeamEnergy) ;
Int_t i ;
for(i=0;i<16;i++)
UInt_t * recptr = recBuf; //Pointer to current position
if(recptr[7] != 1) {
- cout << "Can not handle fast blocks" << endl;
+ Error("ProcessRawFile", "Cannot handle fast blocks" ) ;
fStatus = -2 ;
return kFALSE;
}
// Logical record control words
UInt_t lrtyp = recptr[1];
if (lrtyp != 3) {
- cout << "Can not handle logical record type " << lrtyp << endl ;
+ Error("ProcessRawFile", "Can not handle logical record type %d", lrtyp ) ;
fStatus = -2 ;
return kFALSE;
}
recptr += 2;
if (recptr[0] != fCKW) {
- cout << "Bad check word" << endl;
+ Error("ProcessRawFile", "Bad check word" ) ;
fStatus = -2 ;
return kFALSE;
}
UInt_t evtno = recptr[2]; /* Event number */
if(fDebug)
- cout << "evtno=" << evtno << endl;
+ Info("ProcessRawFile", "evtno= %d", evtno);
UInt_t nh = recptr[4]; /* Number of header words in data bank */
recptr += nh;
UChar_t *byteptr=(UChar_t*)recptr;
// Trigger bit register
- pattern=ntohs(*(UShort_t*)byteptr);
+ pattern=net2host(*(UShort_t*)byteptr);
fPHOSHeader->SetPattern(pattern) ;
byteptr+=sizeof(UShort_t);
//or Kurchatov 64+2 channel ADC
//(the rest of the channels padded with 0xffff)
for(i=0;i<80;i++){
- Int_t peak = static_cast<Int_t>(ntohs(*(UShort_t*)byteptr));
+ Int_t peak = static_cast<Int_t>(net2host(*(UShort_t*)byteptr));
//make digit
Int_t absID = fctdb->Raw2AbsId(i) ;
if(absID > 0)
new((*fDigits)[i])AliPHOSDigit(-1,absID,peak,0.,i) ;
if(fDebug){
if(peak>(UShort_t)1000)
- cout << "event=" << fEvent << " peak[" << i << "] = "<<peak << endl;
+ Info("ProcessRawFile", "event= %d peak[%d] = %f", fEvent, i, peak);
}
byteptr+=sizeof(UShort_t);
}
// Scanning ADCs, 4 modulesX8=32 channels
for(i=0;i<32;i++){
- scanning[i]=ntohs(*(UShort_t*)byteptr);
+ scanning[i]=net2host(*(UShort_t*)byteptr);
byteptr+=sizeof(UShort_t);
}
fPHOSHeader->SetScanning(scanning) ;
// Charge ADCs, 1 moduleX12=12 channels
for(i=0;i<12;i++){
- charge[i]=ntohs(*(UShort_t*)byteptr);
+ charge[i]=net2host(*(UShort_t*)byteptr);
byteptr+=sizeof(UShort_t);
}
fPHOSHeader->SetCharge(charge) ;
// Scalers, 1 moduleX12=12 (4 byte) channels
for(i=0;i<12;i++){
- scaler[i]=ntohl(*(UInt_t*)byteptr);
+ scaler[i]=net2host(*(UInt_t*)byteptr);
byteptr+=sizeof(UInt_t);
}
fPHOSHeader->SetScaler(scaler) ;
// LeCroy TDC 2228A, 4 moduleX8=32 channels
for(i=0;i<8;i++){
- tdc2228[i]=ntohs(*(UShort_t*)byteptr);
+ tdc2228[i]=net2host(*(UShort_t*)byteptr);
byteptr+=sizeof(UShort_t);
}
fPHOSHeader->SetTDC(tdc2228) ;
WriteDigits() ;
if(fDebug)
- cout << "event=" << fEvent << " written " << endl;
+ Info("ProcessRawFile", "event= %d written", fEvent) ;
// Read next record
UInt_t nb = nwphr *sizeof(UInt_t);
}
fEvent++ ;
}
+ CloseRootFiles() ;
fStatus = 1 ;
return kTRUE ;
}
+
//____________________________________________________________________________
-void AliPHOSRaw2Digits::Swab4(void *from, void *to, size_t nwords){
+void AliPHOSRaw2Digits::Swab4(void *from, void *to, size_t nwords)const
+{
// The function swaps 4 bytes: byte#3<-->byte#0, byte#2<-->byte#1
register char *pf=static_cast<char*>(from) ;
register char *pt=static_cast<char*>(to) ;
}
//____________________________________________________________________________
-void AliPHOSRaw2Digits::Swab2(void *from, void *to, size_t nwords)
-{ //The function swaps 2x2 bytes: byte#0<-->byte#1, byte#2<-->byte#3
+void AliPHOSRaw2Digits::Swab2(void *from, void *to, size_t nwords)const
+{
+ //The function swaps 2x2 bytes: byte#0<-->byte#1, byte#2<-->byte#3
register char *pf=static_cast<char*>(from) ;
register char *pt=static_cast<char*>(to);
register char c;
}
}
-//____________________________________________________________________________
-void AliPHOSRaw2Digits::FinishRun(){
- //Write geometry and header tree
- gAlice->Write(0,TObject::kOverwrite);
- gAlice->TreeE()->Write(0,TObject::kOverwrite);
-
-}
//____________________________________________________________________________
void AliPHOSRaw2Digits::WriteDigits(void){
//In this method we create TreeD, write digits and Raw2Digits to it
static_cast<AliPHOSDigit*>(fDigits->At(i))->SetIndexInList(i) ;
char hname[30];
- sprintf(hname,"TreeD%d",fEvent);
+ sprintf(hname,"TreeD%d",fEvent%fMaxPerFile);
TTree * treeD = new TTree(hname,"Digits");
//treeD->Write(0,TObject::kOverwrite);
TBranch * digitizerBranch = treeD->Branch("AliPHOSRaw2Digits",
"AliPHOSRaw2Digits", &d,bufferSize,splitlevel);
digitizerBranch->SetTitle("Default");
-
+
+ if(fDigitsFile)
+ fDigitsFile->cd() ;
digitsBranch->Fill() ;
digitizerBranch->Fill() ;
treeD->Write(0,TObject::kOverwrite);
delete treeD ;
//Write header
+ fHeaderFile->cd() ;
gAlice->TreeE()->Fill();
}
//____________________________________________________________________________
void AliPHOSRaw2Digits::Print(Option_t * option)const{
-
- cout << "----------AliPHOSRaw2Digits----------" << endl ;
- cout << "Input stream " << endl ;
- cout << "Current input File: " << fInName.Data() << endl ;
- cout << "Current output File: " << GetTitle() << endl ;
- cout << "Events processes in the last file " << fEvent << endl ;
- cout << "Input file status " ;
+ //prints current configuration and status.
+
+ printf("----------AliPHOSRaw2Digits---------- \n") ;
+ printf("Current input File: %s\n",fInName.Data()) ;
+ printf("Current output File: %s\n", GetTitle());
+ printf("Events processes in the last file %d\n",fEvent) ;
+ printf("Input file status\n") ;
switch (fStatus){
- case 0: cout << "`Have not processed yet' " << endl ;
+ case 0: printf("`Have not processed yet'\n") ;
break ;
- case 1: cout << "`Processed normally' " << endl ;
+ case 1: printf("`Processed normally'\n") ;
break ;
- case -1: cout << "`File not found'" << endl ;
+ case -1: printf("`File not found'\n") ;
break ;
- case -2: cout << "`Error in reading' " << endl ;
+ case -2: printf("`Error in reading'\n") ;
break ;
- case -3: cout << "'Interupted'" << endl ;
+ case -3: printf("'Interupted'\n") ;
default: ;
}
- cout << "Connection table: " ;
+ printf("Connection table: " );
if(fctdb)
- cout << fctdb->GetName() << " " << fctdb->GetTitle() << endl ;
+ printf("%s %s \n",fctdb->GetName(), fctdb->GetTitle() ) ;
else
- cout << " no DB " << endl ;
-
+ printf(" no DB \n" );
+
}