// Author: Egon Pavlica <http://www.p-ng.si/~pavlica/

//________________________________________
//  This is data tranfer class
// 
// it can calculate averages of track positions
// velocity end energies. It can present data in 
// format, approptiate for presentations.
// it was created to do statistics with the Monte Carlo
// simulation data obtained by LDisorder class.
//
// basic operation of adding data:
//   position and energy vs time is obtained by LDisorder 
//   class. See hoppclient.cc for example. This data is 
//   then transported through network or other media via 
//   LContainer class and then added to LData. See hoppserv.cc
//   for details. Other posibility is shown with hoppclient in 
//   queue mode and empty_container.C script.
//   Before streaming of data, the Prepare function should be
//   called to create fav array off correct size. Temporary
//   array is not streamed.
// 
// adding data using LContainer
//   LContainer class is used to transfer multiple tracks from 
//   simulation part to storage part instead of big LData class.
//
// adding of another LData:
//   fp and fe are summed, fN is increased by the fN of added
//   data
//
//  WARNING: all indexes of array are 1-based in contrast to for
//           example to LDisorder, where are 0-indexed!!!
//
//  WARNING: time units are arbitrary! So velocity as well as tof current
//           and all time axes needs to be converted to real time units
//           velocity need to be divided by real time units
//           If you need to compare different simulations it is enough to 
//           use fresolution as a time unit. In contrast time axis should be
//           multiplied by time units...
//           tof was already normalized to time units!
//
// Logs:
//
//  $Log: LData.cc,v $
//  Revision 1.28  2004/10/12 10:02:25  cvs
//  corrected GetAV, so the zero values are rejected.
//
//  Revision 1.27  2004/08/26 09:11:44  cvs
//  corrected gettime so it return always positive time value regardless average velocity obtained with GetAV().
//
//  Revision 1.26  2004/07/13 10:12:44  cvs
//  forgot to modify info
//
//  Revision 1.25  2004/07/13 09:57:57  cvs
//  found bug in tof normalization. solution is to multiply histogram with  tof->Scale(data->fvt->GetEntries()/(Double_t)data->fN/(header->rpmax-header->rpmin)/header->fresolution); and then the tof is normalized! This bug was corrected and commited to cvs.
//
//  Revision 1.24  2004/07/12 17:14:30  cvs
//  found right tof normalization. Not implemented in code yet
//
//  Revision 1.23  2004/07/09 09:43:23  cvs
//  updated info of LData.cc
//
//  Revision 1.22  2004/04/09 13:21:05  cvs
//  added cputime logging...
//
//  Revision 1.21  2004/01/06 08:28:27  cvs
//  found a bug in LData::Add(int,float*,float*) which caused segfault at adding only one track
//
//  Revision 1.20  2003/12/22 14:32:36  cvs
//  added simulation of laser -> LDataHeader version 5
//  modified hoppserver sigint interruption
//
//  Revision 1.19  2003/12/15 16:17:26  cvs
//  more verbosity
//
//  Revision 1.18  2003/11/24 17:06:23  cvs
//  a bug was corrected in LServer::GetLData and the error bars were corrected when drawing Draw(".tof.")
//
//  Revision 1.17  2003/11/15 17:17:26  cvs
//  new scheme is working...
//  Clients (hoppclient) are connected as kLC_AMAX and free socket is given
//  TLServer (lserver) is multithreading
//  LServer (hoppserver) has a file which is always in memory - faster but needs more memory
//
//  Revision 1.16  2003/11/03 13:54:40  cvs
//  TLServer is now threaded, LData and LDataHeader have now right Draw and Paint methods, LIV is controlled and comments were added.
//
//  Revision 1.15  2003/08/30 11:28:52  cvs
//  simplified and checked LIV calculations
//
//  Revision 1.14  2003/08/28 14:41:17  cvs
//  corrected the bug in LData::Add(float,float,float,...). Description of bug: position index, that was obtained by simulation, was not shifted by -1 like was shifted the range of position in LDataHeader::SetDefaults.
//
//  Revision 1.13  2003/07/25 11:36:26  cvs
//  simulation of IV measurements is done with iv program
//  some minority fixes to LDisorder - corrected ft to match the recorded position
//
//  Revision 1.12  2003/07/15 14:19:35  cvs
//  corrected ranges when creating histograms. See LDataHeader::Defaults(). Added Draw(".bias.") to draw bias array
//
//  Revision 1.11  2003/07/09 13:27:39  cvs
//  Modified ranges for histograms stored in LData. Ranges are set by LDataHeader->SetDefaults() and MAX_BINS in Config.h
//
//  Revision 1.10  2003/07/08 16:02:13  cvs
//  added correct calculations for Draw(".tof.") including statistical error calculation.
//
//  Revision 1.9  2003/07/01 13:09:27  cvs
//  added Draw(".tof.") to simulate photocurrent measurements
//
//  Revision 1.8  2003/07/01 12:17:18  cvs
//  New LData organization. data is stored in TH2F histograms. This enables easier manipulation. Found a bug in drawing averaged velocity vs time. The average number was calcuated over whole times.
//
//  Revision 1.7  2003/06/27 07:43:16  cvs
//  error corrected in Add(float* float* float) in adding velocity.
//
//  Revision 1.6  2003/06/26 12:23:15  cvs
//  averaged velocity is stored in .TTIME. instead of transit time. This was done, becose we need to know the average velocity instead of transit time to know mobility.
//
//  Revision 1.5  2003/06/26 09:27:11  cvs
//  added log fields...
//

