]> git.uio.no Git - u/mrichter/AliRoot.git/blobdiff - TOF/TOFda.cxx
Enabled option for selecting tree name in trneding macro
[u/mrichter/AliRoot.git] / TOF / TOFda.cxx
index b0a2a6dfdad97c87f14f17077f9357151d98e8b5..f0957c7d763f618f7f362c842ffec63ec6379927 100644 (file)
 
 TOF DA for online calibration
 
+Contact: Chiara.Zampolli@bo.infn.it
+         Roberto.Preghenella@bo.infn.it
+
+Run Type: PHYSICS
+DA Type: MON
+Number of events needed:
+Input Files: no input
+Output Files: TOFdaHits.root
+Event types used: PHYSICS_EVENT
+
 */
 
-#define FILE_TOTAL "TOFdaTotal.root"
-#define FILE_RUN "TOFdaRun.root"
+#define FILE_HITS "TOFdaHits.root"
+#define FILE_CALIB "TOFdaCalib.root"
 
 // DATE
-#include <daqDA.h>
-#include <event.h>
-#include <monitor.h>
+#include "event.h"
+#include "monitor.h"
+#include "daqDA.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
 
 //AliRoot
-#include <AliTOFRawStream.h>
-#include <AliRawReaderDate.h>
-#include <AliRawReader.h>
-#include <AliTOFGeometry.h>
-#include <AliTOFGeometryV5.h>
-#include <AliT0RawReader.h>
-#include <AliDAQ.h>
-#include <AliTOFHitData.h>
-#include <AliTOFHitDataBuffer.h>
+#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"
 
 //ROOT
-#include <TFile.h>
-#include <TKey.h>
-#include <TH2S.h>
-#include <TObject.h>
-#include <TMath.h>
-#include <TSystem.h>
-
+#include "TFile.h"
+#include "TKey.h"
+#include "TH2S.h"
+#include "TObject.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()");
   
-  // decoding the events
+
+  /* log start of process */
+  printf("TOF DA started\n");  
   
-  int status;
+  /* check that we got some arguments = list of files */
   if (argc!=2) {
     printf("Wrong number of arguments\n");
     return -1;
   }
 
