/* ======================================================================== *\
!
! *
! * This file is part of MARS, the MAGIC Analysis and Reconstruction
! * Software. It is distributed to you in the hope that it can be a useful
! * and timesaving tool in analysing Data of imaging Cerenkov telescopes.
! * It is distributed WITHOUT ANY WARRANTY.
! *
! * Permission to use, copy, modify and distribute this software and its
! * documentation for any purpose is hereby granted without fee,
! * provided that the above copyright notice appear in all copies and
! * that both that copyright notice and this permission notice appear
! * in supporting documentation. It is provided "as is" without express
! * or implied warranty.
! *
!
!
!   Author(s): Thomas Bretz, 11/2005 <mailto:tbretz@astro.uni-wuerzburg.de>
!   Author(s): Daniela Dorner, 11/2005 <mailto:dorner@astro.uni-wuerzburg.de>
!   Author(s): Daniel Hoehne, 05/2007 <mailto:hoehne@astro.uni-wuerzburg.de>
!
!   Copyright: MAGIC Software Development, 2000-2007
!
!
\* ======================================================================== */

/////////////////////////////////////////////////////////////////////////////
//
// fillcamera.C
// ============
//
// This macro is used to read the camera-output files.
//
// Make sure, that database and password are corretly set in a resource
// file called sql.rc and the resource file is found.
//
// Returns 0 in case of failure and 1 in case of success.
//
//
// At the moment the macro works but produces a segmentation violation.
//
//
/////////////////////////////////////////////////////////////////////////////
#include <iostream>
#include <iomanip>

#include <TEnv.h>
#include <TRegexp.h>

#include <TFile.h>
#include <TTree.h>
#include <TBranch.h>

#include <TH1.h>

#include <TSQLResult.h>
#include <TSQLRow.h>

#include "MSQLServer.h"
#include "MSQLMagic.h"
#include "MGeomCamMagic.h"

#include "MMcRunHeader.hxx"
#include "MMcConfigRunHeader.h"
#include "MMcCorsikaRunHeader.h"
#include "MMcFadcHeader.hxx"
#include "MMcEvtBasic.h"
#include "MGeomCamMagic.h"
#include "MRawRunHeader.h"

#include <math.h>
#include <MBinning.h>

using namespace std;
// --------------------------------------------------------------------------
//
// Checks whether an entry is already existing
//
Bool_t ExistStr(MSQLServer &serv, const char *column, const char *table, Int_t test)
{
    TString query(Form("SELECT %s FROM %s WHERE %s='%d'", column, table, column, test));
    TSQLResult *res = serv.Query(query);
    if (!res)
        return kFALSE;

    TSQLRow *row;

    Bool_t rc = kFALSE;
    while ((row=res->Next()))
    {
        if ((*row)[0])
        {
            rc = kTRUE;
            break;
        }
    }

    delete res;

    return rc;
}
/*
//
// Function to transform zenithangle range to zbin (not needed any more)
//
Double_t ThetaToZBin(Double_t tmin, Double_t tmax)
{
    double result=TMath::Nint(100*(1-TMath::Cos(((tmin+tmax)/2)*TMath::DegToRad())));
    return result;
}
*/