#include "LData.h"
#include <iostream>
#include <TString.h>
#include <TPad.h>
#include <TCanvas.h>
#include <TPaveText.h>
#include <TStyle.h>
#include <TMath.h>
#include <TProfile.h>
#include <TROOT.h>//for gROOT

ClassImp(LData)
  
 LData::LData():TNamed(){
 fjobID=0;
 fheader=0;
 fN=0;
 fpt=0;
 fvt=0;
 fvp=0;
 fet=0; 
 fnav=0;
 fav=0;
 fnav_temp=0;
 fav_temp=0;
 fcpu_time=0.0;
}

 LData::LData(LDataHeader* header):TNamed("data","Monte Carlo simulation results"){
  //this copy parameters from header
  //it creates a temporary fav_temp array of size FNAV_TEMP
  //before the data is sent you must call LData::Prepare() to 
  //prepare LData class for containing real data

  fheader=header;
  fjobID=header->GetJobID();

  fpt=new TH2F("fpt","Position vs Time",fheader->nbint,fheader->rtmin,fheader->rtmax,fheader->nbinp,fheader->rpmin,fheader->rpmax);
  SetStyle((TH1*)fpt,"Time [a.u.]","Position [Ang.]");
  fvt=new TH2F("fvt","Velocity vs Time",fheader->nbint,fheader->rtmin,fheader->rtmax,fheader->nbinv,fheader->rvmin,fheader->rvmax);
  SetStyle((TH1*)fvt,"Time [a.u.]","Velocity [a.u.]");
  fvp=new TH2F("fvp","Velocity vs Position",fheader->nbinp,fheader->rpmin,fheader->rpmax,fheader->nbinv,fheader->rvmin,fheader->rvmax);
  SetStyle((TH1*)fvp,"Position [Ang.]","Velocity [a.u.]");
  fet=new TH2F("fet","Energy vs Time",fheader->nbint,fheader->rtmin,fheader->rtmax,fheader->nbinv,fheader->remin,fheader->remax);
  SetStyle((TH1*)fet,"Time [a.u.]","Energy [eV]");

  //ttime array
  fN=0;
  fnav=0;
  fav=0;
  fcpu_time=0.0;

  fnav_temp=FNAV_TEMP;
  Tnew(fav_temp,1,fnav_temp);
  return;

}
  
 LData::~LData(){
  //default destructor
  if (fav_temp) { Tdelete(fav_temp,1); fav_temp=0; fnav_temp=0; }  
  if (fav) { Tdelete(fav,1); fav=0; fnav=0; }  
  if (fet) { delete fet; fet=0; }  
  if (fvt) { delete fvt; fvt=0; }  
  if (fvp) { delete fvp; fvp=0; }  
  if (fpt) { delete fpt; fpt=0; }  
}
  
  
void 
 LData::ClearArray(){
  //set array values to 0
  //clear arrays
  if (!fpt) {
    if (fverbose)
      std::cerr<<"Error when ClearArray: fpt array not initializedn";
    return;
  }
  if (!fvp) {
    if (fverbose)
      std::cerr<<"Error when ClearArray: fvp array not initializedn";
    return;
  }
  if (!fvt) {
    if (fverbose)
      std::cerr<<"Error when ClearArray: fvt array not initializedn";
    return;
  }
  if (!fet) {
    if (fverbose)
      std::cerr<<"Error when ClearArray: fet array not initializedn";
    return;
  }

  fpt->Reset();
  fvp->Reset();
  fvt->Reset();
  fet->Reset();
  return;
}