-  /* define data source : this is argument 1 */  
-  status=monitorSetDataSource( argv[1] );
-  if (status!=0) {
-    printf("monitorSetDataSource() failed : %s\n",monitorDecodeError(status));
+  /*
+   * 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;
   }
-
-  /* declare monitoring program */
-  status=monitorDeclareMp( __FILE__ );
-  if (status!=0) {
-    printf("monitorDeclareMp() failed : %s\n",monitorDecodeError(status));
+  /* 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;
 
-  /* define wait event timeout - 1s max */
-  monitorSetNowait();
-  monitorSetNoWaitNetworkTimeout(1000);
+  /*
+   * 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;
   
-  /* log start of process */
-  printf("TOF DA started\n");  
+  /* 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);
 
-  /* init some counters */
-  int nevents_physics=0;
-  int nevents_total=0;
+  /* 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;
-  eventTypeType eventT;
-  Int_t iev=0;
+  int ret;
+  /* define data source : this is argument 1 */  
+  ret = monitorSetDataSource(argv[1]);
+  if (ret != 0) {
+    printf("monitorSetDataSource() failed : %s\n",monitorDecodeError(ret));
+    return -1;
+  }
+  /* declare monitoring program */
+  ret = monitorDeclareMp("tofDA");
+  if (ret != 0) {
+    printf("monitorDeclareMp() failed : %s\n",monitorDecodeError(ret));
+    return -1;
+  }
+  /* define wait event timeout - 1s max */
+  monitorSetNowait();
+  monitorSetNoWaitNetworkTimeout(1000);
 
-  /* 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;
     }
+    /* check inhibit collection */
+    if (event->eventType == PHYSICS_EVENT && inhibitCollection) {
+      free(event);
+      continue;
+    }
+    /* increment number of physics events */
+    if (event->eventType == PHYSICS_EVENT) nPhysicsEvents++;
+    /* increment number of calib events */
+    if (event->eventType == CALIBRATION_EVENT) nCalibEvents++;
+    
+    /*
+     * DECODE EVENT
+     */
 
-    iev++; 
+    /* 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);
 
-   /* use event - here, just write event id to result file */
-    nevents_total++;
-    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:
-      nevents_physics++;
-      AliRawReader *rawReader = new AliRawReaderDate((void*)event);
-      //rawReader->RequireHeader(kFALSE);
-
-      //T0 event
-      Int_t meantime = 0;     
-      AliT0RawReader *rawReaderT0 = new AliT0RawReader(rawReader,kTRUE);
-      if (!rawReaderT0->Next()) {
-        printf("T0: no raw data found!\n");
-      } else {
-        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();
-
-      //TOF event
-      Int_t dummy = -1;
-      Int_t Volume[5];
-      AliTOFHitData *HitData;
-      AliTOFHitDataBuffer *DataBuffer;
-      AliTOFHitDataBuffer *PackedDataBuffer;
-      AliTOFRawStream *rawStreamTOF = new AliTOFRawStream(rawReader);
-      //      rawReader->ReadHeader();
-      rawStreamTOF->ResetBuffers();
-      rawStreamTOF->DecodeDDL(0, AliDAQ::NumberOfDdls("TOF") - 1,0);
-      Int_t nPDBEntriesToT = 0;
-      Int_t nDBEntriesToT = 0;
-      for (Int_t iDDL = 0; iDDL < AliDAQ::NumberOfDdls("TOF"); iDDL++){
-       
-       /* read decoded data */
-       DataBuffer = rawStreamTOF->GetDataBuffer(iDDL);
-       PackedDataBuffer = rawStreamTOF->GetPackedDataBuffer(iDDL);
-       
-       /* get buffer entries */
-       Int_t nDBEntries = DataBuffer->GetEntries();
-       Int_t nPDBEntries = PackedDataBuffer->GetEntries();
-       nPDBEntriesToT+=nPDBEntries;
-       nDBEntriesToT+=nDBEntries;
-       
-       //for (Int_t iHit = 0; iHit < nDBEntries; iHit++){
-       // HitData = DataBuffer->GetHit(iHit);
-         /* store volume information */
-       //  rawStreamTOF->EquipmentId2VolumeId(HitData, Volume);
-       //}
-       /* reset buffer */
-       DataBuffer->Reset();
-       
-       /* read data buffer hits */
-       for (Int_t iHit = 0; iHit < nPDBEntries; iHit++){
-         HitData = PackedDataBuffer->GetHit(iHit);
-         /* add volume information */
-         HitData->SetDDLID(iDDL);
-         rawStreamTOF->EquipmentId2VolumeId(HitData, Volume);
-         if (Volume[0]==-1 ||
-             Volume[1]==-1 ||
-             Volume[2]==-1 ||
-             Volume[3]==-1 ||
-             Volume[4]==-1) continue;
-         else {
-           dummy = Volume[3];
-           Volume[3] = Volume[4];
-           Volume[4] = dummy;
-           Int_t tof = (Int_t)((Double_t)HitData->GetTime()*1E3/AliTOFGeometry::TdcBinWidth());
-           Int_t index = rawStreamTOF->GetIndex(Volume);
-           Float_t pos[3];
-           geomV5->GetPosPar(Volume,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
-           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",Volume[0],Volume[1],Volume[2],Volume[3],Volume[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) with %f (ns) and ACQ bit = %i \n",tof, HitData->GetTime(), HitData->GetACQ());
-           //    printf("index = %i, deltabin = %i , filling index = %i, and bin = % i\n",index, deltabin, index, deltabin);
-           
-         }
-         /* reset buffer */
-         PackedDataBuffer->Reset();
-       }
-      }
-      //printf(" Packed Hit Buffer Entries = %i \n",nPDBEntriesToT);
-      //printf(" Hit Buffer Entries = %i \n",nDBEntriesToT);
-   
-      delete rawStreamTOF;
-      rawStreamTOF = 0x0;
-      
-      delete rawReader;
-      rawReader = 0x0;
-    }
+    /*
+     * 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 */
     
-    /* free resources */
+    /* 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;
-    }
-  }
-  
-  delete geomV5;
-  geomV5 = 0x0;
-  delete geom;
-  geom = 0x0;
-
-  //write the Run level file   
-  TFile * fileRun = new TFile (FILE_RUN,"RECREATE"); 
-  htofPartial->Write();
-  fileRun->Close();
-
-  //write the Total file
-  TH2S *htoftot = 0x0;
-  TFile * filetot = 0x0;
-  Bool_t isThere=kFALSE;
-  const char *dirname = "./";
-  TString filename = FILE_TOTAL;
-  if((gSystem->FindFile(dirname,filename))!=NULL){
-    isThere=kTRUE;
-    printf("%s found \n",FILE_TOTAL);
-  }
-  if(isThere){
-
-    TFile * filetot1 = new TFile (FILE_TOTAL,"READ"); 
-    //look for the file
-    if (!filetot1->IsZombie()){
-      printf("updating file %s \n",FILE_TOTAL);
-      TIter next(filetot1->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*) filetot1->Get("htoftot");
-         htoftot->AddDirectory(0);
-         htoftot->Add(htofPartial);
-         break;
-       }
-      }
-    }
-    filetot1->Close();
-    delete filetot1;
-    filetot1=0x0;
-  }
-  else {
-    printf(" no %s file found \n",FILE_TOTAL);
-    htoftot = new TH2S(*htofPartial);
-    htoftot->SetName("htoftot");
-    htoftot->AddDirectory(0);
-  }
+  } /* end of loop over events */
 
-  filetot = new TFile (FILE_TOTAL,"RECREATE");
-  filetot->cd();
-  htoftot->Write();
-  filetot->Close();
+  /* 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 fileRun;
-  delete filetot;
-  delete htofPartial;
-  delete htoftot;
-
-  fileRun = 0x0;
-  filetot = 0x0;
-  htofPartial = 0x0;
-  htoftot = 0x0;
-
-  /* write report */
-  printf("Run #%s, received %d physics events out of %d\n",getenv("DATE_RUN_NUMBER"),nevents_physics,nevents_total);
-
-  status=0;
+  /* 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_RUN, FILE_RUN)) {
-    status=-2;
-  }
-  if (daqDA_FES_storeFile(FILE_TOTAL, FILE_TOTAL)) {
-    status=-2;
-  }
+  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);
   
-  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;
+}