/*
-DAcase2.c
+TOF DA for online calibration
-This program connects to the DAQ data source passed as argument
-and populates local "./result.txt" file with the ids of events received
-during the run.
+Contact: Chiara.Zampolli@bo.infn.it
+ Roberto.Preghenella@bo.infn.it
-The program exits when being asked to shut down (daqDA_checkshutdown)
-or End of Run event.
-
-Messages on stdout are exported to DAQ log system.
-
-contact: alice-datesupport@cern.ch
+Run Type: PHYSICS
+DA Type: MON
+Number of events needed:
+Input Files: no input
+Output Files: TOFdaHits.root
+Event types used: PHYSICS_EVENT
*/
-extern "C" {
-#include <daqDA.h>
-}
+#define FILE_HITS "TOFdaHits.root"
+#define FILE_CALIB "TOFdaCalib.root"
+
+// DATE
#include "event.h"
#include "monitor.h"
-//#include "daqDA.h"
+#include "daqDA.h"
-#include <Riostream.h>
#include <stdio.h>
#include <stdlib.h>
+#include <errno.h>
//AliRoot
+#include "TROOT.h"
#include "AliTOFRawStream.h"
#include "AliRawReaderDate.h"
+#include "AliRawReader.h"
+#include "AliDAQ.h"
+#include "AliTOFHitData.h"
+#include "AliTOFHitDataBuffer.h"
+#include "AliTOFDaConfigHandler.h"
+#include "AliTOFHitField.h"
+#include "AliLog.h"
#include "AliTOFGeometry.h"
-#include "AliTOFGeometryV5.h"
-#include "AliT0digit.h"
-#include "AliT0RawReader.h"
//ROOT
#include "TFile.h"
#include "TKey.h"
#include "TH2S.h"
#include "TObject.h"
-#include "TBenchmark.h"
-#include "TRandom.h"
-
+#include "TMath.h"
+#include "TSystem.h"
+#include "TROOT.h"
+#include "TPluginManager.h"
+#include "TSAXParser.h"
+#include "TTree.h"
/* Main routine
Arguments:
1- monitoring data source
*/
-int main(int argc, char **argv) {
+int
+main(int argc, char **argv)
+{
- AliTOFGeometry * geomV5 = new AliTOFGeometryV5();
- AliTOFGeometry * geom = new AliTOFGeometry();
-
- static const Int_t size = geomV5->NPadXSector()*geomV5->NSectors();
- static const Int_t nbins = 500;
- static const Int_t binmin = -20;
- const Float_t c = 2.99792458E10; //speed of light
- TH1F::AddDirectory(0);
- TH2S * htofPartial = new TH2S("htof","histo with delays", size,-0.5,size*1.-0.5,nbins,binmin-0.5,nbins*1.+binmin-0.5);
+ /* magic line from Rene */
+ gROOT->GetPluginManager()->AddHandler("TVirtualStreamerInfo",
+ "*",
+ "TStreamerInfo",
+ "RIO",
+ "TStreamerInfo()");
- TRandom *rand = new TRandom(); //to be used for testing with cosmic data
- rand->SetSeed(0); //to be used for testing with cosmic data
- //TTree *tree = 0x0; // tree for T0 decoder
-
- // decoding the events
+ /* log start of process */
+ printf("TOF DA started\n");
- int status;
- bool decodeStatus;
+ /* check that we got some arguments = list of files */
if (argc!=2) {
printf("Wrong number of arguments\n");
return -1;
}
- /* open result file */
- FILE *fp=NULL;
- fp=fopen("./result.txt","a");
- if (fp==NULL) {
- printf("Failed to open file\n");
+ /*
+ * CONFIG
+ */
+
+ /* retrieve config file */
+ int getConfigFile = daqDA_DB_getFile("TOFPhysicsConfig.xml","TOFPhysicsConfig.xml");
+ if (getConfigFile != 0){
+ printf("Failed to retrieve config file from DB! returning...\n");
return -1;
}
+ /* parse config file */
+ AliTOFDaConfigHandler* tofHandler = new AliTOFDaConfigHandler();
+ TSAXParser *parser = new TSAXParser();
+ parser->ConnectToHandler("AliTOFDaConfigHandler", tofHandler);
+ if (parser->ParseFile("./TOFPhysicsConfig.xml") != 0) {
+ printf("Failed parsing config file! retunring... \n");
+ return -1;
+ }
+ /* setup config params */
+ Int_t meanMultiplicity = tofHandler->GetMeanMultiplicity(); /* average expected TOF multiplicity */
+ Int_t maxHits = tofHandler->GetMaxHits(); /* max number of hits to be collected */
+ printf("current settings:\n");
+ printf(" - meanMultiplicity = %d\n", meanMultiplicity);
+ printf(" - maxHits = %d\n", maxHits);
+ /* constants */
+ const Int_t nChannels = 157248;
+ Int_t noiseCheckTrigger = 10; /* first noise check after 10 events */
+ Float_t meanChannelRate = (Float_t)meanMultiplicity / (Float_t)nChannels; /* average expected channel rate (hits/event) */
+ Float_t noiseThreshold = 10. * meanChannelRate; /* noise threshold (hits/event) */
+ Int_t minNoiseHits = 10; /* min number of channel hits to check noise */
+ /* counters and flags */
+ Int_t nPhysicsEvents, nCalibEvents, totHits;
+ Int_t nChHits[nChannels];
+ Bool_t inhibitCollection;
+ Bool_t noiseFlag[nChannels];
+ /* variables */
+ Int_t nhits, ddl, slot, trm, chain, tdc, channel, index, timebin, totbin, deltaBC, l0l1latency, det[5], dummy;
+ Float_t noiseHitThreshold;
+
+ /*
+ * INIT
+ */
+
+ /* init counters and flags */
+ nPhysicsEvents = 0;
+ nCalibEvents = 0;
+ totHits = 0;
+ inhibitCollection = kFALSE;
+ for (Int_t ich = 0; ich < nChannels; ich++) {
+ nChHits[ich] = 0;
+ noiseFlag[ich] = kFALSE;
+ }
+ /* TOF raw data handling */
+ AliTOFRawStream *rawStream = new AliTOFRawStream();
+ AliTOFHitDataBuffer *pdb = NULL;
+ AliTOFHitData *hit = NULL;
+
+ /* open HITS output file */
+ TFile *fileOutHits = new TFile(FILE_HITS, "RECREATE");
+ /* create hit field data structure */
+ AliTOFHitField *hitField = new AliTOFHitField();
+ /* create temporary tree */
+ TTree *tempTree = new TTree("tempTree", "temporary tree");
+ tempTree->Branch("hit", "AliTOFHitField", &hitField);
+ /* create output tree */
+ TTree *outTree = new TTree("hitTree", "hit tree");
+ outTree->Branch("hit", "AliTOFHitField", &hitField);
+
+ /* open CALIB output file */
+ TFile *fileOutCalib = new TFile(FILE_CALIB, "RECREATE");
+ /* create calib hit histo */
+ TH1F *hCalibHit = new TH1F("hCalibHit", "Calibration events;index;N_{hits}/N_{events}", nChannels, 0., nChannels);
+
+ /*
+ * ONLINE MONITOR
+ */
+
+ AliLog::SetGlobalLogLevel(AliLog::kFatal);
+ struct eventHeaderStruct *event;
+ int ret;
/* define data source : this is argument 1 */
- status=monitorSetDataSource( argv[1] );
- if (status!=0) {
- printf("monitorSetDataSource() failed : %s\n",monitorDecodeError(status));
+ ret = monitorSetDataSource(argv[1]);
+ if (ret != 0) {
+ printf("monitorSetDataSource() failed : %s\n",monitorDecodeError(ret));
return -1;
}
-
/* declare monitoring program */
- status=monitorDeclareMp( __FILE__ );
- if (status!=0) {
- printf("monitorDeclareMp() failed : %s\n",monitorDecodeError(status));
+ ret = monitorDeclareMp("tofDA");
+ if (ret != 0) {
+ printf("monitorDeclareMp() failed : %s\n",monitorDecodeError(ret));
return -1;
}
-
/* define wait event timeout - 1s max */
monitorSetNowait();
monitorSetNoWaitNetworkTimeout(1000);
-
- /* log start of process */
- printf("DA example case2 monitoring program started\n");
-
- /* init some counters */
- int nevents_physics=0;
- int nevents_total=0;
-
- struct equipmentStruct *equipment;
- int *eventEnd;
- int *eventData;
- int *equipmentEnd;
- int *equipmentData;
- int *equipmentID;
- struct eventHeaderStruct *event;
- eventTypeType eventT;
- Int_t iev=0;
- /* main loop (infinite) */
- for(;;) {
+ /* loop over events */
+ while (1) {
/* check shutdown condition */
- if (daqDA_checkShutdown()) {break;}
+ if (daqDA_checkShutdown()) break;
+
+ /*
+ * NOISE CHECK
+ */
+
+ /* check inhibit collection */
+ if (!inhibitCollection) {
+ /* check number of events and check noise */
+ if (nPhysicsEvents >= noiseCheckTrigger || totHits >= maxHits) {
+ noiseHitThreshold = noiseThreshold * nPhysicsEvents;
+ printf("noise check triggered after %d events: threshold is %f hits\n", nPhysicsEvents, noiseHitThreshold);
+ /* loop over all channels */
+ for (Int_t ich = 0; ich < nChannels; ich++) {
+ /* check */
+ if (nChHits[ich] < minNoiseHits || noiseFlag[ich] || nChHits[ich] < noiseHitThreshold) continue;
+ printf("channel %d tagged as noisy (%d hits): disabled\n", ich, nChHits[ich]);
+ noiseFlag[ich] = kTRUE;
+ totHits -= nChHits[ich];
+ } /* end of loop over all channels */
+ /* set new noise check trigger value */
+ noiseCheckTrigger *= 10;
+ } /* end of noise check */
+
+ /* inhibit hit collection when maximum number of hits exceeded */
+ if (totHits >= maxHits) {
+ printf("maximum number of hits exceeded (%d): inhibit hit collection\n", maxHits);
+ inhibitCollection = kTRUE;
+ }
+ }
+ /*
+ * GET EVENT
+ */
+
/* get next event (blocking call until timeout) */
- status=monitorGetEventDynamic((void **)&event);
- if (status==MON_ERR_EOF) {
+ ret = monitorGetEventDynamic((void **)&event);
+ if (ret == MON_ERR_EOF) {
printf ("End of File detected\n");
break; /* end of monitoring file has been reached */
}
-
- if (status!=0) {
- printf("monitorGetEventDynamic() failed : %s\n",monitorDecodeError(status));
+ if (ret != 0) {
+ printf("monitorGetEventDynamic() failed (ret=%d errno=%d): %s\n", ret, errno, monitorDecodeError(ret));
break;
}
-
/* retry if got no event */
- if (event==NULL) {
+ if (event==NULL) continue;
+ /* check event type */
+ if (event->eventType != PHYSICS_EVENT && event->eventType != CALIBRATION_EVENT) {
+ free(event);
continue;
}
-
- iev++;
-
- /* use event - here, just write event id to result file */
- eventT=event->eventType;
- switch (event->eventType){
-
- /* START OF RUN */
- case START_OF_RUN:
- break;
- /* END START OF RUN */
-
- /* END OF RUN */
- case END_OF_RUN:
- break;
-
- case PHYSICS_EVENT:
- printf(" event number = %i \n",iev);
- //if (iev%10000 ==0) printf(" event number = %i \n",iev);
- //if (iev > 50000) break;
- AliRawReader *rawReader = new AliRawReaderDate((void*)event);
- // rawReader->RequireHeader(kFALSE);
- //rawReader->LoadEquipmentIdsMap("TOFmap.txt"); //to be used if no exact mapping implemented
- Int_t meantime = 0;
-
-
- // TTree *tree = new TTree(); // tree for T0 decoder
- AliT0RawReader *rawReaderT0 = new AliT0RawReader(rawReader);
- // printf("rawReaderT0 = %p \n", rawReaderT0);
- //printf("rawReader = %p \n", rawReader);
- //printf("event = %p \n", event);
- // AliT0digit *digit = 0x0;
- //tree->SetBranchAddress("T0",&digit);
-
- if (!rawReaderT0->Next())
- printf(" no raw data found!! %i", rawReaderT0->Next());
- Int_t allData[110][5];
- for (Int_t i=0; i<110; i++) {
- allData[i][0]=rawReaderT0->GetData(i,0);
- }
- meantime = allData[49][0];
- printf("time zero (ns) = %i (%f) \n", meantime, meantime*25*1E-3-200);
-
- delete rawReaderT0;
- rawReaderT0 = 0x0;
- rawReader->Reset();
-
- AliTOFRawStream *rawStreamTOF = new AliTOFRawStream(rawReader);
-
- //loop the event data
- Int_t detectorIndex[5] = {-1, -1, -1, -1, -1};
-
- printf("before T0 \n");
-
- while(rawStreamTOF->Next()){
- for (Int_t ii=0; ii<5; ii++) detectorIndex[ii] = -1;
-
- detectorIndex[0] = (Int_t)rawStreamTOF->GetSector();
- detectorIndex[1] = (Int_t)rawStreamTOF->GetPlate();
- detectorIndex[2] = (Int_t)rawStreamTOF->GetStrip();
- detectorIndex[3] = (Int_t)rawStreamTOF->GetPadZ();
- detectorIndex[4] = (Int_t)rawStreamTOF->GetPadX();
-
- if (detectorIndex[0]==-1 ||
- detectorIndex[1]==-1 ||
- detectorIndex[2]==-1 ||
- detectorIndex[3]==-1 ||
- detectorIndex[4]==-1) continue;
- else {
- Float_t tdc = (Float_t)rawStreamTOF->GetTDC();
- Int_t tof = (Int_t)rawStreamTOF->GetTofBin();
- Int_t detID[5]={0,0,0,0,0};
- detectorIndex[0] = rawStreamTOF->GetSector();
- detectorIndex[1] = rawStreamTOF->GetPlate();
- detectorIndex[2] = rawStreamTOF->GetStrip();
- detectorIndex[3] = rawStreamTOF->GetPadZ();
- detectorIndex[4] = rawStreamTOF->GetPadX();
- Int_t index = rawStreamTOF->GetIndex(detectorIndex);
- Float_t pos[3];
- geomV5->GetPosPar(detectorIndex,pos);
- Float_t texp=TMath::Sqrt(pos[0]*pos[0]+pos[1]*pos[1]+pos[2]*pos[2])/c*1E9; //expected time in ns
- Float_t texpBin=(texp*1E3-32)/AliTOFGeometry::TdcBinWidth(); //expected time in number of TDC bin
- //to be uded with cosmics
- //Float_t tsim = (Float_t)rand->Gaus(texp,1E-1); //TDC measured time in ns, simulated to be used for testing with cosmic data
- //Float_t delta = tsim-texp;
- //Int_t deltabin = (Int_t)((delta*1E3-32)/AliTOFGeometry::TdcBinWidth()); //to be used for testing with cosmics data
- Int_t deltabin = tof-TMath::Nint(texpBin); //to be used with real data; rounding expected time to Int_t
- htofPartial->Fill(index,deltabin); //channel index start from 0, bin index from 1
- //debugging printings
- printf("sector %i, plate %i, strip %i, padz %i, padx %i \n",detectorIndex[0],detectorIndex[1],detectorIndex[2],detectorIndex[3],detectorIndex[4]);
- //printf("pos x = %f, pos y = %f, pos z = %f \n",pos[0],pos[1],pos[2]);
- //printf ("expected time = %f (ns)\n",texp);
- //printf ("expected time bin = %f (TDC bin)\n",texpBin);
- printf ("measured time bin = %i (TDC bin)\n",tof);
- // printf("index = %i, deltabin = %i , filling index = %i, and bin = % i\n",index, deltabin, index, deltabin);
- }
- }
-
- delete rawStreamTOF;
- rawStreamTOF = 0x0;
-
- delete rawReader;
- rawReader = 0x0;
-
+ /* check inhibit collection */
+ if (event->eventType == PHYSICS_EVENT && inhibitCollection) {
+ free(event);
+ continue;
}
-
- /* free resources */
+ /* increment number of physics events */
+ if (event->eventType == PHYSICS_EVENT) nPhysicsEvents++;
+ /* increment number of calib events */
+ if (event->eventType == CALIBRATION_EVENT) nCalibEvents++;
+
+ /*
+ * DECODE EVENT
+ */
+
+ /* create raw reader */
+ AliRawReader *rawReader = new AliRawReaderDate((void *)event);
+ /* setup raw stream */
+ rawStream->SetRawReader(rawReader);
+ /* reset buffers */
+ rawStream->ResetBuffers();
+ /* decode */
+ rawStream->DecodeDDL(0, AliDAQ::NumberOfDdls("TOF") - 1, 0);
+
+ /*
+ * HIT MANIPULATION
+ */
+
+ /* loop over DDLs */
+ for (Int_t iddl = 0; iddl < AliDAQ::NumberOfDdls("TOF"); iddl++) {
+ /* get packed-data buffer */
+ pdb = rawStream->GetPackedDataBuffer(iddl);
+ nhits = pdb->GetEntries();
+ /* loop over hits in buffer */
+ for (Int_t ihit = 0; ihit < nhits; ihit++) {
+ /* get hit */
+ hit = pdb->GetHit(ihit);
+ /* get channel info */
+ ddl = iddl;
+ slot = hit->GetSlotID();
+ trm = slot - 3;
+ chain = hit->GetChain();
+ tdc = hit->GetTDC();
+ channel = hit->GetChan();
+ /* get index */
+ rawStream->EquipmentId2VolumeId(ddl, slot, chain, tdc, channel, 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);
+
+ /* switch event type */
+ switch (event->eventType) {
+
+ /*
+ * PHYSICS EVENT
+ */
+
+ case PHYSICS_EVENT:
+ /* check noise flag */
+ if (noiseFlag[index]) continue;
+ /* increment number of channel hits and total hits */
+ nChHits[index]++;
+ totHits++;
+ /* get signal info */
+ timebin = hit->GetTimeBin();
+ totbin = hit->GetTOTBin();
+ deltaBC = hit->GetDeltaBunchID();
+ l0l1latency = hit->GetL0L1Latency();
+ /* set hit field data */
+ hitField->SetIndex(index);
+ hitField->SetTimeBin(timebin);
+ hitField->SetTOTBin(totbin);
+ hitField->SetDeltaBC(deltaBC);
+ hitField->SetL0L1Latency(l0l1latency);
+ /* fill temp tree */
+ tempTree->Fill();
+ break;
+
+ /*
+ * CALIBRATION EVENT
+ */
+
+ case CALIBRATION_EVENT:
+ /* fill calib hit histo */
+ hCalibHit->Fill(index);
+ break;
+
+ } /* end of switch event type */
+ } /* end of loop over hits in buffer */
+ } /* end of loop over DDLs */
+
+ /* delete raw reader */
+ delete rawReader;
+ /* free event */
free(event);
- /* exit when last event received, no need to wait for TERM signal */
- if (eventT==END_OF_RUN) {
- printf("EOR event detected\n");
- break;
- }
- }
+ } /* end of loop over events */
+
+ /* final noise check */
+ noiseHitThreshold = noiseThreshold * nPhysicsEvents;
+ printf("final noise check after %d events: threshold is %f hits\n", nPhysicsEvents, noiseHitThreshold);
+ /* loop over all channels */
+ for (Int_t ich = 0; ich < nChannels; ich++) {
+ /* check */
+ if (nChHits[ich] < minNoiseHits || noiseFlag[ich] || nChHits[ich] < noiseHitThreshold) continue;
+ printf("channel %d tagged as noisy (%d hits): disabled\n", ich, nChHits[ich]);
+ noiseFlag[ich] = kTRUE;
+ totHits -= nChHits[ich];
+ } /* end of loop over all channels */
- delete geomV5;
- geomV5 = 0x0;
- delete geom;
- geom = 0x0;
-
- //write the Run level file
- TFile * fileRun = new TFile ("outciccioTOFT0daRun.root","RECREATE");
- TBenchmark *bench = new TBenchmark();
- bench->Start("t0");
- htofPartial->Write();
- bench->Stop("t0");
- bench->Print("t0");
- fileRun->Close();
-
- TFile * filetot = new TFile ("outciccioTOFT0daTotal.root","READ");
- printf("dopo aver aperto il file in modalita' lettura \n");
- TH2S *htoftot = 0x0;
- //look for the file
- if (!filetot->IsZombie()){
- printf("il file non e' zombie \n");
- TIter next(filetot->GetListOfKeys());
- TKey *key;
- //look for the histogram
- while ((key=(TKey*)next())){
- const char * namekey = key->GetName();
- if (strcmp(namekey,"htoftot")==0){
- printf(" histo found \n");
- htoftot = (TH2S*) filetot->Get("htoftot");
- htoftot->AddDirectory(0);
- htoftot->Add(htofPartial);
- break;
- }
- }
- filetot->Close();
- }
- else {
- printf(" no file found \n");
- htoftot = new TH2S(*htofPartial);
- htoftot->SetName("htoftot");
- htoftot->AddDirectory(0);
- }
- filetot=0x0;
- filetot = new TFile ("outciccioTOFT0daTotal.root","RECREATE");
- filetot->cd();
- htoftot->Write();
- filetot->Close();
+ /* copy hits into output tree from temp tree */
+ printf("copy hits from temporary tree into output tree\n");
+ printf("temporary tree contains %d hits\n", (Int_t)tempTree->GetEntries());
+ for (Int_t ihit = 0; ihit < tempTree->GetEntries(); ihit++) {
+ /* get entry */
+ tempTree->GetEntry(ihit);
+ /* check noise flag */
+ if (noiseFlag[hitField->GetIndex()]) continue;
+ /* fill output tree */
+ outTree->Fill();
+ } /* end of copy hits into output tree from temp tree */
+ printf("output tree contains %d hits\n", (Int_t)outTree->GetEntries());
+
+ /* write output tree on HITS file */
+ fileOutHits->cd();
+ outTree->Write();
+ fileOutHits->Close();
+ /* export file to FXS */
+ if (daqDA_FES_storeFile(FILE_HITS, "HITS"))
+ return -2;
+
+ /* scale calib hit histo by number of calib events */
+ printf("found %d calibration events\n", nCalibEvents);
+ hCalibHit->Sumw2();
+ if (nCalibEvents > 0)
+ hCalibHit->Scale(1. / nCalibEvents);
- delete fileRun;
- delete filetot;
- delete bench;
- delete htofPartial;
- delete htoftot;
-
- fileRun = 0x0;
- filetot = 0x0;
- bench = 0x0;
- htofPartial = 0x0;
- htoftot = 0x0;
-
- /* write report */
- fprintf(fp,"Run #%s, received %d physics events out of %d\n",getenv("DATE_RUN_NUMBER"),nevents_physics,nevents_total);
-
- /* close result file */
- fclose(fp);
-
-
- return status;
+ /* write calib hit histo on CALIB file */
+ fileOutCalib->cd();
+ hCalibHit->Write();
+ fileOutCalib->Close();
+ /* export file to FXS */
+ if (daqDA_FES_storeFile(FILE_CALIB, "CALIB"))
+ return -2;
+
+ return 0;
}