Float_t 
 LData::Velocity(const Int_t i,const Int_t n,const Float_t* track) const{
  //this is used to calculate velocity in track i of size fy
  //set here the division with time interval if neccessary!!
  //set here the multiplication with header->fbasez!!
  if (i==1) return track[2]-track[1];
  return (i<1 || i>n)? 0.0:(track[i]-track[i-1]);
}

LData* 
 LData::Add(LData* data){
  //this add another data to this data class! fjobID must be equal 
  //or 0 is returned! It uses AddTime to store ttime


  if (fjobID!=data->GetJobID()) {
    if (fverbose)
      std::cerr<<"Error when adding LData: JobID are not equal of added datan";
    return 0;
  }

  //adding tracks
  if (!fN) ClearArray();

  AddTH2F(fpt,data->fpt);
  AddTH2F(fvt,data->fvt);
  AddTH2F(fvp,data->fvp);
  AddTH2F(fet,data->fet);

  fN+=data->fN;

  //adding time - slow but simple
  for(Int_t i=1;i<=data->fnav;i++)
    AddAV(data->fav[i]);

  //add cpu time
  fcpu_time+=data->GetCPUtime();

  //all is done
  return this;
}

void 
 LData::Add(const Int_t n,const Float_t* track,const Float_t* tracke,const Float_t ttime,const Double_t cputime){
  //n is the last index of track and tracke
  //this add ttime, tracks fp and fe and increases fN by one
  //STORE AVERAGE VELOCITY INSTEAD TRANSIT TIME into fav

  //  std::cerr<<"Index n:"<<n<<std::endl;

  if (!fpt) {
    if (fverbose)
      std::cerr<<"Error when adding LData: fpt array not initializedn";
    return;
  }
  if (!fvt) {
    if (fverbose)
      std::cerr<<"Error when adding LData: fvt array not initializedn";
    return;
  }
  if (!fvp) {
    if (fverbose)
      std::cerr<<"Error when adding LData: fvp array not initializedn";
    return;
  }
  if (!fet) {
    if (fverbose)
      std::cerr<<"Error when adding LData: fet array not initializedn";
    return;
  }

  //clear arrays
  //  if (!fN) ClearArray();

  //trace if particle has reached opposite electrode
  if (ttime>0) AddAV(((track[n]-track[1])*fheader->fbasez)/ttime);  

  //  if (fverbose) std::cout<<"TTime:"<<n<<":"<<ttime<<std::endl;
  Float_t time;
  Float_t velocity;
  Float_t position;
  Float_t energy;
  for(Int_t i=1;i<=n;i++) {
    time=CalcIndexToTime(i);
    (n>1?velocity=Velocity(i,n,track):velocity=0.0);
    position=(track[i]-1)*fheader->fbasez;
    energy=tracke[i];
    fpt->Fill(time,position);
    fet->Fill(time,energy);
    fvt->Fill(time,velocity);
    fvp->Fill(position,velocity);
  }
  fN++;//number of stored simulations has changed
  if (cputime>0.0) fcpu_time+=cputime;//add cpu time
}

