--- calo/flight/CaloPreSampler/src/CaloPreSampler.cpp	2007/08/10 09:55:42	1.3
+++ calo/flight/CaloPreSampler/src/CaloPreSampler.cpp	2014/01/23 11:23:54	1.19
@@ -12,7 +12,12 @@
  */
 CaloPreSampler::CaloPreSampler(){
   Clear();
-};
+}
+
+void CaloPreSampler::SetCaloLevel2Pointer(CaloLevel2 *cl2p){
+  if ( pcalo ) delete pcalo;
+  pcalo = cl2p;
+}
 
 CaloPreSampler::CaloPreSampler(PamLevel2 *l2p){  
   //
@@ -30,12 +35,21 @@
   cstrip = new CaloStrip(false);
   //  c1 = new CaloLevel1();
   pcalo = new CaloLevel2();
-  N = 3;
+  N = 4;
+  NC = 22-N; 
   debug = false;
   sel = true;
   cont = false;
   emulate18 = true;
+  usepl18x = false;
   simulation = false;
+  withtrk = true;
+  rigdefault = 50.;
+  nox = false;
+  noy = false;
+  forcecalo = false;
+  forcefitmode = -1;
+  memset(mask,0,2*22*sizeof(Int_t));
   //
   Clear();
   //
@@ -62,13 +76,58 @@
   printf(" Reading magnetic field maps at %s\n",(q4->PATH+q4->NAME).Data());
   trk->LoadField(q4->PATH+q4->NAME);
   //
-};
+}
+
+CaloTrkVar* CaloPreSampler::GetCaloTrack(Int_t t){
+  this->Process();
+  if ( t < 0 ) return pcalo->GetCaloStoredTrack(t);
+  if ( L2->GetTrack(t) ){
+    return pcalo->GetCaloStoredTrack(L2->GetTrack(t)->GetTrkTrack()->GetSeqNo());
+  };
+  return NULL;
+}
+
+void CaloPreSampler::SetNoWpreSampler(Int_t n){
+  if ( NC+n < 23 ){
+    N = n;
+  } else {
+    printf(" ERROR! Calorimeter is made of 22 W planes\n");
+    printf(" you are giving N presampler = %i and N calo = %i \n",n,NC);
+    printf(" WARNING: using default values NWpre = 4, NWcalo = 18\n");
+    NC = 18;
+    N = 4;
+  };
+}
+
+void CaloPreSampler::SetNoWcalo(Int_t n){
+  if ( N+n < 23 ){
+    NC = n;
+  } else {
+    printf(" ERROR! Calorimeter is made of 22 W planes\n");
+    printf(" you are giving N W presampler = %i and N W calo = %i \n",N,n);
+    printf(" WARNING: using default values NWpre = 4, NWcalo = 18\n");
+    NC = 18;
+    N = 4;
+  };
+}
+
+void CaloPreSampler::SplitInto(Int_t NoWpreSampler, Int_t NoWcalo){
+  this->SetNoWcalo(0);
+  this->SetNoWpreSampler(0);
+  if ( NoWpreSampler < NoWcalo ){
+	this->SetNoWpreSampler(NoWpreSampler);
+	this->SetNoWcalo(NoWcalo);
+  } else {
+	this->SetNoWcalo(NoWcalo);
+	this->SetNoWpreSampler(NoWpreSampler);
+  };
+}
 
 void CaloPreSampler::Clear(){
   //
   pcalo->Clear();
   //
-};
+}
 
 void CaloPreSampler::Print(){
   //
@@ -90,13 +149,13 @@
   };
   printf("========================================================================\n");
   //
-};
+}
 
 void CaloPreSampler::Delete(){
   Clear();
   delete pcalo;
   //delete this;
-};
+}
 
 
 void CaloPreSampler::Process(){
@@ -107,9 +166,23 @@
     return;
   };
   //