//int Process(MSQLServer &serv, TString fname, Bool_t dummy)
int Process(MSQLMagic &serv, TString fname, Bool_t dummy)
{
    TFile file(fname, "READ");
    if (!file.IsOpen())
    {
        cout << "ERROR - Could not find file " << fname << endl;
        return 0;
    }

//
// Get tree RunHeaders from file
//
    TTree *tree = dynamic_cast<TTree*>(file.Get("RunHeaders"));
    if (!tree)
    {
        cout << "ERROR - Tree RunHeaders not found in file " << fname << endl;
        return 0;
    }
//
// Get branch MMcCorsikaRunHeader from tree RunHeaders
//
    TBranch *b1 = tree->GetBranch("MMcCorsikaRunHeader.");
    if (!b1)
    {
        cout << "ERROR - Branch MMcCorsikaRunHeader. not found in file " << fname << endl;
        return 0;
    }

    MMcCorsikaRunHeader *runheader1 = new MMcCorsikaRunHeader();
    b1->SetAddress(&runheader1);
//
// Get branch MMcConfigRunHeader from tree RunHeaders
//
    TBranch *b2 = tree->GetBranch("MMcConfigRunHeader.");
    if (!b2)
    {
        cout << "ERROR - Branch MMcConfigRunHeader. not found in file " << fname << endl;
        return 0;
    }

    MMcConfigRunHeader *runheader2 = new MMcConfigRunHeader();
    b2->SetAddress(&runheader2);
//
// Get branch MMcRunHeader from tree RunHeaders
//
    TBranch *b3 = tree->GetBranch("MMcRunHeader.");
    if (!b3)
    {
        cout << "ERROR - Branch MMcRunHeader. not found in file " << fname << endl;
        return 0;
    }

    MMcRunHeader *runheader3 = new MMcRunHeader();
    b3->SetAddress(&runheader3);
//
// Get branch MMcFadcRunHeader from tree RunHeaders
//
    TBranch *b4 = tree->GetBranch("MMcFadcHeader.");
    if (!b4)
    {
        cout << "ERROR - Branch MMcFadcHeader. not found in file " << fname << endl;
        return 0;
    }

    MMcFadcHeader *fadcheader = new MMcFadcHeader();
    b4->SetAddress(&fadcheader);
//
// Get branch MRawRunHearder from tree RunHeaders
//
    TBranch *b5 = tree->GetBranch("MRawRunHeader.");
    if (!b5)
    {
        cout << "ERROR - Branch MRawRunHeader. not found in file " << fname << endl;
        return 0;
    }

    MRawRunHeader *rawheader = new MRawRunHeader();
    b5->SetAddress(&rawheader);

    tree->GetEvent(0);
//
// Get tree Events from file
//
    TTree *tree2 = dynamic_cast<TTree*>(file.Get("Events"));
    if (!tree2)
    {
        cout << "ERROR - Tree Events not found in file " << fname << endl;
        return 0;
    }
//
// Get branch MMcEvtBasic from tree Events
//
    TBranch *b6 = tree2->GetBranch("MMcEvtBasic.");
    if (!b6)
    {
        cout << "ERROR - Branch MMcEvtBasic. not found in file " << fname << endl;
        return 0;
    }

    MMcEvtBasic *evtbasic = new MMcEvtBasic();
    b6->SetAddress(&evtbasic);

    tree2->GetEvent(0);



    Float_t emin = runheader1->GetELowLim();
    TString elow = Form("%5.1f",emin);
    Float_t emax = runheader1->GetEUppLim();
    TString eupp = Form("%5.1f",emax);

    Float_t slopespec  = runheader1->GetSlopeSpec();
    TString slope      = Form("%5.1f",slopespec);

    Float_t wobblemode = runheader1->GetWobbleMode();
    TString wobble     = Form("%5.0f",wobblemode);

    Float_t corsvers1  = runheader1->GetCorsikaVersion();
    TString corsika1   = Form("%5.0f",corsvers1);

    Float_t pointspread    = runheader2->GetPointSpread();
    TString psf            = Form("%5.1f",pointspread);
    Float_t pointspreadx   = runheader2->GetPointSpreadX();
    TString psfx           = Form("%5.2f",pointspreadx);
    Float_t pointspready   = runheader2->GetPointSpreadY();
    TString psfy           = Form("%5.2f",pointspready);
    Float_t pointspreadadd = TMath::Hypot(runheader2->GetPointSpreadX(), runheader2->GetPointSpread());
    TString psfadd         = Form("%5.2f",pointspreadadd);

    Float_t mispointingx = runheader2->GetMissPointingX();
    TString misx         = Form("%5.2f",mispointingx);
    Float_t mispointingy = runheader2->GetMissPointingY();
    TString misy         = Form("%5.2f",mispointingy);

    Float_t reflvers  = runheader3->GetReflVersion();
    TString reflector = Form("%5.0f",reflvers);
    Float_t camvers   = runheader3->GetCamVersion();
    TString camera    = Form("%5.0f",camvers);

    Float_t impactmax = runheader3->GetImpactMax();
    TString imax      = Form("%5.1f",impactmax);

    TH1I h("myhist", "", 1, -0.5, 0.5);
    tree2->Draw("MRawEvtData.GetNumPixels()>>myhist", "", "goff");
    h.SetDirectory(0);
    UInt_t numtriggers = TMath::Nint(h.GetBinContent(2));
    TString numtrig = Form("%7.0i",numtriggers);

    UInt_t numsimshow = runheader3->GetNumSimulatedShowers();
    TString numss     = Form("%7.0i",numsimshow);
    UInt_t numevents  = tree2->GetEntries();
    TString numevt    = Form("%7.0i",numevents);

    Float_t numphednsb = runheader3->GetNumPheFromDNSB();
    TString numphe    = Form("%5.1f",numphednsb);

    Float_t pedestal     = fadcheader->GetPedestal(1);
    TString ped          = Form("%5.1f",pedestal);
    Float_t low2highgain = fadcheader->GetLow2HighGain();
    TString low2high     = Form("%5.1f",low2highgain);

    Float_t amplitude = fadcheader->GetAmplitud();
    TString amplfadc  = Form("%5.1f",amplitude);
    Float_t amplitudo = fadcheader->GetAmplitudOuter();
    TString amplfadco = Form("%5.1f",amplitudo);

    Float_t elecnoise = fadcheader->GetElecNoise(1);
    TString enoise    = Form("%5.1f",elecnoise);
    Float_t diginoise = fadcheader->GetDigitalNoise(1);
    TString dnoise    = Form("%5.1f",diginoise);

    Float_t phimin = runheader3->GetShowerPhiMin();
    TString pmin   = Form("%5.1f",phimin);
    Float_t phimax = runheader3->GetShowerPhiMax();
    TString pmax   = Form("%5.1f",phimax);

    Float_t particleid   = evtbasic->GetPartId();
    TString partid       = Form("%5.0f",particleid);
    TString partname     = evtbasic->GetParticleName();
//    TString partname = Form("%5.1f",particlename);

    Double_t tmin    = runheader3->GetShowerThetaMin();
    TString thetamin = Form("%5.1f",tmin);
    Double_t tmax    = runheader3->GetShowerThetaMax();
    TString thetamax = Form("%5.1f",tmax);

    Float_t mirrorfraction = runheader2->GetMirrorFraction();
    TString mirrfrac       = Form("%5.2f",mirrorfraction);
//    Float_t reflectivity   = runheader2->GetMirrors()->GetReflectivity()->GetArray();
//    TString refl           = Form("%5.2f",reflectivity);


//workaround for getting the spotsize in cm from PointSpreadX (for path)
/*
    Double_t psfx=runheader2->GetPointSpreadX();
    cout << "psfx=" << psfx << endl;
    psfx=psfx*10;
    Int_t psfxint= (int) psfx;
    psfx=psfxint;
    psfx=psfx/10;
    cout << "PSF for path=" << psfx << endl;
*/




/*
//     Bestimmung von fakewobble aus file
//     Kombination aus Wobble(0,1) und MissPoint
    TString WobbleMod;

    if (wobblemode != 0){
        WobbleMod = "wobble";
    }
    else
    {
        if (mispointingx == 0 && mispointingy == 0){
            WobbleMod = "nowobble";
        }
        else{
            WobbleMod = "fakewobble";
        }
     }
*/
    /* Bestimmung von fakewobble aus file */
    /* Kombination aus Wobble(0,1) und MissPoint */
    TString WobbleMod;

    if (wobblemode == 1){
        WobbleMod = "Wobble";
    }
    else
    {
        if (mispointingx == 0 && mispointingy == 0){
            WobbleMod = "On";
        }
        else{
            WobbleMod = "Fake Wobble";            // als ObservationModeKEY 4 einfügen?
        }
     }

    Float_t pointsfx=TMath::Floor(pointspreadx*10);
    pointsfx=TMath::Nint(pointsfx);
    TString pointsfuncx=Form("%5.1f",pointsfx);

//    Float_t cos1=TMath::DegToRad(tmin);
//    Float_t cos2=TMath::DegToRad(tmax);
    Float_t zBin=TMath::Nint((1-((TMath::Cos(tmin*TMath::Pi()/180)+TMath::Cos(tmax*TMath::Pi()/180))/2))*100);
    zBin=TMath::Nint(zBin);

// folgende Werte werden aus dem Pfadnamen gewonnen   !!!neue Pfadstuktur!!!
//     RunNumber
    TRegexp reg2("_[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]_");
    TString Run = fname(reg2);
    Int_t RunNum = atoi(Run.Data()+1);

     if (RunNum < 1 || RunNum > 99999)
     {
         cout << "ERROR - RunNumber wrong value" << endl;
         return 0;
     }

//     PointSpreadFunction
    TRegexp reg4("/[12][0-9]/");
    TString pointsf = fname(reg4);
    Int_t Point = atoi(pointsf.Data()+1);

    if (Point < 0 || Point > 99)
    {
        cout << "ERROR - PointSpreadFunction wrong value" << endl;

        return 0;
    }

//     zbin
    TRegexp reg1("/19[0-9][0-9]/");
    TString zbin = fname(reg1);
    Int_t ZBin  = atoi(zbin.Data()+3);

    if (ZBin < 0 || ZBin > 99)
    {
        cout << "ERROR - zbin wrong value" << endl;
        return 0;
    }

// WobbleMode
    TRegexp reg3("/0[0-9]/");	/*extrahiert '/0X'   mit X= 1-8 */
    TString WM = fname(reg3);	/* weist WM den extrahierten Wert zu */
    Int_t Wob = atoi(WM.Data()+1); /* schneidet fuehrenden '/' ab */

     if (Wob < 1 || Wob > 8)
     {
         cout << "ERROR - ObservationMode wrong value" << endl;
         return 0;
     }


    /* wandelt numerischen Wert in WobbleModus Bezeichnung um */

     const TString wobbleModes[] = {
        "",     	// 0 wird nicht verwendet, daher ein leeres Feld
        "Gammawobble+",
        "Gammanowobble0",
        "GammawobbleHE+",
        "GammanowobbleHE0",
        "Gammawobble0",
        "GammawobbleHE0",
        "Gammadiffuse0"
        "Protonnowobble0",
    };

    /* Umrechnung von WobbleModus Bezeichnung in 'wobble', 'nowobble', 'fakewobble' */
    TString WobMode;	/* dieser Wert wird in 'MCDB' Tabelle 'WobbleMode' eingetragen */

    if (Wob == 1 || Wob == 3){
        WobMode = "Wobble";
    }
    if (Wob == 2 || Wob == 4 || Wob == 7 || Wob == 8){
        WobMode = "On";
    }
    if (Wob == 5 || Wob == 6){
        WobMode = "Fake Wobble";
     }


    /*    MGeomCamMagic m;
    cout << fadcheader->GetAmplitud() << endl;
    cout << fadcheader->GetCameraMean(m, 0)<<  endl;
    cout << fadcheader->GetCameraMean(m, 1)<<  endl;
*/

    cout << "File " << fname << endl;


    cout << endl;
    cout << endl;

    cout << "--- From File ---" << endl;

//    cout << wobblemode << endl;
//    cout << wobble << endl;
    cout << endl;
    cout << elow << " < E < " << eupp      << endl;
    cout << "SpectralIndex  " << slope     << endl;
    cout << "WobbleMode     " << WobbleMod << endl;
    cout << "ObservationMode " << WobbleMod << endl;
    cout << "CorsikaVer     " << corsika1  << endl;
    cout << "ReflVer        " << reflector << endl;
    cout << "CamVer         " << camera    << endl;
    cout << "ParticleId     " << partid    << endl;
    cout << "ParticleName  "  << partname  << endl;
    cout << "PointSpread    " << psf       << endl;
    cout << "PointSpreadXY  " << psfx      << " /" << psfy << endl;
    cout << "AdditionPSF    " << psfadd << endl;
    cout << "MispointingXY  " << misx << " /" << misy <<endl;
    cout << "NumSimShowers  " << numss     << endl;
    cout << "ImpactMax      " << imax      << endl;
    cout << "NumEvents      " << numevt    << endl;
    cout << "NumTriggers    " << numtrig   << endl;
    cout << "NumPheFromDNSB " << numphe    << endl;
    cout << "Pedestal       " << ped       << endl;
    cout << "Low2HighGain   " << low2high  << endl;
    cout << "AmplitudeFADC  " << amplfadc  << endl;
    cout << "AmplFADCOuter  " << amplfadco << endl;
    cout << "ElecNoise      " << enoise    << endl;
    cout << "DigiNoise      " << dnoise    << endl;
    cout << "PhiMin         " << pmin      << endl;
    cout << "PhiMax         " << pmax      << endl;
    cout << "ThetaMin       " << thetamin  << endl;
    cout << "ThetaMax       " << thetamax  << endl;

//    cout << "Zenith range=" << runheader3->GetShowerThetaMin() << "to" << runheader3->GetShowerThetaMax() << endl;
    cout << "Zenith range      " << tmin << " to " << tmax << endl;

//    cout << "zbin              " << ThetaToZBin(tmin,tmax) << endl;

    cout << "MirrorFraction " << mirrfrac << endl;
//    cout << "Reflectivity   " << refl     << endl;

    cout << endl;
    cout << endl;
    cout << "--- key's from mcdb tables ---" << endl;
    cout << endl;


//    Int_t corsikakey = QueryNameKEY(serv, dummy, "CorsikaVersion", Form("%d",CorVer));

//    Int_t corsikakey = QueryNameKEY(serv, dummy, "CorsikaVersion", corsika1.Data());
    Int_t corsikakey = serv.QueryKeyOfName("CorsikaVersion", corsika1.Data());
    cout << "corsikakey: " << corsikakey << endl;

//    Int_t reflectorkey = QueryNameKEY(serv, dummy, "ReflectorVersion", reflector.Data());
    Int_t reflectorkey = serv.QueryKeyOfName("ReflectorVersion", reflector.Data());
    cout << "reflectorkey: " << reflectorkey << endl;

//    Int_t camerakey = QueryNameKEY(serv, dummy, "CameraVersion", camera.Data());
    Int_t camerakey = serv.QueryKeyOfName("CameraVersion", camera.Data());
    cout << "camerakey: " << camerakey << endl;

//    Int_t wobblekey = QueryNameKEY(serv, dummy, "WobbleMode",Form("%s",WobbleMod.Data()));
    Int_t wobblekey = serv.QueryKeyOfName("WobbleMode", WobbleMod.Data());
    cout << "wobblekey: " << wobblekey << endl;

//    Int_t observationkey = QueryNameKEY(serv, dummy, "ObservationMode",Form("%s",WobbleMod.Data()));
    Int_t observationkey = serv.QueryKeyOfName("ObservationMode", WobbleMod.Data());
    cout << "observationkey: " << observationkey << endl;

//     Int_t particlekey = QueryNameKEY(serv, dummy, "MCParticle", Form("%s",partname.Data()));
    Int_t particlekey = serv.QueryKeyOfName("MCParticle", partname.Data());
     cout << "particlekey: " << particlekey << endl;
    cout << endl;
    cout << endl;

//    TRegexp reg1("/Spot_[0123456789.]*/");
//    TRegexp reg2("/[a-zA-Z]*wobble[a-zA-Z]*/");
//    TRegexp reg3("_zbin[0-9]+_");

    cout << "--- From File ---" << endl;
    cout << endl;
    cout << "WobbleMode     " << WobbleMod << endl;
    cout << "PSF            " << pointsfuncx << endl;
    cout << "zBin           " << zBin << endl;
    cout << endl;
    cout << "--- From FileName ---" << endl;
    cout << endl;
    cout << "WobbleMode       " << WobMode   << endl;
    cout << "RunNum           " << RunNum    << endl;
    cout << "PSF              " << Point     << endl;
    cout << "ZBin             " << ZBin      << endl;
    cout << "WobbleMode(Pfad) " << Wob       << endl;
    cout << endl;
    cout << "--- Check ---" << endl;
    cout << endl;

    if (WobbleMod!=WobMode){
        cout << "Error, WobbleMode in file and filename are not the same" << endl;
        return 0;
    }
    else{
        cout << "WobbleMode correct" << endl;
    }
    if (pointsfx!=Point){
        cout << "Error, PSF in file and filename are not the same" << endl;
        return 0;
    }
    else{
        cout << "PSF correct" << endl;
    }
    if (zBin!=ZBin){
        cout << "Error, ZBin in file and filename are not the same" << endl;
        return 0;
    }
    else{
        cout << "ZBin correct" << endl;
    }

    delete runheader1;
    delete runheader2;
    delete runheader3;
    delete fadcheader;
    delete rawheader;
    delete evtbasic;


    TString query;

    if (!ExistStr(serv, "fRunNumber", "MCRunData", RunNum ))
    {
        query = Form(" INSERT INTO MCRunData SET"
                     " fELowLim=%s,"
                     " fEUppLim=%s, "
                     " fSlopeSpec=%s, "
                     " fImpactMax=%s, "
                     " fNumSimulatedShowers=%d, "
                     " fNumEvents=%d, "
                     " fNumPheFromDNSB=%s, "
                     " fzbin=%d, "
		     " fThetaMin=%s, "
		     " fThetaMax=%s, "
                     " fPointSpread=%s, "
		     " fPointSpreadX=%s, "
		     " fPointSpreadY=%s, "
		     " fPedesMean=%s, "
		     " fLow2HighGain=%s, "
		     " fAmplFadc=%s, "
		     " fAmplFadcOuter=%s, "
		     " fElectricNoise=%s, "
		     " fDigitalNoise=%s, "
		     " fRunNumber=%d, "
		     " fMisspointingX=%s, "
		     " fMissPointingY=%s, "
		     " fCorsikaVersionKEY =%d, "
		     " fReflectorVersionKEY=%d, "
		     " fCameraVersionKEY=%d, "
		     " fWobbleModeKEY=%d, "
		     " fObservationModeKEY=%d, "
		     " fMCParticleKEY=%d, "
		     " fSequenceFirst=0 ",
                     elow.Data(), eupp.Data(), slope.Data(), imax.Data(), numsimshow, numevents, numphe.Data(),
	   	     zBin, thetamin.Data(), thetamax.Data(), psf.Data(), psfx.Data(), psfy.Data(), ped.Data(), low2high.Data(),
		     amplfadc.Data(), amplfadco.Data(), enoise.Data(), dnoise.Data(), RunNum,
                     misx.Data(), misy.Data(), corsikakey, reflectorkey, camerakey, wobblekey, observationkey, particlekey  );

    }

//
//  not yet implemented
//

/*
    if (!ExistStr(serv, "fRunNumber", "MCRunData", RunNum ))
    {
    query = Form(" fELowLim=%s,"
                 " fEUppLim=%s, "
                 " fSlopeSpec=%s, "
                 " fImpactMax=%s, "
                 " fNumSimulatedShowers=%d, "
                 " fNumEvents=%d, "
                 " fNumPheFromDNSB=%s, "
                 " fzbin=%d, "
                 " fThetaMin=%s, "
                 " fThetaMax=%s, "
                 " fPointSpread=%s, "
                 " fPointSpreadX=%s, "
                 " fPointSpreadY=%s, "
                 " fPedesMean=%s, "
                 " fLow2HighGain=%s, "
                 " fAmplFadc=%s, "
                 " fAmplFadcOuter=%s, "
                 " fElectricNoise=%s, "
                 " fDigitalNoise=%s, "
                 " fRunNumber=%d, "
                 " fMisspointingX=%s, "
                 " fMissPointingY=%s, "
                 " fCorsikaVersionKEY =%d, "
                 " fReflectorVersionKEY=%d, "
                 " fCameraVersionKEY=%d, "
                 " fWobbleModeKEY=%d, "
                 " fObservationModeKEY=%d, "
                 " fMCParticleKEY=%d, "
                 " fSequenceFirst=0 ",
                 elow.Data(), eupp.Data(), slope.Data(), imax.Data(), numsimshow, numevents, numphe.Data(),
                 zBin, thetamin.Data(), thetamax.Data(), psf.Data(), psfx.Data(), psfy.Data(), ped.Data(), low2high.Data(),
                 amplfadc.Data(), amplfadco.Data(), enoise.Data(), dnoise.Data(), RunNum,
                 misx.Data(), misy.Data(), corsikakey, reflectorkey, camerakey, wobblekey, observationkey, particlekey  );
    }

    if (serv.Insert("MCRunData", query)==kFALSE)
        return 2;
*/


    else
    {

        query = Form(" UPDATE MCRunData SET "
                     " fELowLim=%s,"
                     " fEUppLim=%s, "
                     " fSlopeSpec=%s, "
                     " fImpactMax=%s, "
                     " fNumSimulatedShowers=%d, "
                     " fNumEvents=%d, "
                     " fNumPheFromDNSB=%s, "
                     " fzbin=%d, "
		     " fThetaMin=%s, "
		     " fThetaMax=%s, "
                     " fPointSpread=%s, "
		     " fPointSpreadX=%s, "
		     " fPointSpreadY=%s, "
		     " fPedesMean=%s, "
		     " fLow2HighGain=%s, "
		     " fAmplFadc=%s, "
		     " fAmplFadcOuter=%s, "
		     " fElectricNoise=%s, "
		     " fDigitalNoise=%s, "
		     " fMisspointingX=%s, "
		     " fMissPointingY=%s, "
		     " fCorsikaVersionKEY =%d, "
		     " fReflectorVersionKEY=%d, "
		     " fCameraVersionKEY=%d, "
		     " fWobbleModeKEY=%d, "
		     " fObservationModeKEY=%d, "
		     " fMCParticleKEY=%d, "
		     " WHERE fRunNumber=%d ",
                     elow.Data(), eupp.Data(), slope.Data(), imax.Data(), numsimshow, numevents, numphe.Data(),
	   	     zBin, thetamin.Data(), thetamax.Data(), psf.Data(), psfx.Data(), psfy.Data(), ped.Data(), low2high.Data(),
		     amplfadc.Data(), amplfadco.Data(), enoise.Data(), dnoise.Data(),
                     misx.Data(), misy.Data(), corsikakey, reflectorkey, camerakey, wobblekey, observationkey, particlekey, RunNum  );

    }
//
//  not yet implemented
//

/*
        query = Form(" fELowLim=%s,"
                     " fEUppLim=%s, "
                     " fSlopeSpec=%s, "
                     " fImpactMax=%s, "
                     " fNumSimulatedShowers=%d, "
                     " fNumEvents=%d, "
                     " fNumPheFromDNSB=%s, "
                     " fzbin=%d, "
		     " fThetaMin=%s, "
		     " fThetaMax=%s, "
                     " fPointSpread=%s, "
		     " fPointSpreadX=%s, "
		     " fPointSpreadY=%s, "
		     " fPedesMean=%s, "
		     " fLow2HighGain=%s, "
		     " fAmplFadc=%s, "
		     " fAmplFadcOuter=%s, "
		     " fElectricNoise=%s, "
		     " fDigitalNoise=%s, "
		     " fMisspointingX=%s, "
		     " fMissPointingY=%s, "
		     " fCorsikaVersionKEY =%d, "
		     " fReflectorVersionKEY=%d, "
		     " fCameraVersionKEY=%d, "
		     " fWobbleModeKEY=%d, "
		     " fObservationModeKEY=%d, "
		     " fMCParticleKEY=%d ",
                     elow.Data(), eupp.Data(), slope.Data(), imax.Data(), numsimshow, numevents, numphe.Data(),
	   	     zBin, thetamin.Data(), thetamax.Data(), psf.Data(), psfx.Data(), psfy.Data(), ped.Data(), low2high.Data(),
		     amplfadc.Data(), amplfadco.Data(), enoise.Data(), dnoise.Data(),
                     misx.Data(), misy.Data(), corsikakey, reflectorkey, camerakey, wobblekey, observationkey, particlekey );

    }
*/


//    if (serv.Update("MCRunData", query, "fRunNumber")==kFALSE)
//        return 2;


    if (dummy)
        return 0;

    TSQLResult *res = serv.Query(query);
    if (!res)
    {
        cout << "ERROR - Query failed: " << query << endl;
        return 0;
    }

    return 1;
}

int fillcamera(TString fname, Bool_t dummy=kTRUE)
{
    TEnv env("sql.rc");

//    MSQLServer serv(env);
    MSQLMagic serv(env);
    if (!serv.IsConnected())
    {
        cout << "ERROR - Connection to database failed." << endl;
        return 2;
    }

    serv.SetIsDummy(dummy);

    cout << endl;
    cout << "fillcamera" << endl;
    cout << "---------" << endl;
    cout << endl;
    cout << "Connected to " << serv.GetName() << endl;
    cout << "File: " << fname << endl;
    cout << endl;

    return Process(serv, fname, dummy);

}