void
 LData::Add(const LContainer* container){
  //adds data from a container
  Int_t n=container->GetN();
  if (!n) {
    if (fverbose)
      std::cerr<<"Warning: adding LData: container empty!n";
    return;
  }
  for (Int_t i=1;i<=n;i++){
    //    if (fverbose) std::cout<<"Adding container:"<<i<<std::endl;
    Add(container->GetTrackN(i),container->GetPositionTrack(i),container->GetEnergyTrack(i),container->GetTTime(i));
    fcpu_time+=container->GetCPUtime(i);
  }
  //done
}


void 
 LData::AddAV(const Float_t avelocity){
  //this add ttime to fav_temp array and increase fnav counter by 1
  //if necessary increases fav_temp bye FNAV_TEMP

  Int_t mode=(!fnav_temp)?1:0;

  fnav++;//points where to store avelocity

  //if necessary increase temp array
  if (fnav>fnav_temp){
    while (fnav>fnav_temp) fnav_temp+=FNAV_TEMP;
    Float_t* temp;
    Tnew(temp,1,fnav_temp);

    if (mode)
      for(Int_t i=1;i<fnav;i++)
	temp[i]=fav[i];
    else 
      for(Int_t i=1;i<fnav;i++)
	temp[i]=fav_temp[i];

    Tdelete(fav_temp,1);
    fav_temp=temp;
  }

  fav_temp[fnav]=avelocity;
}


Int_t
 LData::Prepare(){
  //this function is called to prepare LData for streaming....
  //this function store from fttime_temp to fttime array and correct its
  //size. I have done this to avoid the ?slow? dinamic resizing 
  if (!fnav_temp) return 0;//when only reading was done
  if (!fnav) return 0;
  Tnew(fav,1,fnav);
  for(Int_t i=1;i<=fnav;i++)
    fav[i]=fav_temp[i];
  //done
  return fnav;
}


Float_t 
 LData::GetMaxTTime(){
  //this return the max ttime value
  if (fnav>0){
    if (!fav) Prepare();
    
    Float_t max;
    max=fav[1];
    for(Int_t runs=1;runs<=fnav;runs++)
      if (fav[runs]>max) max=fav[runs];
    return max;
  }
  return 0.0;
}

Float_t 
 LData::GetMinTTime(){
  //this return the min ttime value
  if (fnav>0){
    if (!fav)  Prepare();
    
    Float_t max;
    max=fav[1];
    for(Int_t runs=1;runs<=fnav;runs++)
      if (fav[runs]<max) max=fav[runs];
    return max;
  }
  return 0.0;
}


#include <TMarker.h>
Float_t
 LData::GetTTime(Float_t to){
  //return transit time calculated from average velocities (fav array)
  //to...time units
  if (!fheader) return 0.0;
  if (GetAV()==0.0) return 0.0; //if velocity is zero
  float l=fheader->rpmax-fheader->rpmin;
  float ttime=l/favg;
  if (to>0.0) ttime*=to;
  if (ttime<0.0) ttime*=-1.0;//time is always positive
  //add a marker to tof histogram if it is present
  TObject *h1obj = gROOT->FindObject("tof");
  if (h1obj && h1obj->InheritsFrom("TH1D")) {
    TH1D* his=(TH1D*) h1obj;
    TMarker* ttmark=new TMarker(ttime,his->GetBinContent(his->FindBin(ttime)),2);
    ttmark->SetMarkerSize(2.5);
    ttmark->SetMarkerColor(2);
    ttmark->Draw();
  }

  return ttime;
}