+  // Clear structures used to communicate with fortran
+  //
+  event->ClearStructs();//ELENA
+  if ( forcefitmode > 0 ){
+    if ( forcefitmode != 1000 && forcefitmode != 1001 && forcefitmode != 1002 ){
+      printf(" ERROR! forcefitmode=%i \n Use forcefitmode = 1000 for fit mode 0, 1001 fit mode 1, 1002 fit mode 3\n",forcefitmode);
+      forcefitmode = -1;
+    } else {
+      event->clevel2->fmode[0] = forcefitmode;
+      event->clevel2->fmode[1] = forcefitmode;
+    };
+  };
+  //
   Bool_t newentry = false;
   //
   if ( L2->IsORB() ){
+    if ( debug ) printf(" I am here, we have orbital infos \n");
     if ( L2->GetOrbitalInfo()->pkt_num != PKT || L2->GetOrbitalInfo()->OBT != OBT || L2->GetOrbitalInfo()->absTime != atime || sel != ssel ){
       newentry = true;
       OBT = L2->GetOrbitalInfo()->OBT;
@@ -131,18 +204,16 @@
   Int_t S11 = 0;
   Float_t tmptrigty = -1.; 
   Bool_t trackanyway = true;
-  Float_t rigdefault = 50.;
+  //  Float_t rigdefault = 50.;
   Bool_t hZn = true;
-  Bool_t withtrk = true;
+  //  Bool_t withtrk = true;
   Bool_t st = true;
   Int_t ntrkentry = 0;
   TrkLevel2 *trk = L2->GetTrkLevel2();
-  Bool_t filled = false;
+  //  Bool_t filled = false;
   //
   if ( debug ) printf(" Processing event at OBT %u PKT %u time %u \n",OBT,PKT,atime);
   //
-  this->Clear();
-  //
   // find out if we have trkseqno = -1, -2 or -3
   //
   Bool_t m1 = false;
@@ -153,6 +224,19 @@
     if ( L2->GetCaloLevel2()->GetCaloTrkVar(mm)->trkseqno == -2 ) m2 = true;
     if ( L2->GetCaloLevel2()->GetCaloTrkVar(mm)->trkseqno == -3 ) m3 = true;
   };
+  if ( !withtrk ) m3 = true;
+  //
+  // copy variables calculated during calibration process which is skipped here... this has been moved before this->Clear() for reprocessing purpose
+  //
+  event->clevel2->good = L2->GetCaloLevel2()->good;
+  memcpy(event->clevel2->perr,L2->GetCaloLevel2()->perr,sizeof(L2->GetCaloLevel2()->perr));
+  memcpy(event->clevel2->swerr,L2->GetCaloLevel2()->swerr,sizeof(L2->GetCaloLevel2()->swerr));
+  memcpy(event->clevel2->crc,L2->GetCaloLevel2()->crc,sizeof(L2->GetCaloLevel2()->crc));
+  event->clevel2->selftrigger = L2->GetCaloLevel2()->selftrigger;
+  //
+  //
+  this->Clear(); // moved after all calls to L2->GetCaloLevel2() since pcalo could be the same as L2->GetCaloLevel2() !!!
+  //
   //
   if ( debug ) printf(" Fill estrip matrix needed to calculate variables \n");
   //
@@ -167,13 +251,24 @@
     //
     mip = L2->GetCaloLevel1()->DecodeEstrip(i,view,plane,strip);
     //
+    if ( !usepl18x && view==0 && plane==18 ) mip = 0.;
+    //
+    // Mask x or y view if nox and/or noy are true (default false)
+    //
+    if ( mask[view][plane] ) mip = 0.;
+    if ( nox && view == 0 ) mip = 0.; 
+    if ( noy && view == 1 ) mip = 0.; 
+    //
+    if ( emulate18 && view == 0 && plane == 18 ) mip = 0.;
+    //
     // Selection mode: fill the matrix only for plane < (22 - N) REMEMBER N = number of W planes to be used as presampler, ie if N = 2 then we want to use planes from 0 to 19
     //                 included so plane < (22 - 2)
     //
     if ( sel ){
       if ( plane < (22 - N) ){
 	//
-	if ( emulate18 && plane == (18 - N) ) mip = 0.;
+	if ( emulate18 && plane == (18 - N) && view == 0 ) mip = 0.;
+	if ( plane >= NC ) mip = 0.;
 	event->clevel1->estrip[strip][plane][view] = mip;
 	//
       };
@@ -184,7 +279,8 @@
     if ( cont ){
       if ( plane >= N ){
 	//
-	if ( emulate18 && plane == (18 + N) ) mip = 0.;
+	if ( emulate18 && plane == (18 + N) && view == 0 ) mip = 0.;
+	if ( (plane-N) >= NC ) mip = 0.;
 	event->clevel1->estrip[strip][(plane-N)][view] = mip;
 	//
       };
@@ -228,7 +324,8 @@
   //
   // use only N W planes
   //
-  event->clevel1->npla = 22-N;
+  //  event->clevel1->npla = 22-N;
+  event->clevel1->npla = NC;
   //
   S3 = 0;
   S2 = 0;
@@ -248,13 +345,13 @@
   //
   event->clevel1->good2 = 1;
   //
-  // copy variables calculated during calibration process which is skipped here...
+  // copy variables calculated during calibration process which is skipped here... this has to be moved before this->Clear() for reprocessing purpose
   //
-  event->clevel2->good = L2->GetCaloLevel2()->good;
-  memcpy(event->clevel2->perr,L2->GetCaloLevel2()->perr,sizeof(L2->GetCaloLevel2()->perr));
-  memcpy(event->clevel2->swerr,L2->GetCaloLevel2()->swerr,sizeof(L2->GetCaloLevel2()->swerr));
-  memcpy(event->clevel2->crc,L2->GetCaloLevel2()->crc,sizeof(L2->GetCaloLevel2()->crc));
-  event->clevel2->selftrigger = L2->GetCaloLevel2()->selftrigger;
+//  event->clevel2->good = L2->GetCaloLevel2()->good;
+//  memcpy(event->clevel2->perr,L2->GetCaloLevel2()->perr,sizeof(L2->GetCaloLevel2()->perr));
+//  memcpy(event->clevel2->swerr,L2->GetCaloLevel2()->swerr,sizeof(L2->GetCaloLevel2()->swerr));
+//  memcpy(event->clevel2->crc,L2->GetCaloLevel2()->crc,sizeof(L2->GetCaloLevel2()->crc));
+//  event->clevel2->selftrigger = L2->GetCaloLevel2()->selftrigger;
   //
   // Calculate variables common to all tracks (qtot, nstrip, etc.)
   //
@@ -270,7 +367,7 @@
   //
   ntrkentry = 0;
   //
-  filled = false;
+  //  filled = false;
   //
   // Run over tracks (tracker or calorimeter )
   //
@@ -307,7 +404,7 @@
 
 
       ntrkentry++;	
-      filled = true;
+      //      filled = true;
       //
     }; // loop on all the tracks
   };
@@ -319,7 +416,7 @@
   // conditions are: 0) no track from the tracker 1) we have a track fit both in x and y 2) no problems with calo for this event 3) no selftrigger event
   //
   //  if ( trackanyway && !filled && event->clevel2->npcfit[0] >= 2 && event->clevel2->npcfit[1] >= 2 && event->clevel2->good != 0 && event->clevel2->trigty < 2. ){
-  if ( trackanyway && m3 ){
+  if ( (trackanyway && m3) || forcecalo ){
     if ( debug ) printf(" Event with a track not fitted by the tracker \n");
     //
     // Disable "track mode" in the fortran routine
@@ -352,7 +449,7 @@
       if ( debug ) printf("-3 a Call FillTrkVar() \n");
       event->FillTrkVar(pcalo,ntrkentry);
       ntrkentry++;
-      filled = true;
+      //      filled = true;
       //
     } else {
       if ( debug ) printf(" Selftrigger: problems with event \n");
@@ -399,7 +496,7 @@
       if ( debug ) printf("-2 a Call FillTrkVar() \n");
       event->FillTrkVar(pcalo,ntrkentry);
       ntrkentry++;
-      filled = true;
+      //      filled = true;
       //
     } else {
       if ( debug ) printf(" Selftrigger: problems with event \n");
@@ -445,20 +542,68 @@
       if ( debug ) printf("-1 a Call FillTrkVar() \n");
       event->FillTrkVar(pcalo,ntrkentry);
       ntrkentry++;
-      filled = true;
+      //      filled = true;
       //
     } else {
       if ( debug ) printf(" Selftrigger: problems with event \n");
     };
   };
-  //
-  // Clear structures used to communicate with fortran
-  //
-  event->ClearStructs();
+//   //
+//   // Clear structures used to communicate with fortran
+//   //
+//   event->ClearStructs();
+// ELENA: moved @ beginning
   //
   //
   //
   if ( debug ) this->Print();
   if ( debug ) printf(" exit \n");
   //
-};
+}
+
+//
+// Method to add a calorimeter track, evaluated around a tracker track defined by a status vector.
+// (can be used to evaluate the calorimeter track around an arbitrary axis, by setting the status vector with zero deflection )
+// 
+//
+CaloTrkVar* CaloPreSampler::AddCaloTrkVar(float *al,int trktag){
+
+    int ntrkentry = pcalo->ntrk();
+    //
+    for (Int_t nt=0; nt < ntrkentry; nt++){  
+	if( pcalo->GetCaloTrkVar(nt)->trkseqno == trktag){
+	    cout << " CaloTrkVar* CaloPreSampler::AddCaloTrkVar(float *al,int trktag)"<<endl;
+	    cout << " --> trktag = "<<trktag<<" already defined "<<endl;
+	    return NULL;
+	}
+    }
+    //
+    event->clevel1->good2 = 1; //is a trk track
+    event->clevel1->trkchi2 = 0;
+    event->clevel1->hzn = 0; 
+    //
+    // Copy the alpha vector in the input structure
+    //
+    for (Int_t e = 0; e < 5 ; e++){
+	event->clevel1->al_p[e][0] = al[e];
+    };	  
+    //
+    // Get tracker related variables for this track
+    //
+    if ( debug ) printf("track %i Call GetTrkVar() \n",trktag);
+    event->GetTrkVar();
+    if ( debug ) printf(" event->clevel2->dX0l %f \n",event->clevel2->dX0l);
+    //
+    // Save tracker track sequence number
+    //	
+    event->trkseqno = trktag;
+    //
+    // Copy values in the class ca from the structure clevel2
+    //
+    if ( debug ) printf("track %i Call FillTrkVar() \n",trktag);
+    event->FillTrkVar(pcalo,ntrkentry);
+
+    return pcalo->GetCaloTrkVar(ntrkentry);
+    
+
+};//ELENA