Float_t 
 LData::GetAV(){
  //calculates average and standard deviation of average  
  //velocity from fav array
  //average is returned, while st.dev. is stored in LData::favsig
  //average is also stored in LData::favg
  //average velocity, that is simulated with LDisorder and added to fav array
  //could be negative or zero. This happens, when the particle travel distance
  //is zero -  particle starts at zero and exits at the same point or at any 
  //point with smaller z position. These values are thus rejected from 
  //the calculation of average velocity.
  //Average velocity is defined as total distance/average time!
  if (!fav) Prepare(); //to be secure
  Float_t avg=0.0,var=0.0;
  int count=0;
  for(Int_t i=1;i<=fnav;i++)
    if (fav[i]>0.0) {avg+=fav[i];count++;}
  if (!count)//in case that the default velocity should be negative
    for(Int_t i=1;i<=fnav;i++)
      if (fav[i]<0.0) {avg+=fav[i];count++;}
  if (!count) {
    if (fverbose) std::cerr<<"Warning:LData::GetAV:All fav entries are zeron";
    return 0.0;
  }
  avg/=count;
  if (avg>0.0) {
    for(Int_t i=1;i<=fnav;i++)
      if (fav[i]>0.0) var+=(fav[i]-avg)*(fav[i]-avg);
  } else {
    for(Int_t i=1;i<=fnav;i++)
      if (fav[i]<0.0) var+=(fav[i]-avg)*(fav[i]-avg);
  }
  var/=(count-1);
  //standard deviation of average is standard deviation of data divided by 
  //number of data
  favsig=sqrt(var/count);
  favg=avg;
  return avg;
}


void 
 LData::SetStyle(TH1* his,const char* xaxis,const char* yaxis){
  his->SetXTitle(xaxis);
  his->SetYTitle(yaxis);
  his->SetStats(kFALSE);
  his->GetXaxis()->CenterTitle();
  his->GetYaxis()->CenterTitle();
}

int 
 LData::AddTH2F(TH2F* a,TH2F* b){
  //this add a to b
  if (!a) {
    if (fverbose) std::cerr<<"Error:LData::AddTH2F: a is zero n";
    return -1;
  }
  if (!b) {
    if (fverbose) std::cerr<<"Error:LData::AddTH2F: b is zero n";
    return -1;
  }
  b->Add((TH1*)a);
  return 0;//success
}
 
TObject* 
 LData::GetHistogram(Option_t* option,Float_t binwidth){
  //create and fill histograms 
  //binwidth is used for RESOLUTION parameter
  //when using option TTIME, binwidth (if set) is used to set number of bins
  //for option see LData::Draw
  //Profiles are used with default options- error on mean

  TString opt = option;
  opt.ToLower();

  if (opt.Contains(".vt.")) return (TObject*)fvt;

  if (opt.Contains(".pt.")) return (TObject*)fpt;

  if (opt.Contains(".vp.")) return (TObject*)fvp;

  if (opt.Contains(".et.")) return (TObject*)fet;

  if (opt.Contains(".avt.")) {
    //check if a profile with identical name exist
    TObject *h1obj = gROOT->FindObject("avt");
    if (h1obj && h1obj->InheritsFrom("TProfile")) return h1obj;
    TProfile* hprof=fvt->ProfileX("avt");
    hprof->SetTitle("Average Velocity vs Time");
    SetStyle((TH1*)hprof,"Time [a.u.]","Average Velocity [a.u.]");
    return (TObject*) hprof;
  }
  
  if (opt.Contains(".avp.")) {
    //check if a profile with identical name exist
    TObject *h1obj = gROOT->FindObject("avp");
    if (h1obj && h1obj->InheritsFrom("TProfile")) return h1obj;
    TProfile* hprof=fvp->ProfileX("avp");
    hprof->SetTitle("Average Velocity vs Position");
    SetStyle((TH1*)hprof,"Position [Ang.]","Average Velocity [a.u.]");
    return (TObject*) hprof;
  }
  
  if (opt.Contains(".apt.")) {
    //check if a profile with identical name exist
    TObject *h1obj = gROOT->FindObject("apt");
    if (h1obj && h1obj->InheritsFrom("TProfile")) return h1obj;
    TProfile* hprof=fpt->ProfileX("apt");
    hprof->SetTitle("Average Position vs Time");
    SetStyle((TH1*)hprof,"Time [a.u.]","Average Position [Ang.]");
    return (TObject*) hprof;
  }

  if (opt.Contains(".aet.")) {
    //check if a profile with identical name exist
    TObject *h1obj = gROOT->FindObject("aet");
    if (h1obj && h1obj->InheritsFrom("TProfile")) return h1obj;
    TProfile* hprof=fet->ProfileX("aet");
    hprof->SetTitle("Average Energy vs Time");
    SetStyle((TH1*)hprof,"Time [a.u.]","Average Energy [eV]");
    return (TObject*) hprof;
  }


  if (opt.Contains(".av.")) {
    //check if a profile with identical name exist
    TObject *h1obj = gROOT->FindObject("ttime");
    if (h1obj && h1obj->InheritsFrom("TH1F")) return h1obj;
    if (fnav>1){
      Float_t max=GetMaxTTime();
      Float_t min=GetMinTTime();
      Int_t nbins;
      if (binwidth>1.0) nbins=(Int_t) binwidth;
      else nbins=(Int_t)sqrt(fnav);
      min-=0.5*(max-min)/nbins;
      max+=0.5*(max-min)/nbins;

      TH1F* graf=new TH1F("ttime","Average Velocity Distribution",nbins+1,min,max);
      if (nbins>1){
	Prepare();
	for(Int_t i=1;i<=fnav;i++) graf->Fill(fav[i]);
	SetStyle((TH1*)graf,"Transit time [a.u.]","Frequency");
	return (TObject*)graf;
      }
      else
	std::cerr<<"Error: LData::GetHistogram - histogram is empty!n";
    }
    else std::cerr<<"Only one ttimen";
  }
  

  //TOF simulation 
  //new histogram value I(i) is calculated from the fvt(i,j)
  //using the following formula:
  //   I(i)=Sum_j(fvt(i,j)*v(j))
  //where v(j) is velocity in y axis of fvt. STATISTICAL Error is
  //   Sigma(I(j))=sqrt(Sum_j(fvt(i,j)))*Sigma(v(j))
  //where is assumed that all Sigma(v(j)) are the same
  if (opt.Contains(".tof.")) {
    
    Int_t nx = fvt->GetXaxis()->GetNbins();
    Int_t ny = fvt->GetYaxis()->GetNbins();
    
    const char* pname="tof";
    TH1D *h1=0;
    //check if a hist with identical name exist
    TObject *h1obj = gROOT->FindObject(pname);
    if (h1obj && h1obj->InheritsFrom("TH1D")) {
      h1 = (TH1D*)h1obj;
      h1->Reset();
    }
    
    if (!h1) {
      const TArrayD *bins = fvt->GetXaxis()->GetXbins();
      if (bins->fN == 0) {
        h1 = new TH1D(pname,"TOF simulation",nx,fvt->GetXaxis()->GetXmin(),fvt->GetXaxis()->GetXmax());
      } else {
	h1 = new TH1D(pname,"TOF simulation",nx,bins->fArray);
      }
    }
    
    // Fill the histogram
    Double_t cont,sum,sum2;
    for (Int_t binx =1;binx<=nx;binx++) {
      sum=0.0;
      sum2=0.0;
      for (Int_t biny=1;biny<=ny;biny++) {
        cont =  fvt->GetCellContent(binx,biny);
        if (cont) {
	  sum=cont*fvt->GetYaxis()->GetBinCenter(biny);
	  h1->Fill(fvt->GetXaxis()->GetBinCenter(binx),sum);
	  sum2+=sum*sum/cont;
        }
      }
      //assuming all widths are the same
      if (sum2>0.0)
      	h1->SetBinError(binx,sqrt(sum2));
    }
    //normalize tof
    h1->SetEntries(fN);
    h1->Scale(1.0/h1->GetEntries());//normalization per particle
    h1->Scale(1.0/fheader->fresolution);//since velocity is not normalized
    h1->Scale(1.0/(fheader->rpmax-fheader->rpmin));//weighting field
    
    SetStyle(h1,"Time [a.u.]","Current [a.u.]");
    return (TObject*) h1;
  }

  //draw bias array
  if (opt.Contains(".bias.")) {
    if (!fheader) {
      std::cerr<<"Error in LData::GetHistogram(): no header present in LDatan";
      return 0;
    }
    TH1F *h1=fheader->GetBiasHist();
    SetStyle(h1,"Position [Ang.]","Bias Potential [eV]");
    return (TObject*) h1;
  }
  
  std::cerr<<"Error in LData::GetHistogram()n";
  return 0;
}

void 
 LData::Browse(TBrowser*){
  Inspect();
  gPad->Update();
}

void
 LData::DrawPanel(){
  printf("mona");
}

void 
 LData::Draw(Option_t* option){
  //see LData::Paint() for more info
  TString opt = option;
  opt.ToLower();
  if (gPad) {
    if (!gPad->IsEditable()) (gROOT->GetMakeDefCanvas())();
    if (!opt.Contains("same")) {
      //the following statement is necessary in case one attempts to draw
      //a temporary histogram already in the current pad
      if (TestBit(kCanDelete)) gPad->GetListOfPrimitives()->Remove(this);
      gPad->Clear();
    }
  }
  AppendPad(opt.Data());  
}

void 
 LData::Paint(Option_t* option){
  //Regarding option, this method draws distribution of
  // .VT. -- velocity vs time 
  // .AVT. -- average velocity vs time
  // .PT. -- position vs time 
  // .APT. -- average position vs time
  // .VP.  -- velocity vs position
  // .AVP.  -- average velocity vs position
  // .ET. -- energy vs time 
  // .AET. -- average energy vs time 
  // .AV. -- average velocity distibution (different data)
  // .TOF. -- photogenerated current vs time
  //.BIAS. -- bias vs position
  // 
  //histograms are created dynamically - potential memory leak!

  TObject* graf=GetHistogram(option);

  if (graf){
    //remove my labels
    TString opt = option;
    opt.ToLower();
    if (opt.Contains(".vt.")) 
      opt.Remove(opt.Index(".vt.",4),4);
    if (opt.Contains(".avt.")) 
      opt.Remove(opt.Index(".avt.",5),5);
    if (opt.Contains(".pt.")) 
      opt.Remove(opt.Index(".pt.",4),4);
    if (opt.Contains(".apt.")) 
      opt.Remove(opt.Index(".apt.",5),5);
    if (opt.Contains(".vp.")) 
      opt.Remove(opt.Index(".vp.",4),4);
    if (opt.Contains(".avp.")) 
      opt.Remove(opt.Index(".avp.",5),5);
    if (opt.Contains(".et.")) 
      opt.Remove(opt.Index(".et.",4),4);
    if (opt.Contains(".aet.")) 
      opt.Remove(opt.Index(".aet.",4),4);
    if (opt.Contains(".av.")) 
      opt.Remove(opt.Index(".av.",4),4);
    if (opt.Contains(".tof.")) 
      opt.Remove(opt.Index(".tof.",5),5);
    if (opt.Contains(".bias.")) 
      opt.Remove(opt.Index(".bias.",6),6);
    
    
    gStyle->SetCanvasBorderMode(0);
    gStyle->SetCanvasColor(0);
    gStyle->SetFillStyle(4000);//transparent canvas
    gStyle->SetTitleBorderSize(0);
    gStyle->SetFrameFillColor(0);
    gStyle->SetTitleColor(0);
    //TCanvas* c1=new TCanvas("LData","LData",1);
    //    c1->Update();

    graf->Paint(opt.Data());
  }
}


bool
 LData::Test(Int_t mode)const {
  //various tests, see LDisorder::for example
  //* in test mode 1, the particle should only travel in z dimension,
  //  so at each time step, they should be in another bin. The most important
  //  is, that the MAX is equal to SPACEZ 
  
  Int_t nx = fvt->GetXaxis()->GetNbins();
  Int_t ny = fvt->GetYaxis()->GetNbins();
  bool passed=true;

  if (mode==1){
    double sum;
    double should=(double)fN;
    for(int i=1;i<=nx;i++){
      sum=0.0;
      for (int j=1;j<=ny;j++) sum+=fvt->GetCellContent(i,j);
      if (sum!=should) {
	printf("Error:time bin:%d sum: %e - should be:%en",i,sum,should);
	passed=false;
      }
    }
  }
  return passed;
}
  /*
 TF1* LData::GetTTime(Int_t nbins){
  //this fits gaussian to ttime histogram and returns the fitted function
  //use ->GetParameter(2) to mean value
  //use ->GetParameter(3) to std

  Double_t sigma,mean;
  TH1F* data=GetHistogram("ttime",(Float_t) nbins);
  Int_t center=data->GetMaximumBin();
  Int_t low=center-nbins/10;
  Int_t high=center+nbins/10;
  TF1* g1=new TF1("g1","gaus");
  //g1->SetLineColor(2);
  data->Fit("g1","NOQ","",data->GetBinCenter(low),data->GetBinCenter(high));
  sigma=g1->GetParameter(2);
  mean=g1->GetParameter(1);
  data->Fit("g1","NOQ","",mean-sigma,mean+sigma);
  return g1;
}

//TA VARIANTA BOLJE DELUJE
  Int_t nbins=600; //WARNING!!!
  TH1F* graf2=data2->GetHistogram("ttime",nbins);

  Double_t sigma,mean;
  Double_t param[4];
  Int_t center=graf2->GetMaximumBin();
  Int_t low=center-nbins/10;
  Int_t high=center+nbins/10;
  TF1* g1=new TF1("g1","landau");
  g1->SetLineColor(3);
  graf2->Fit("g1","NOQ");

  TF1* g2=new TF1("g2",Total,data2->GetMinTTime(),data2->GetMaxTTime(),4);
  param[0]=g1->Eval(g1->GetParameter(1));
  param[1]=g1->GetParameter(1);
  param[2]=5.0*g1->GetParameter(2);
  param[3]=g1->GetParameter(2);;
  g2->SetParameters(param);
  g2->SetLineColor(2);
  graf2->Fit("g2","NOQ");
  //c1->Update();  while (!getchar());  
  *x=-1.0*header2->fgradient;
  *y=g2->GetParameter(1)*header2->fresolution;
  *err=g2->GetParameter(3)*header2->fresolution;

*/

void 
 LData::Streamer(TBuffer &R__b){
  //special streamer for LContainer

  if(R__b.IsReading()){
    Version_t R__v;
    R__v=R__b.ReadVersion();
    TNamed::Streamer(R__b);

    R__b>>fjobID;
    R__b>>fN;
    R__b>>fnav;

    if (!fav) Tnew(fav,1,fnav);
    R__b.ReadFastArray(fav+1,fnav);

    R__b>>favg;
    R__b>>favsig;
    if (R__v > 3) {
      R__b>>fcpu_time;
    }


    if (!fpt) fpt=new TH2F();
    fpt->Streamer(R__b);
    if (!fvt) fvt=new TH2F();
    fvt->Streamer(R__b);
    if (!fvp) fvp=new TH2F();
    fvp->Streamer(R__b);
    if (!fet) fet=new TH2F();
    fet->Streamer(R__b);

    if (!fheader)
      fheader=new LDataHeader();
    
    fheader->Streamer(R__b);
    if (fheader->GetJobID()!=fjobID)
      if (fverbose) std::cerr<<"Warrning:LData::Streamer: incoming data has different header!!!n";
    
  } else {
    Prepare();
    Version_t R__v=LData::IsA()->GetClassVersion();
    R__b.WriteVersion(LData::IsA());
    TNamed::Streamer(R__b);
    
    R__b<<fjobID;
    R__b<<fN;
    R__b<<fnav;

    R__b.WriteFastArray(fav+1,fnav);

    R__b<<favg;
    R__b<<favsig;
    if (R__v > 3) {
      R__b<<fcpu_time;
    }

    TH2F* his=fpt;
    if (!his) his=new TH2F();
    his->Streamer(R__b);    
    his=fvt;
    if (!his) his=new TH2F();
    his->Streamer(R__b);    
    his=fvp;
    if (!his) his=new TH2F();
    his->Streamer(R__b);    
    his=fet;
    if (!his) his=new TH2F();
    his->Streamer(R__b);    
    

    if (!fheader){
      fheader=new LDataHeader();
      fheader->SetJobID(fjobID);
    }
    fheader->Streamer(R__b);    
  }
}




ROOT page - Class index - Top of the page

This page has been automatically generated. If you have any comments or suggestions about the page layout send a mail to ROOT support, or contact the developers with any questions or problems regarding ROOT.