<commit_before>/***************************************************************************
 //          	Modified by Kunal Garg - 03/05/2018 (kgarg@cern.ch)
 //            Based on AddAnalysisTaskRsnMini
 //
 //
 // Macro to configure the KStarPlusMinus analysis task
 // It calls all configs desired by the user, by means
 // of the boolean switches defined in the first lines.
 // ---
 // Inputs:
 //  1) flag to know if running on MC or data
 //  2) collision system, whether pp, pPb or PbPb
 // --
 // Returns:
 //  kTRUE  --> initialization successful
 //  kFALSE --> initialization failed (some config gave errors)
 //
 ****************************************************************************/

//enum ERsnCollType_t { kPP=0,      kPPb,      kPbPb};

enum pairYCutSet { kPairDefault,    // USED ONLY FOR pA
    kNegative,       // USED ONLY FOR pA
    kCentral         // USED ONLY FOR pA
};

enum eventCutSet { kEvtDefault=0,
    kNoPileUpCut, //=1
    kDefaultVtx12,//=2
    kDefaultVtx8, //=3
    kDefaultVtx5, //=4
    kMCEvtDefault, //=5
    kSpecial1, //=6
    kSpecial2, //=7
    kNoEvtSel, //=8
    kSpecial3, //=9
    kSpecial4, //=10
    kSpecial5 //=11
};

enum eventMixConfig { kDisabled = -1,
    kMixDefault,     //=0 //10 events, Dvz = 1cm, DC = 10
    k5Evts,          //=1 //5 events, Dvz = 1cm, DC = 10
    k5Cent,          //=2 //10 events, Dvz = 1cm, DC = 5
};

AliRsnMiniAnalysisTask *AddTaskKStarPlusMinusRun2016
(
 Bool_t      isMC,
 Bool_t      isPP,
 Float_t     cutV = 10.0,
 Bool_t      isGT = 0,
 Int_t       evtCutSetID = 0,
 Int_t       pairCutSetID = 0,
 Int_t       mixingConfigID = 0,
 Int_t       aodFilterBit = 0,
 Bool_t      enableMonitor=kTRUE,
 TString     monitorOpt="pp",
 Float_t     piPIDCut = 3.0,
 Int_t       customQualityCutsID=1,
 AliRsnCutSetDaughterParticle::ERsnDaughterCutSet cutPiCandidate = AliRsnCutSetDaughterParticle::kTPCpidphipp2015,
 Float_t     pi_k0s_PIDCut = 5.0,
 Float_t     massTol = 0.03,
 Float_t     massTolVeto = 0.0043,
 Int_t       tol_switch = 1,
 Double_t    tol_sigma = 4,
 Float_t     pLife = 20,
 Float_t     radiuslow = 0.5,
 Bool_t      Switch = kTRUE,
 Float_t     k0sDCA = 1000.0,
 Float_t     k0sCosPoinAn = 0.97,
 Float_t     k0sDaughDCA = 1.0,
 Int_t       NTPCcluster = 70,
 TString     outNameSuffix = "KStarPlusMinus_test_func",
 Float_t     DCAxy = 0.06,
 Bool_t      enableSys = kFALSE,
 Float_t     crossedRows = 70,
 Float_t     rowsbycluster = 0.8,
 Float_t		 v0rapidity= 0.8,
 Int_t       Sys= 0
 )
{
    //-------------------------------------------
    // event cuts
    //-------------------------------------------
    UInt_t      triggerMask=AliVEvent::kINT7;
    Bool_t      rejectPileUp=kTRUE;
    Double_t    vtxZcut=10.0;//cm, default cut on vtx z
    Int_t       MultBins=aodFilterBit/100;
    //   cout<<"EVENTCUTID is    "<<evtCutSetID<<endl;
    if(evtCutSetID==eventCutSet::kDefaultVtx12) vtxZcut=12.0; //cm
    if(evtCutSetID==eventCutSet::kDefaultVtx8) vtxZcut=8.0; //cm
    if(evtCutSetID==eventCutSet::kDefaultVtx5) vtxZcut=5.0; //cm
    if(evtCutSetID==eventCutSet::kNoPileUpCut) rejectPileUp=kFALSE;

    if(isMC) rejectPileUp=kFALSE;

    //-------------------------------------------
    //mixing settings
    //-------------------------------------------

    Int_t       nmix = 10;
    if (mixingConfigID == eventMixConfig::kMixDefault) nmix = 10;
    if (mixingConfigID == eventMixConfig::k5Evts)      nmix = 5;
    if (mixingConfigID == eventMixConfig::k5Cent)      maxDiffMultMix = 5;

    //
    // -- INITIALIZATION ----------------------------------------------------------------------------
    // retrieve analysis manager
    //

    AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
    if (!mgr) {
        ::Error("AddTaskKStarPlusMinus", "No analysis manager to connect to.");
        return NULL;
    }

    // create the task and configure
    TString taskName = Form("KStarPlusMinus%s%s", (isPP? "pp" : "PbPb"), (isMC ? "MC" : "Data"));

	AliRsnMiniAnalysisTask* task = new AliRsnMiniAnalysisTask(taskName.Data(),isMC);

	if(evtCutSetID==eventCutSet::kSpecial4 || evtCutSetID==eventCutSet::kSpecial5) task->UseESDTriggerMask(triggerMask); //ESD ****** check this *****
		//if(evtCutSetID!=eventCutSet::kNoEvtSel && evtCutSetID!=eventCutSet::kSpecial3 && evtCutSetID!=eventCutSet::kSpecial4) task->SelectCollisionCandidates(triggerMask); //AOD
	if(evtCutSetID!=eventCutSet::kNoEvtSel && evtCutSetID!=eventCutSet::kSpecial3 && evtCutSetID!=eventCutSet::kSpecial4) task->UseESDTriggerMask(triggerMask); //AOD

	if(isPP){
		if(MultBins==1) task->UseMultiplicity("AliMultSelection_V0M");
		else if(MultBins==2) task->UseMultiplicity("AliMultSelection_RefMult08");
		else task->UseMultiplicity("QUALITY");
	}else task->UseCentrality("V0M");

    // set event mixing options
    task->UseContinuousMix();
    //task->UseBinnedMix();
    task->SetNMix(nmix);
    task->SetMaxDiffVz(1.0);
    task->SetMaxDiffMult(5.0);
    ::Info("AddAnalysisTaskKStarCharged", Form("Event mixing configuration: \n events to mix = %i \n max diff. vtxZ = cm %5.3f \n max diff multi = %\5.3f", nmix, 1.0, 10.0));

    mgr->AddTask(task);

    //
    // -- EVENT CUTS (same for all configs) ---------------------------------------------------------
    //
    // cut on primary vertex:
    // - 2nd argument --> |Vz| range
    // - 3rd argument --> minimum required number of contributors
    // - 4th argument --> tells if TPC stand-alone vertexes must be accepted

    AliRsnCutPrimaryVertex *cutVertex = 0;
    if(evtCutSetID!=eventCutSet::kSpecial1 && evtCutSetID!=eventCutSet::kNoEvtSel && (!MultBins || fabs(vtxZcut-10.)>1.e-10)){
        cutVertex=new AliRsnCutPrimaryVertex("cutVertex",vtxZcut,0,kFALSE);
        if(!MultBins && evtCutSetID!=eventCutSet::kSpecial3){
            cutVertex->SetCheckZResolutionSPD();
            cutVertex->SetCheckDispersionSPD();
            cutVertex->SetCheckZDifferenceSPDTrack();
        }
        if(evtCutSetID==eventCutSet::kSpecial3) cutVertex->SetCheckGeneratedVertexZ();
    }

    AliRsnCutEventUtils* cutEventUtils=0;
    if(evtCutSetID!=eventCutSet::kNoEvtSel && evtCutSetID!=eventCutSet::kSpecial3){
        cutEventUtils=new AliRsnCutEventUtils("cutEventUtils",kTRUE,rejectPileUp);
        if(!MultBins){
            cutEventUtils->SetCheckIncompleteDAQ();
            cutEventUtils->SetCheckSPDClusterVsTrackletBG();
			  	cutEventUtils->SetCheckInelGt0MC(kFALSE);
        }else{
            //cutEventUtils->SetCheckInelGt0SPDtracklets();
            cutEventUtils->SetRemovePileUppA2013(kFALSE);
            cutEventUtils->SetCheckAcceptedMultSelection();
        }
    }

    if(!isMC){ //assume pp data
        cutVertex->SetCheckPileUp(rejectPileUp);// set the check for pileup
        ::Info("AddAnalysisTaskKStarCharged", Form(":::::::::::::::::: Pile-up rejection mode: %s", (rejectPileUp)?"ON":"OFF"));
    }

    // define and fill cut set for event cut
    AliRsnCutSet* eventCuts=0;
    if(cutEventUtils || cutVertex){
        eventCuts=new AliRsnCutSet("eventCuts",AliRsnTarget::kEvent);

        if(cutEventUtils && cutVertex){
            eventCuts->AddCut(cutEventUtils);
            eventCuts->AddCut(cutVertex);
            eventCuts->SetCutScheme(Form("%s&%s",cutEventUtils->GetName(),cutVertex->GetName()));
        }else if(cutEventUtils && !cutVertex){
            eventCuts->AddCut(cutEventUtils);
            eventCuts->SetCutScheme(Form("%s",cutEventUtils->GetName()));
        }else if(!cutEventUtils && cutVertex){
            eventCuts->AddCut(cutVertex);
            eventCuts->SetCutScheme(Form("%s",cutVertex->GetName()));
        }

        task->SetEventCuts(eventCuts);
    }

    // -- EVENT-ONLY COMPUTATIONS -------------------------------------------------------------------
    //vertex
    Int_t vtxID=task->CreateValue(AliRsnMiniValue::kVz,kFALSE);
    AliRsnMiniOutput* outVtx=task->CreateOutput("eventVtx","HIST","EVENT");
    outVtx->AddAxis(vtxID,240,-12.0,12.0);

    //multiplicity
    Int_t multID=task->CreateValue(AliRsnMiniValue::kMult,kFALSE);
    AliRsnMiniOutput* outMult=task->CreateOutput("eventMult","HIST","EVENT");
    //if(isPP)
    outMult->AddAxis(multID,400,0.5,400.5);
    //else outMult->AddAxis(multID,100,0.,100.);

    TH2F* hvz=new TH2F("hVzVsCent","",100,0.,100., 240,-12.0,12.0);
    task->SetEventQAHist("vz",hvz);//plugs this histogram into the fHAEventVz data member

    TH2F* hmc=new TH2F("MultiVsCent","", 100,0.,100., 400,0.5,400.5);
    hmc->GetYaxis()->SetTitle("QUALITY");
    task->SetEventQAHist("multicent",hmc);//plugs this histogram into the fHAEventMultiCent data member

    //
    // -- PAIR CUTS (common to all resonances) ------------------------------------------------------
    Double_t    minYlab =  -0.5;
    Double_t    maxYlab =  0.5;

    AliRsnCutMiniPair* cutY=new AliRsnCutMiniPair("cutRapidity", AliRsnCutMiniPair::kRapidityRange);
    cutY->SetRangeD(-0.5,0.5);

    AliRsnCutMiniPair* cutV0=new AliRsnCutMiniPair("cutV0", AliRsnCutMiniPair::kContainsV0Daughter);

    AliRsnCutSet* PairCutsSame=new AliRsnCutSet("PairCutsSame",AliRsnTarget::kMother);
    PairCutsSame->AddCut(cutY);
    PairCutsSame->AddCut(cutV0);
    PairCutsSame->SetCutScheme(TString::Format("%s&(!%s)",cutY->GetName(),cutV0->GetName()).Data());
    //note the use of the ! operator in this cut scheme

    AliRsnCutSet* PairCutsMix=new AliRsnCutSet("PairCutsMix",AliRsnTarget::kMother);
    PairCutsMix->AddCut(cutY);
    PairCutsMix->SetCutScheme(cutY->GetName());
    //
    // -- CONFIG ANALYSIS --------------------------------------------------------------------------
    gROOT->LoadMacro("$ALICE_PHYSICS/PWGLF/RESONANCES/macros/mini/ConfigKStarPlusMinusRun2016.C");
    //gROOT->LoadMacro("ConfigKStarPlusMinusRun2016.C");
    if (isMC) {
        Printf("========================== MC analysis - PID cuts not used");
    } else
        Printf("========================== DATA analysis - PID cuts used");

    if (!ConfigKStarPlusMinusRun2016(task, isPP, isMC, isGT, piPIDCut,customQualityCutsID, cutPiCandidate, pi_k0s_PIDCut, aodFilterBit, enableMonitor, monitorOpt.Data(), massTol, massTolVeto, tol_switch, tol_sigma, pLife, radiuslow, Switch, k0sDCA, k0sCosPoinAn, k0sDaughDCA, NTPCcluster, "", PairCutsSame, PairCutsMix, DCAxy, enableSys, crossedRows, rowsbycluster, v0rapidity, Sys)) return 0x0;

    //
    // -- CONTAINERS --------------------------------------------------------------------------------
    //
    TString outputFileName = AliAnalysisManager::GetCommonFileName();
    //  outputFileName += ":Rsn";
    Printf("AddTaskKStarPlusMinus - Set OutputFileName : \n %s\n", outputFileName.Data() );

    AliAnalysisDataContainer *output = mgr->CreateContainer(Form("RsnOut_%s_%.1f_%.1f_%.1f_%.2f_%.3f_%.f_%.f_%.f_%.1f_%.2f_%.1f_%.3f_%.1f", outNameSuffix.Data(),piPIDCut,customQualityCutsID,pi_k0s_PIDCut,massTol,massTolVeto,pLife,radiuslow, k0sDCA,k0sCosPoinAn,k0sDaughDCA, DCAxy, Sys), TList::Class(), AliAnalysisManager::kOutputContainer, outputFileName);

    mgr->ConnectInput(task, 0, mgr->GetCommonInputContainer());
    mgr->ConnectOutput(task, 1, output);

    return task;
}
<commit_msg>Modification on AddTask macro to load systematic studies on Charged KStar analysis in Run2<commit_after>/***************************************************************************
 //          	Modified by Kunal Garg - 03/05/2018 (kgarg@cern.ch)
 //            Based on AddAnalysisTaskRsnMini
 //
 //
 // Macro to configure the KStarPlusMinus analysis task
 // It calls all configs desired by the user, by means
 // of the boolean switches defined in the first lines.
 // ---
 // Inputs:
 //  1) flag to know if running on MC or data
 //  2) collision system, whether pp, pPb or PbPb
 // --
 // Returns:
 //  kTRUE  --> initialization successful
 //  kFALSE --> initialization failed (some config gave errors)
 //
 ****************************************************************************/

//enum ERsnCollType_t { kPP=0,      kPPb,      kPbPb};

enum pairYCutSet { kPairDefault,    // USED ONLY FOR pA
    kNegative,       // USED ONLY FOR pA
    kCentral         // USED ONLY FOR pA
};

enum eventCutSet { kEvtDefault=0,
    kNoPileUpCut, //=1
    kDefaultVtx12,//=2
    kDefaultVtx8, //=3
    kDefaultVtx5, //=4
    kMCEvtDefault, //=5
    kSpecial1, //=6
    kSpecial2, //=7
    kNoEvtSel, //=8
    kSpecial3, //=9
    kSpecial4, //=10
    kSpecial5 //=11
};

enum eventMixConfig { kDisabled = -1,
    kMixDefault,     //=0 //10 events, Dvz = 1cm, DC = 10
    k5Evts,          //=1 //5 events, Dvz = 1cm, DC = 10
    k5Cent,          //=2 //10 events, Dvz = 1cm, DC = 5
};

AliRsnMiniAnalysisTask *AddTaskKStarPlusMinusRun2016
(
 Bool_t      isMC,
 Bool_t      isPP,
 Float_t     cutV = 10.0,
 Bool_t      isGT = 0,
 Int_t       evtCutSetID = 0,
 Int_t       pairCutSetID = 0,
 Int_t       mixingConfigID = 0,
 Int_t       aodFilterBit = 0,
 Bool_t      enableMonitor=kTRUE,
 TString     monitorOpt="pp",
 Float_t     piPIDCut = 3.0,
 Int_t       customQualityCutsID=1,
 AliRsnCutSetDaughterParticle::ERsnDaughterCutSet cutPiCandidate = AliRsnCutSetDaughterParticle::kTPCpidphipp2015,
 Float_t     pi_k0s_PIDCut = 5.0,
 Float_t     massTol = 0.03,
 Float_t     massTolVeto = 0.0043,
 Int_t       tol_switch = 1,
 Double_t    tol_sigma = 4,
 Float_t     pLife = 20,
 Float_t     radiuslow = 0.5,
 Bool_t      Switch = kTRUE,
 Float_t     k0sDCA = 1000.0,
 Float_t     k0sCosPoinAn = 0.97,
 Float_t     k0sDaughDCA = 1.0,
 Int_t       NTPCcluster = 70,
 TString     outNameSuffix = "KStarPlusMinus_test_func",
 Float_t     DCAxy = 0.06,
 Bool_t      enableSys = kFALSE,
 Float_t     crossedRows = 70,
 Float_t     rowsbycluster = 0.8,
 Float_t		 v0rapidity= 0.8,
 Int_t       Sys= 0
 )
{
    //-------------------------------------------
    // event cuts
    //-------------------------------------------
    UInt_t      triggerMask=AliVEvent::kINT7;
    Bool_t      rejectPileUp=kTRUE;
    Double_t    vtxZcut=10.0;//cm, default cut on vtx z
    Int_t       MultBins=aodFilterBit/100;
    //   cout<<"EVENTCUTID is    "<<evtCutSetID<<endl;
    if(evtCutSetID==eventCutSet::kDefaultVtx12) vtxZcut=12.0; //cm
    if(evtCutSetID==eventCutSet::kDefaultVtx8) vtxZcut=8.0; //cm
    if(evtCutSetID==eventCutSet::kDefaultVtx5) vtxZcut=5.0; //cm
    if(evtCutSetID==eventCutSet::kNoPileUpCut) rejectPileUp=kFALSE;

    if(isMC) rejectPileUp=kFALSE;

    //-------------------------------------------
    //mixing settings
    //-------------------------------------------

    Int_t       nmix = 10;
    if (mixingConfigID == eventMixConfig::kMixDefault) nmix = 10;
    if (mixingConfigID == eventMixConfig::k5Evts)      nmix = 5;
    if (mixingConfigID == eventMixConfig::k5Cent)      maxDiffMultMix = 5;

    //
    // -- INITIALIZATION ----------------------------------------------------------------------------
    // retrieve analysis manager
    //

    AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
    if (!mgr) {
        ::Error("AddTaskKStarPlusMinus", "No analysis manager to connect to.");
        return NULL;
    }

    // create the task and configure
    TString taskName = Form("KStarPlusMinus%s%s", (isPP? "pp" : "PbPb"), (isMC ? "MC" : "Data"));

	AliRsnMiniAnalysisTask* task = new AliRsnMiniAnalysisTask(taskName.Data(),isMC);

	if(evtCutSetID==eventCutSet::kSpecial4 || evtCutSetID==eventCutSet::kSpecial5) task->UseESDTriggerMask(triggerMask); //ESD ****** check this *****
		//if(evtCutSetID!=eventCutSet::kNoEvtSel && evtCutSetID!=eventCutSet::kSpecial3 && evtCutSetID!=eventCutSet::kSpecial4) task->SelectCollisionCandidates(triggerMask); //AOD
	if(evtCutSetID!=eventCutSet::kNoEvtSel && evtCutSetID!=eventCutSet::kSpecial3 && evtCutSetID!=eventCutSet::kSpecial4) task->UseESDTriggerMask(triggerMask); //AOD

	if(isPP){
		if(MultBins==1) task->UseMultiplicity("AliMultSelection_V0M");
		else if(MultBins==2) task->UseMultiplicity("AliMultSelection_RefMult08");
		else task->UseMultiplicity("QUALITY");
	}else task->UseCentrality("V0M");

    // set event mixing options
    task->UseContinuousMix();
    //task->UseBinnedMix();
    task->SetNMix(nmix);
    task->SetMaxDiffVz(1.0);
    task->SetMaxDiffMult(5.0);
    ::Info("AddAnalysisTaskKStarCharged", Form("Event mixing configuration: \n events to mix = %i \n max diff. vtxZ = cm %5.3f \n max diff multi = %\5.3f", nmix, 1.0, 10.0));

    mgr->AddTask(task);

    //
    // -- EVENT CUTS (same for all configs) ---------------------------------------------------------
    //
    // cut on primary vertex:
    // - 2nd argument --> |Vz| range
    // - 3rd argument --> minimum required number of contributors
    // - 4th argument --> tells if TPC stand-alone vertexes must be accepted

    AliRsnCutPrimaryVertex *cutVertex = 0;
    if(evtCutSetID!=eventCutSet::kSpecial1 && evtCutSetID!=eventCutSet::kNoEvtSel && (!MultBins || fabs(vtxZcut-10.)>1.e-10)){
        cutVertex=new AliRsnCutPrimaryVertex("cutVertex",vtxZcut,0,kFALSE);
        if(!MultBins && evtCutSetID!=eventCutSet::kSpecial3){
            cutVertex->SetCheckZResolutionSPD();
            cutVertex->SetCheckDispersionSPD();
            cutVertex->SetCheckZDifferenceSPDTrack();
        }
        if(evtCutSetID==eventCutSet::kSpecial3) cutVertex->SetCheckGeneratedVertexZ();
    }

    AliRsnCutEventUtils* cutEventUtils=0;
    if(evtCutSetID!=eventCutSet::kNoEvtSel && evtCutSetID!=eventCutSet::kSpecial3){
        cutEventUtils=new AliRsnCutEventUtils("cutEventUtils",kTRUE,rejectPileUp);
        if(!MultBins){
            cutEventUtils->SetCheckIncompleteDAQ();
            cutEventUtils->SetCheckSPDClusterVsTrackletBG();
			  	cutEventUtils->SetCheckInelGt0MC(kFALSE);
        }else{
            //cutEventUtils->SetCheckInelGt0SPDtracklets();
            cutEventUtils->SetRemovePileUppA2013(kFALSE);
            cutEventUtils->SetCheckAcceptedMultSelection();
        }
    }

    if(!isMC){ //assume pp data
        cutVertex->SetCheckPileUp(rejectPileUp);// set the check for pileup
        ::Info("AddAnalysisTaskKStarCharged", Form(":::::::::::::::::: Pile-up rejection mode: %s", (rejectPileUp)?"ON":"OFF"));
    }

    // define and fill cut set for event cut
    AliRsnCutSet* eventCuts=0;
    if(cutEventUtils || cutVertex){
        eventCuts=new AliRsnCutSet("eventCuts",AliRsnTarget::kEvent);

        if(cutEventUtils && cutVertex){
            eventCuts->AddCut(cutEventUtils);
            eventCuts->AddCut(cutVertex);
            eventCuts->SetCutScheme(Form("%s&%s",cutEventUtils->GetName(),cutVertex->GetName()));
        }else if(cutEventUtils && !cutVertex){
            eventCuts->AddCut(cutEventUtils);
            eventCuts->SetCutScheme(Form("%s",cutEventUtils->GetName()));
        }else if(!cutEventUtils && cutVertex){
            eventCuts->AddCut(cutVertex);
            eventCuts->SetCutScheme(Form("%s",cutVertex->GetName()));
        }

        task->SetEventCuts(eventCuts);
    }

    // -- EVENT-ONLY COMPUTATIONS -------------------------------------------------------------------
    //vertex
    Int_t vtxID=task->CreateValue(AliRsnMiniValue::kVz,kFALSE);
    AliRsnMiniOutput* outVtx=task->CreateOutput("eventVtx","HIST","EVENT");
    outVtx->AddAxis(vtxID,240,-12.0,12.0);

    //multiplicity
    Int_t multID=task->CreateValue(AliRsnMiniValue::kMult,kFALSE);
    AliRsnMiniOutput* outMult=task->CreateOutput("eventMult","HIST","EVENT");
    //if(isPP)
    outMult->AddAxis(multID,400,0.5,400.5);
    //else outMult->AddAxis(multID,100,0.,100.);

    TH2F* hvz=new TH2F("hVzVsCent","",100,0.,100., 240,-12.0,12.0);
    task->SetEventQAHist("vz",hvz);//plugs this histogram into the fHAEventVz data member

    TH2F* hmc=new TH2F("MultiVsCent","", 100,0.,100., 400,0.5,400.5);
    hmc->GetYaxis()->SetTitle("QUALITY");
    task->SetEventQAHist("multicent",hmc);//plugs this histogram into the fHAEventMultiCent data member

    //
    // -- PAIR CUTS (common to all resonances) ------------------------------------------------------
    Double_t    minYlab =  -0.5;
    Double_t    maxYlab =  0.5;

    AliRsnCutMiniPair* cutY=new AliRsnCutMiniPair("cutRapidity", AliRsnCutMiniPair::kRapidityRange);
    cutY->SetRangeD(-0.5,0.5);

    AliRsnCutMiniPair* cutV0=new AliRsnCutMiniPair("cutV0", AliRsnCutMiniPair::kContainsV0Daughter);

    AliRsnCutSet* PairCutsSame=new AliRsnCutSet("PairCutsSame",AliRsnTarget::kMother);
    PairCutsSame->AddCut(cutY);
    PairCutsSame->AddCut(cutV0);
    PairCutsSame->SetCutScheme(TString::Format("%s&(!%s)",cutY->GetName(),cutV0->GetName()).Data());
    //note the use of the ! operator in this cut scheme

    AliRsnCutSet* PairCutsMix=new AliRsnCutSet("PairCutsMix",AliRsnTarget::kMother);
    PairCutsMix->AddCut(cutY);
    PairCutsMix->SetCutScheme(cutY->GetName());
    //
    // -- CONFIG ANALYSIS --------------------------------------------------------------------------
    gROOT->LoadMacro("$ALICE_PHYSICS/PWGLF/RESONANCES/macros/mini/ConfigKStarPlusMinusRun2.C");
    //gROOT->LoadMacro("$ALICE_PHYSICS/PWGLF/RESONANCES/macros/mini/ConfigKStarPlusMinusRun2016.C");
    //gROOT->LoadMacro("ConfigKStarPlusMinusRun2016.C");
    if (isMC) {
        Printf("========================== MC analysis - PID cuts not used");
    } else
        Printf("========================== DATA analysis - PID cuts used");

    if (!ConfigKStarPlusMinusRun2(task, isPP, isMC, isGT, piPIDCut,customQualityCutsID, cutPiCandidate, pi_k0s_PIDCut, aodFilterBit, enableMonitor, monitorOpt.Data(), massTol, massTolVeto, tol_switch, tol_sigma, pLife, radiuslow, Switch, k0sDCA, k0sCosPoinAn, k0sDaughDCA, NTPCcluster, "", PairCutsSame, PairCutsMix, DCAxy, enableSys, crossedRows, rowsbycluster, v0rapidity, Sys)) return 0x0;

    //
    // -- CONTAINERS --------------------------------------------------------------------------------
    //
    TString outputFileName = AliAnalysisManager::GetCommonFileName();
    //  outputFileName += ":Rsn";
    Printf("AddTaskKStarPlusMinus - Set OutputFileName : \n %s\n", outputFileName.Data() );

    AliAnalysisDataContainer *output = mgr->CreateContainer(Form("RsnOut_%s_%.1f_%.1f_%.1f_%.2f_%.3f_%.f_%.f_%.f_%.1f_%.2f_%.1f_%.3f_%.1f", outNameSuffix.Data(),piPIDCut,customQualityCutsID,pi_k0s_PIDCut,massTol,massTolVeto,pLife,radiuslow, k0sDCA,k0sCosPoinAn,k0sDaughDCA, DCAxy, Sys), TList::Class(), AliAnalysisManager::kOutputContainer, outputFileName);

    mgr->ConnectInput(task, 0, mgr->GetCommonInputContainer());
    mgr->ConnectOutput(task, 1, output);

    return task;
}
<|endoftext|>


<commit_before>//===-- source/Host/linux/Host.cpp ------------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/utsname.h>
#include <unistd.h>

#include "llvm/Object/ELF.h"
#include "llvm/Support/ScopedPrinter.h"

#include "lldb/Utility/Log.h"
#include "lldb/Utility/ProcessInfo.h"
#include "lldb/Utility/Status.h"

#include "lldb/Host/FileSystem.h"
#include "lldb/Host/Host.h"
#include "lldb/Host/HostInfo.h"
#include "lldb/Host/linux/Support.h"
#include "lldb/Utility/DataExtractor.h"

using namespace lldb;
using namespace lldb_private;

namespace {
enum class ProcessState {
  Unknown,
  DiskSleep,
  Paging,
  Running,
  Sleeping,
  TracedOrStopped,
  Zombie,
};
}

namespace lldb_private {
class ProcessLaunchInfo;
}

static bool GetStatusInfo(::pid_t Pid, ProcessInstanceInfo &ProcessInfo,
                          ProcessState &State, ::pid_t &TracerPid) {
  auto BufferOrError = getProcFile(Pid, "status");
  if (!BufferOrError)
    return false;

  llvm::StringRef Rest = BufferOrError.get()->getBuffer();
  while(!Rest.empty()) {
    llvm::StringRef Line;
    std::tie(Line, Rest) = Rest.split('\n');

    if (Line.consume_front("Gid:")) {
      // Real, effective, saved set, and file system GIDs. Read the first two.
      Line = Line.ltrim();
      uint32_t RGid, EGid;
      Line.consumeInteger(10, RGid);
      Line = Line.ltrim();
      Line.consumeInteger(10, EGid);

      ProcessInfo.SetGroupID(RGid);
      ProcessInfo.SetEffectiveGroupID(EGid);
    } else if (Line.consume_front("Uid:")) {
      // Real, effective, saved set, and file system UIDs. Read the first two.
      Line = Line.ltrim();
      uint32_t RUid, EUid;
      Line.consumeInteger(10, RUid);
      Line = Line.ltrim();
      Line.consumeInteger(10, EUid);

      ProcessInfo.SetUserID(RUid);
      ProcessInfo.SetEffectiveUserID(EUid);
    } else if (Line.consume_front("PPid:")) {
      ::pid_t PPid;
      Line.ltrim().consumeInteger(10, PPid);
      ProcessInfo.SetParentProcessID(PPid);
    } else if (Line.consume_front("State:")) {
      char S = Line.ltrim().front();
      switch (S) {
      case 'R':
        State = ProcessState::Running;
        break;
      case 'S':
        State = ProcessState::Sleeping;
        break;
      case 'D':
        State = ProcessState::DiskSleep;
        break;
      case 'Z':
        State = ProcessState::Zombie;
        break;
      case 'T':
        State = ProcessState::TracedOrStopped;
        break;
      case 'W':
        State = ProcessState::Paging;
        break;
      }
    } else if (Line.consume_front("TracerPid:")) {
      Line = Line.ltrim();
      Line.consumeInteger(10, TracerPid);
    }
  }
  return true;
}

static bool IsDirNumeric(const char *dname) {
  for (; *dname; dname++) {
    if (!isdigit(*dname))
      return false;
  }
  return true;
}

static ArchSpec GetELFProcessCPUType(llvm::StringRef exe_path) {
  Log *log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);

  auto buffer_sp = FileSystem::Instance().CreateDataBuffer(exe_path, 0x20, 0);
  if (!buffer_sp)
    return ArchSpec();

  uint8_t exe_class =
      llvm::object::getElfArchType(
          {buffer_sp->GetChars(), size_t(buffer_sp->GetByteSize())})
          .first;

  switch (exe_class) {
  case llvm::ELF::ELFCLASS32:
    return HostInfo::GetArchitecture(HostInfo::eArchKind32);
  case llvm::ELF::ELFCLASS64:
    return HostInfo::GetArchitecture(HostInfo::eArchKind64);
  default:
    LLDB_LOG(log, "Unknown elf class ({0}) in file {1}", exe_class, exe_path);
    return ArchSpec();
  }
}

static void GetProcessArgs(::pid_t pid, ProcessInstanceInfo &process_info) {
  auto BufferOrError = getProcFile(pid, "cmdline");
  if (!BufferOrError)
    return;
  std::unique_ptr<llvm::MemoryBuffer> Cmdline = std::move(*BufferOrError);

  llvm::StringRef Arg0, Rest;
  std::tie(Arg0, Rest) = Cmdline->getBuffer().split('\0');
  process_info.SetArg0(Arg0);
  while (!Rest.empty()) {
    llvm::StringRef Arg;
    std::tie(Arg, Rest) = Rest.split('\0');
    process_info.GetArguments().AppendArgument(Arg);
  }
}

static void GetExePathAndArch(::pid_t pid, ProcessInstanceInfo &process_info) {
  Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));
  std::string ExePath(PATH_MAX, '\0');

  // We can't use getProcFile here because proc/[pid]/exe is a symbolic link.
  llvm::SmallString<64> ProcExe;
  (llvm::Twine("/proc/") + llvm::Twine(pid) + "/exe").toVector(ProcExe);

  ssize_t len = readlink(ProcExe.c_str(), &ExePath[0], PATH_MAX);
  if (len > 0) {
    ExePath.resize(len);
  } else {
    LLDB_LOG(log, "failed to read link exe link for {0}: {1}", pid,
             Status(errno, eErrorTypePOSIX));
    ExePath.resize(0);
  }
  // If the binary has been deleted, the link name has " (deleted)" appended.
  // Remove if there.
  llvm::StringRef PathRef = ExePath;
  PathRef.consume_back(" (deleted)");

  if (!PathRef.empty()) {
    process_info.GetExecutableFile().SetFile(PathRef, FileSpec::Style::native);
    process_info.SetArchitecture(GetELFProcessCPUType(PathRef));
  }
}

static void GetProcessEnviron(::pid_t pid, ProcessInstanceInfo &process_info) {
  // Get the process environment.
  auto BufferOrError = getProcFile(pid, "environ");
  if (!BufferOrError)
    return;

  std::unique_ptr<llvm::MemoryBuffer> Environ = std::move(*BufferOrError);
  llvm::StringRef Rest = Environ->getBuffer();
  while (!Rest.empty()) {
    llvm::StringRef Var;
    std::tie(Var, Rest) = Rest.split('\0');
    process_info.GetEnvironment().insert(Var);
  }
}

static bool GetProcessAndStatInfo(::pid_t pid,
                                  ProcessInstanceInfo &process_info,
                                  ProcessState &State, ::pid_t &tracerpid) {
  tracerpid = 0;
  process_info.Clear();

  process_info.SetProcessID(pid);

  GetExePathAndArch(pid, process_info);
  GetProcessArgs(pid, process_info);
  GetProcessEnviron(pid, process_info);

  // Get User and Group IDs and get tracer pid.
  if (!GetStatusInfo(pid, process_info, State, tracerpid))
    return false;

  return true;
}

uint32_t Host::FindProcesses(const ProcessInstanceInfoMatch &match_info,
                             ProcessInstanceInfoList &process_infos) {
  static const char procdir[] = "/proc/";

  DIR *dirproc = opendir(procdir);
  if (dirproc) {
    struct dirent *direntry = nullptr;
    const uid_t our_uid = getuid();
    const lldb::pid_t our_pid = getpid();
    bool all_users = match_info.GetMatchAllUsers();

    while ((direntry = readdir(dirproc)) != nullptr) {
      if (direntry->d_type != DT_DIR || !IsDirNumeric(direntry->d_name))
        continue;

      lldb::pid_t pid = atoi(direntry->d_name);

      // Skip this process.
      if (pid == our_pid)
        continue;

      ::pid_t tracerpid;
      ProcessState State;
      ProcessInstanceInfo process_info;

      if (!GetProcessAndStatInfo(pid, process_info, State, tracerpid))
        continue;

      // Skip if process is being debugged.
      if (tracerpid != 0)
        continue;

      if (State == ProcessState::Zombie)
        continue;

      // Check for user match if we're not matching all users and not running
      // as root.
      if (!all_users && (our_uid != 0) && (process_info.GetUserID() != our_uid))
        continue;

      if (match_info.Matches(process_info)) {
        process_infos.Append(process_info);
      }
    }

    closedir(dirproc);
  }

  return process_infos.GetSize();
}

bool Host::FindProcessThreads(const lldb::pid_t pid, TidMap &tids_to_attach) {
  bool tids_changed = false;
  static const char procdir[] = "/proc/";
  static const char taskdir[] = "/task/";
  std::string process_task_dir = procdir + llvm::to_string(pid) + taskdir;
  DIR *dirproc = opendir(process_task_dir.c_str());

  if (dirproc) {
    struct dirent *direntry = nullptr;
    while ((direntry = readdir(dirproc)) != nullptr) {
      if (direntry->d_type != DT_DIR || !IsDirNumeric(direntry->d_name))
        continue;

      lldb::tid_t tid = atoi(direntry->d_name);
      TidMap::iterator it = tids_to_attach.find(tid);
      if (it == tids_to_attach.end()) {
        tids_to_attach.insert(TidPair(tid, false));
        tids_changed = true;
      }
    }
    closedir(dirproc);
  }

  return tids_changed;
}

bool Host::GetProcessInfo(lldb::pid_t pid, ProcessInstanceInfo &process_info) {
  ::pid_t tracerpid;
  ProcessState State;
  return GetProcessAndStatInfo(pid, process_info, State, tracerpid);
}

Environment Host::GetEnvironment() { return Environment(environ); }

Status Host::ShellExpandArguments(ProcessLaunchInfo &launch_info) {
  return Status("unimplemented");
}
<commit_msg>Revert "fix"<commit_after>//===-- source/Host/linux/Host.cpp ------------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/utsname.h>
#include <unistd.h>

#include "llvm/Object/ELF.h"
#include "llvm/Support/ScopedPrinter.h"

#include "lldb/Utility/Log.h"
#include "lldb/Utility/ProcessInfo.h"
#include "lldb/Utility/Status.h"

#include "lldb/Host/FileSystem.h"
#include "lldb/Host/Host.h"
#include "lldb/Host/HostInfo.h"
#include "lldb/Host/linux/Support.h"
#include "lldb/Utility/DataExtractor.h"

using namespace lldb;
using namespace lldb_private;

namespace {
enum class ProcessState {
  Unknown,
  DiskSleep,
  Paging,
  Running,
  Sleeping,
  TracedOrStopped,
  Zombie,
};
}

namespace lldb_private {
class ProcessLaunchInfo;
}

static bool GetStatusInfo(::pid_t Pid, ProcessInstanceInfo &ProcessInfo,
                          ProcessState &State, ::pid_t &TracerPid) {
  auto BufferOrError = getProcFile(Pid, "status");
  if (!BufferOrError)
    return false;

  llvm::StringRef Rest = BufferOrError.get()->getBuffer();
  while(!Rest.empty()) {
    llvm::StringRef Line;
    std::tie(Line, Rest) = Rest.split('\n');

    if (Line.consume_front("Gid:")) {
      // Real, effective, saved set, and file system GIDs. Read the first two.
      Line = Line.ltrim();
      uint32_t RGid, EGid;
      Line.consumeInteger(10, RGid);
      Line = Line.ltrim();
      Line.consumeInteger(10, EGid);

      ProcessInfo.SetGroupID(RGid);
      ProcessInfo.SetEffectiveGroupID(EGid);
    } else if (Line.consume_front("Uid:")) {
      // Real, effective, saved set, and file system UIDs. Read the first two.
      Line = Line.ltrim();
      uint32_t RUid, EUid;
      Line.consumeInteger(10, RUid);
      Line = Line.ltrim();
      Line.consumeInteger(10, EUid);

      ProcessInfo.SetUserID(RUid);
      ProcessInfo.SetEffectiveUserID(EUid);
    } else if (Line.consume_front("PPid:")) {
      ::pid_t PPid;
      Line.ltrim().consumeInteger(10, PPid);
      ProcessInfo.SetParentProcessID(PPid);
    } else if (Line.consume_front("State:")) {
      char S = Line.ltrim().front();
      switch (S) {
      case 'R':
        State = ProcessState::Running;
        break;
      case 'S':
        State = ProcessState::Sleeping;
        break;
      case 'D':
        State = ProcessState::DiskSleep;
        break;
      case 'Z':
        State = ProcessState::Zombie;
        break;
      case 'T':
        State = ProcessState::TracedOrStopped;
        break;
      case 'W':
        State = ProcessState::Paging;
        break;
      }
    } else if (Line.consume_front("TracerPid:")) {
      Line = Line.ltrim();
      Line.consumeInteger(10, TracerPid);
    }
  }
  return true;
}

static bool IsDirNumeric(const char *dname) {
  for (; *dname; dname++) {
    if (!isdigit(*dname))
      return false;
  }
  return true;
}

static ArchSpec GetELFProcessCPUType(llvm::StringRef exe_path) {
  Log *log = GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);

  auto buffer_sp = FileSystem::Instance().CreateDataBuffer(exe_path, 0x20, 0);
  if (!buffer_sp)
    return ArchSpec();

  uint8_t exe_class =
      llvm::object::getElfArchType(
          {buffer_sp->GetChars(), size_t(buffer_sp->GetByteSize())})
          .first;

  switch (exe_class) {
  case llvm::ELF::ELFCLASS32:
    return HostInfo::GetArchitecture(HostInfo::eArchKind32);
  case llvm::ELF::ELFCLASS64:
    return HostInfo::GetArchitecture(HostInfo::eArchKind64);
  default:
    LLDB_LOG(log, "Unknown elf class ({0}) in file {1}", exe_class, exe_path);
    return ArchSpec();
  }
}

static bool GetProcessAndStatInfo(::pid_t pid,
                                  ProcessInstanceInfo &process_info,
                                  ProcessState &State, ::pid_t &tracerpid) {
  tracerpid = 0;
  process_info.Clear();

  Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_PROCESS));

  // We can't use getProcFile here because proc/[pid]/exe is a symbolic link.
  llvm::SmallString<64> ProcExe;
  (llvm::Twine("/proc/") + llvm::Twine(pid) + "/exe").toVector(ProcExe);
  std::string ExePath(PATH_MAX, '\0');

  ssize_t len = readlink(ProcExe.c_str(), &ExePath[0], PATH_MAX);
  if (len <= 0) {
    LLDB_LOG(log, "failed to read link exe link for {0}: {1}", pid,
             Status(errno, eErrorTypePOSIX));
    return false;
  }
  ExePath.resize(len);

  // If the binary has been deleted, the link name has " (deleted)" appended.
  // Remove if there.
  llvm::StringRef PathRef = ExePath;
  PathRef.consume_back(" (deleted)");

  process_info.SetArchitecture(GetELFProcessCPUType(PathRef));

  // Get the process environment.
  auto BufferOrError = getProcFile(pid, "environ");
  if (!BufferOrError)
    return false;
  std::unique_ptr<llvm::MemoryBuffer> Environ = std::move(*BufferOrError);

  // Get the command line used to start the process.
  BufferOrError = getProcFile(pid, "cmdline");
  if (!BufferOrError)
    return false;
  std::unique_ptr<llvm::MemoryBuffer> Cmdline = std::move(*BufferOrError);

  // Get User and Group IDs and get tracer pid.
  if (!GetStatusInfo(pid, process_info, State, tracerpid))
    return false;

  process_info.SetProcessID(pid);
  process_info.GetExecutableFile().SetFile(PathRef, FileSpec::Style::native);

  llvm::StringRef Rest = Environ->getBuffer();
  while (!Rest.empty()) {
    llvm::StringRef Var;
    std::tie(Var, Rest) = Rest.split('\0');
    process_info.GetEnvironment().insert(Var);
  }

  llvm::StringRef Arg0;
  std::tie(Arg0, Rest) = Cmdline->getBuffer().split('\0');
  process_info.SetArg0(Arg0);
  while (!Rest.empty()) {
    llvm::StringRef Arg;
    std::tie(Arg, Rest) = Rest.split('\0');
    process_info.GetArguments().AppendArgument(Arg);
  }

  return true;
}

uint32_t Host::FindProcesses(const ProcessInstanceInfoMatch &match_info,
                             ProcessInstanceInfoList &process_infos) {
  static const char procdir[] = "/proc/";

  DIR *dirproc = opendir(procdir);
  if (dirproc) {
    struct dirent *direntry = nullptr;
    const uid_t our_uid = getuid();
    const lldb::pid_t our_pid = getpid();
    bool all_users = match_info.GetMatchAllUsers();

    while ((direntry = readdir(dirproc)) != nullptr) {
      if (direntry->d_type != DT_DIR || !IsDirNumeric(direntry->d_name))
        continue;

      lldb::pid_t pid = atoi(direntry->d_name);

      // Skip this process.
      if (pid == our_pid)
        continue;

      ::pid_t tracerpid;
      ProcessState State;
      ProcessInstanceInfo process_info;

      if (!GetProcessAndStatInfo(pid, process_info, State, tracerpid))
        continue;

      // Skip if process is being debugged.
      if (tracerpid != 0)
        continue;

      if (State == ProcessState::Zombie)
        continue;

      // Check for user match if we're not matching all users and not running
      // as root.
      if (!all_users && (our_uid != 0) && (process_info.GetUserID() != our_uid))
        continue;

      if (match_info.Matches(process_info)) {
        process_infos.Append(process_info);
      }
    }

    closedir(dirproc);
  }

  return process_infos.GetSize();
}

bool Host::FindProcessThreads(const lldb::pid_t pid, TidMap &tids_to_attach) {
  bool tids_changed = false;
  static const char procdir[] = "/proc/";
  static const char taskdir[] = "/task/";
  std::string process_task_dir = procdir + llvm::to_string(pid) + taskdir;
  DIR *dirproc = opendir(process_task_dir.c_str());

  if (dirproc) {
    struct dirent *direntry = nullptr;
    while ((direntry = readdir(dirproc)) != nullptr) {
      if (direntry->d_type != DT_DIR || !IsDirNumeric(direntry->d_name))
        continue;

      lldb::tid_t tid = atoi(direntry->d_name);
      TidMap::iterator it = tids_to_attach.find(tid);
      if (it == tids_to_attach.end()) {
        tids_to_attach.insert(TidPair(tid, false));
        tids_changed = true;
      }
    }
    closedir(dirproc);
  }

  return tids_changed;
}

bool Host::GetProcessInfo(lldb::pid_t pid, ProcessInstanceInfo &process_info) {
  ::pid_t tracerpid;
  ProcessState State;
  return GetProcessAndStatInfo(pid, process_info, State, tracerpid);
}

Environment Host::GetEnvironment() { return Environment(environ); }

Status Host::ShellExpandArguments(ProcessLaunchInfo &launch_info) {
  return Status("unimplemented");
}
<|endoftext|>


<commit_before>#ifndef LUNAR_BYTESTREAM_HPP
#define LUNAR_BYTESTREAM_HPP

#include "lunar_common.hpp"

#include <deque>

namespace lunar {

template <typename T>
class bytestream {
    typedef std::basic_string<T> string_t;

public:
    bytestream() : m_is_eof(false) { }

    ~bytestream()
    {
        for (auto &data: m_deque) {
            data.remove();
        }

        m_del_func = [](string_t *ptr) { delete ptr; };
    }

    void set_del_func(std::function<void(string_t*)> func) { m_del_func = func; }

    STRM_RESULT front(T &c)
    {
        assert(m_tmp_pos.x <= m_deque.size());
        if (m_tmp_pos.x >= m_deque.size() ||
            m_deque[m_tmp_pos.x].front(c, m_tmp_pos.y) == STRM_NO_MORE_DATA) {
            return m_is_eof ? STRM_CLOSED : STRM_NO_MORE_DATA;
        } else {
            return STRM_SUCCESS;
        }
    }

    const point2u64 & get_tmp_pos() const { return m_tmp_pos; }

    void move_tmp_pos(uint64_t num)
    {
        assert(num > 0);
        assert((size_t)m_tmp_pos.x < m_deque.size());

        while ((size_t)m_tmp_pos.x < m_deque.size()) {
            auto size = m_deque[m_tmp_pos.x].size() - m_tmp_pos.y;
            if (size > num) {
                m_tmp_pos.y += num;
                break;
            } else {
                m_tmp_pos.x++;
                m_tmp_pos.y = 0;

                num -= size;
                if (num == 0) {
                    break;
                }
            }
        }
    }

    void restore_tmp_pos(const point2u64 &pos)
    {
        m_tmp_pos = pos;
    }

    void consume(uint64_t num)
    {
        while (! m_deque.empty() && num > 0) {
            data_t   &data = m_deque.front();
            uint64_t  len  = data.size();

            if (num >= len) {
                data.remove();
                m_deque.pop_front();
                num -= len;
            } else {
                data.consume(num);
                break;
            }
        }
    }

    void push_back(string_t *data)
    {
        m_deque.push_back(data_t(*this, data));
    }

    void push_eof() { m_is_eof = true; }

private:
    class data_t {
    public:
        data_t(bytestream &bs, string_t *data) : m_bs(bs), m_data(data), m_pos(0) { }
        ~data_t() { }

        STRM_RESULT front(T &c, size_t offset)
        {
            auto pos = m_pos + offset;
            if (pos >= m_data->size()) {
                return STRM_NO_MORE_DATA;
            } else {
                c = (*m_data)[pos];
                return STRM_SUCCESS;
            }
        }

        size_t size()
        {
            return m_data->size() - m_pos;
        }

        void consume(uint64_t num)
        {
            m_pos += num;
            assert(m_pos <= m_data->size());
        }

        void remove()
        {
            m_bs.m_del_func(m_data);
        }

    private:
        bytestream &m_bs;
        string_t *m_data;
        size_t    m_pos;
    };

    std::deque<data_t> m_deque;
    point2u64 m_tmp_pos;
    bool      m_is_eof;
    std::function<void(string_t*)> m_del_func;
};

};

#endif // LUNAR_BYTESTREAM_HPP<commit_msg>fix bug<commit_after>#ifndef LUNAR_BYTESTREAM_HPP
#define LUNAR_BYTESTREAM_HPP

#include "lunar_common.hpp"

#include <deque>

namespace lunar {

template <typename T>
class bytestream {
    typedef std::basic_string<T> string_t;

public:
    bytestream() : m_is_eof(false), m_del_func([](string_t *ptr) { delete ptr; }) { }

    ~bytestream()
    {
        for (auto &data: m_deque) {
            data.remove();
        }
    }

    void set_del_func(std::function<void(string_t*)> func) { m_del_func = func; }

    STRM_RESULT front(T &c)
    {
        assert(m_tmp_pos.x <= m_deque.size());
        if (m_tmp_pos.x >= m_deque.size() ||
            m_deque[m_tmp_pos.x].front(c, m_tmp_pos.y) == STRM_NO_MORE_DATA) {
            return m_is_eof ? STRM_CLOSED : STRM_NO_MORE_DATA;
        } else {
            return STRM_SUCCESS;
        }
    }

    const point2u64 & get_tmp_pos() const { return m_tmp_pos; }

    void move_tmp_pos(uint64_t num)
    {
        assert(num > 0);
        assert((size_t)m_tmp_pos.x < m_deque.size());

        while ((size_t)m_tmp_pos.x < m_deque.size()) {
            auto size = m_deque[m_tmp_pos.x].size() - m_tmp_pos.y;
            if (size > num) {
                m_tmp_pos.y += num;
                break;
            } else {
                m_tmp_pos.x++;
                m_tmp_pos.y = 0;

                num -= size;
                if (num == 0) {
                    break;
                }
            }
        }
    }

    void restore_tmp_pos(const point2u64 &pos)
    {
        m_tmp_pos = pos;
    }

    void consume(uint64_t num)
    {
        while (! m_deque.empty() && num > 0) {
            data_t   &data = m_deque.front();
            uint64_t  len  = data.size();

            if (num >= len) {
                data.remove();
                m_deque.pop_front();
                num -= len;
            } else {
                data.consume(num);
                break;
            }
        }
    }

    void push_back(string_t *data)
    {
        m_deque.push_back(data_t(*this, data));
    }

    void push_eof() { m_is_eof = true; }

private:
    class data_t {
    public:
        data_t(bytestream &bs, string_t *data) : m_bs(bs), m_data(data), m_pos(0) { }
        ~data_t() { }

        STRM_RESULT front(T &c, size_t offset)
        {
            auto pos = m_pos + offset;
            if (pos >= m_data->size()) {
                return STRM_NO_MORE_DATA;
            } else {
                c = (*m_data)[pos];
                return STRM_SUCCESS;
            }
        }

        size_t size()
        {
            return m_data->size() - m_pos;
        }

        void consume(uint64_t num)
        {
            m_pos += num;
            assert(m_pos <= m_data->size());
        }

        void remove()
        {
            m_bs.m_del_func(m_data);
        }

    private:
        bytestream &m_bs;
        string_t *m_data;
        size_t    m_pos;
    };

    std::deque<data_t> m_deque;
    point2u64 m_tmp_pos;
    bool      m_is_eof;
    std::function<void(string_t*)> m_del_func;
};

};

#endif // LUNAR_BYTESTREAM_HPP<|endoftext|>


<commit_before>/*
 *  Copyright 2012 Anders E. Wallin (anders.e.e.wallin "at" gmail.com)
 *
 *  This file is part of OpenVoronoi.
 *
 *  OpenVoronoi is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  OpenVoronoi is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with OpenVoronoi.  If not, see <http://www.gnu.org/licenses/>.
*/

#pragma once

#include <vector>

namespace kdtree {

/// a node in the KD-tree
template<class point_type>
struct kd_node {
    /// create node
    /// \param p position of node
    /// \param d direction of cut/split at this node
    /// \param l left child kd_node
    /// \param r right child kd_node
    kd_node( point_type p, int d, kd_node* l, kd_node* r) :
        pos(p), dir(d), left(l), right(r) {}
    virtual ~kd_node() {
        if (left)
            delete left;
        if (right)
            delete right;
    }
    point_type pos; ///< position of the node
    int dir; ///< direction of cut at this node
    kd_node *left;     ///< pointer to left child node
    kd_node *right;    ///< pointer to right child node
};

/// hyper rectangle
template<class point_type>
struct  kd_hyperrect {
    /// ctor
    kd_hyperrect(int dimi, const point_type mini, const point_type maxi) :
        dim(dimi) {
        min = mini;
        max = maxi;
    }
    /// extend hyperrectangle to include the given point
    void extend(const point_type& pos ) {
        for (int i=0; i < dim; i++) {
            if (pos[i] < min[i]) {
                min[i] = pos[i];
            }
            if (pos[i] > max[i]) {
                max[i] = pos[i];
            }
        }
    }

    int dim; ///< number of dimensions
    point_type min; ///< minimum point (e.g. lower left corner)
    point_type max; ///< maximum point (e.g. upper right corner)
};

/// \brief KD-tree for nearest neigbor search
template<class point_type>
class KDTree {
public:
    /// ctor
    KDTree(int dim = 3) : dim_(dim), root_(0), rect_(0) {
    }
    virtual ~KDTree() {
        if (rect_)
            delete rect_;
        if (root_)
            delete root_;
    }
    /// insert given point into tree
    int insert( const point_type pos) {
        return insert(root_, pos);
    }
    /// return a point in the tree that is nearest to the given point
    /// false is returned if the tree is empty.
    std::pair<point_type,bool> nearest( const point_type& pos) {
        num_nearest_i_calls=0;
        kd_hyperrect<point_type> rect = *rect_;
        kd_node<point_type>* result;
        if (!root_) return std::make_pair(pos,false);
        /* Our first guesstimate is the root node */
        result = root_;
        /* Search for the nearest neighbour recursively */
        double result_dist = root_->pos.dist(pos);
        kd_nearest_i( root_, pos, result, result_dist , rect);
        return std::make_pair( result->pos, true);
    }
    /// for debug, return the number of function calls made during a search
    int get_num_calls() {return num_nearest_i_calls;}
    /// print output of tree
    void print_tree() {
        if (root_)
            print_node(root_,0);
    }
private:
    /// insert given point into tree
    int insert(kd_node<point_type>* node, const point_type pos ) {
        if ( insert_rec( node, pos,  0) ) {
            return -1; // error (?)
        }

        if ( rect_ == 0 )
            rect_ = new kd_hyperrect<point_type>(dim_,pos,pos);
        else
            rect_->extend( pos );

        return 0;
    }

    /// recursive point-insertion function
    int insert_rec( kd_node<point_type>*& node, const point_type pos, int dir) {
        if (node == 0) {
            node = new kd_node<point_type>(pos,dir,0,0);
            if (root_==0) {
                root_=node;
            }
            return 0;
        } else {

            // else an existing node
            //node = *nptr;
            int new_dir = (node->dir + 1) % dim_;
            if( pos[node->dir] < node->pos[ node->dir] )  {
                //std::cout << " left "; print_node(node,0);
                return insert_rec( node->left, pos,  new_dir  );
            } else {
                //std::cout << " right "; print_node(node,0);
                return insert_rec( node->right, pos, new_dir );
            }
        }
    }
    /// square
    double sq(double x) {return x*x;}

    /// find nearest point
    void kd_nearest_i(kd_node<point_type> *node, const point_type pos,
                       kd_node<point_type>*& result, double& result_dist_sq , kd_hyperrect<point_type>& rect) {
        int dir = node->dir;
        num_nearest_i_calls++;
        //int i;
        //double dummy;
        kd_node<point_type> *nearer_subtree, *farther_subtree;
        double nearer_hyperrect_coord, farther_hyperrect_coord;

        /* Decide whether to go left or right in the tree */
        //dummy = pos[dir] - node->pos[dir];
        //if (dummy <= 0) {
            bool b;
        if (pos[dir] <= node->pos[dir]) {
            nearer_subtree = node->left;
            farther_subtree = node->right;
            nearer_hyperrect_coord  = rect.max[dir];
            farther_hyperrect_coord = rect.min[dir];
            b= true;
        } else {
            nearer_subtree = node->right;
            farther_subtree = node->left;
            nearer_hyperrect_coord  = rect.min[dir];
            farther_hyperrect_coord = rect.max[dir];
            b=false;
        }

        if (nearer_subtree) {
            //std::cout << " recurse into nearer subtree \n";
            /* Slice the hyperrect to get the hyperrect of the nearer subtree */
            double dummy = nearer_hyperrect_coord;
            //nearer_hyperrect_coord = node->pos[dir];
            if (b)
                rect.max[dir] = node->pos[dir];
            else
                rect.min[dir] = node->pos[dir];
            /* Recurse down into nearer subtree */
            kd_nearest_i(nearer_subtree, pos, result, result_dist_sq, rect);
            /* Undo the slice */
            if (b)
                rect.max[dir] = dummy; //node->pos[dir];
            else
                rect.min[dir] = dummy; //node->pos[dir];
            //rect->min[dir] = //nearer_hyperrect_coord = dummy;
        }

        /* Check the distance of the point at the current node, compare it
         * with our best so far */
        double dist_sq = node->pos.dist( pos );
        //for(int i=0; i < dim_; i++) {
        //    dist_sq += sq(node->pos[i] - pos[i]);
        //}
        if (dist_sq < result_dist_sq) {
            result = node;
            result_dist_sq = dist_sq;
        }

        if (farther_subtree) {
            //std::cout << " recurse into farther subtree \n";
            /* Get the hyperrect of the farther subtree */
            double dummy = farther_hyperrect_coord;
            if (b)
                rect.min[dir] = node->pos[dir];
            else
                rect.max[dir] = node->pos[dir];
            //farther_hyperrect_coord = node->pos[dir]; // this changes rect_ !!
            /* Check if we have to recurse down by calculating the closest
             * point of the hyperrect and see if it's closer than our
             * minimum distance in result_dist_sq. */
            if (hyperrect_dist_sq(rect, pos) < result_dist_sq)
            {
                /* Recurse down into farther subtree */
                kd_nearest_i(farther_subtree, pos, result, result_dist_sq, rect);
                      //double dist_sq = node->pos.dist( pos );
            //for(int i=0; i < dim_; i++) {
            //    dist_sq += sq(node->pos[i] - pos[i]);
            //}
            /*
            if (dist_sq < result_dist_sq) {
                result = node;
                result_dist_sq = dist_sq;
            }*/
            }
            /* Undo the slice on the hyperrect */
            if (b)
                rect.min[dir] = dummy;
            else
                rect.max[dir] = dummy;

            //*farther_hyperrect_coord = dummy;
        }
    }
    /// return distance squared from hyperrect to given point
    double hyperrect_dist_sq(kd_hyperrect<point_type>& rect, const point_type& pos){
        double result = 0;
        for (int i=0; i < dim_; i++) {
            if (pos[i] < rect.min[i]) {
                result += sq(rect.min[i] - pos[i]);
            } else if (pos[i] > rect.max[i]) {
                result += sq(rect.max[i] - pos[i]);
            }
        }
        return result;
    }

    /// text output
    void print_node(kd_node<point_type>* n, int d) {
        for(int i=0;i<d;++i)
            std::cout << " ";
        std::cout << "d=" << n->dir << " node at ";
        for (int i=0;i<dim_;++i)
            std::cout << n->pos[i] << " "; // << n->pos[1] << "  " << " " << n->pos[2] << "\n";
        std::cout << "\n";
        if (n->left)
            print_node(n->left,d+1);
        if (n->right)
            print_node(n->right,d+1);
    }

    int num_nearest_i_calls; ///< for debug, keep track of function calls
    int dim_; ///< number of dimensions
    kd_node<point_type>* root_; ///< root of the tree
    kd_hyperrect<point_type>* rect_; ///< hyperrectangle
};

} // kdtree namespace
<commit_msg>kdtree: Don't try to dereference "rect_" if not initialized (i.e. root_ == NULL).<commit_after>/*
 *  Copyright 2012 Anders E. Wallin (anders.e.e.wallin "at" gmail.com)
 *
 *  This file is part of OpenVoronoi.
 *
 *  OpenVoronoi is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  OpenVoronoi is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with OpenVoronoi.  If not, see <http://www.gnu.org/licenses/>.
*/

#pragma once

#include <vector>

namespace kdtree {

/// a node in the KD-tree
template<class point_type>
struct kd_node {
    /// create node
    /// \param p position of node
    /// \param d direction of cut/split at this node
    /// \param l left child kd_node
    /// \param r right child kd_node
    kd_node( point_type p, int d, kd_node* l, kd_node* r) :
        pos(p), dir(d), left(l), right(r) {}
    virtual ~kd_node() {
        if (left)
            delete left;
        if (right)
            delete right;
    }
    point_type pos; ///< position of the node
    int dir; ///< direction of cut at this node
    kd_node *left;     ///< pointer to left child node
    kd_node *right;    ///< pointer to right child node
};

/// hyper rectangle
template<class point_type>
struct  kd_hyperrect {
    /// ctor
    kd_hyperrect(int dimi, const point_type mini, const point_type maxi) :
        dim(dimi) {
        min = mini;
        max = maxi;
    }
    /// extend hyperrectangle to include the given point
    void extend(const point_type& pos ) {
        for (int i=0; i < dim; i++) {
            if (pos[i] < min[i]) {
                min[i] = pos[i];
            }
            if (pos[i] > max[i]) {
                max[i] = pos[i];
            }
        }
    }

    int dim; ///< number of dimensions
    point_type min; ///< minimum point (e.g. lower left corner)
    point_type max; ///< maximum point (e.g. upper right corner)
};

/// \brief KD-tree for nearest neigbor search
template<class point_type>
class KDTree {
public:
    /// ctor
    KDTree(int dim = 3) : dim_(dim), root_(0), rect_(0) {
    }
    virtual ~KDTree() {
        if (rect_)
            delete rect_;
        if (root_)
            delete root_;
    }
    /// insert given point into tree
    int insert( const point_type pos) {
        return insert(root_, pos);
    }
    /// return a point in the tree that is nearest to the given point
    /// false is returned if the tree is empty.
    std::pair<point_type,bool> nearest( const point_type& pos) {
        if (!root_) return std::make_pair(pos,false);
        num_nearest_i_calls=0;
        kd_hyperrect<point_type> rect = *rect_;
        kd_node<point_type>* result;
        /* Our first guesstimate is the root node */
        result = root_;
        /* Search for the nearest neighbour recursively */
        double result_dist = root_->pos.dist(pos);
        kd_nearest_i( root_, pos, result, result_dist , rect);
        return std::make_pair( result->pos, true);
    }
    /// for debug, return the number of function calls made during a search
    int get_num_calls() {return num_nearest_i_calls;}
    /// print output of tree
    void print_tree() {
        if (root_)
            print_node(root_,0);
    }
private:
    /// insert given point into tree
    int insert(kd_node<point_type>* node, const point_type pos ) {
        if ( insert_rec( node, pos,  0) ) {
            return -1; // error (?)
        }

        if ( rect_ == 0 )
            rect_ = new kd_hyperrect<point_type>(dim_,pos,pos);
        else
            rect_->extend( pos );

        return 0;
    }

    /// recursive point-insertion function
    int insert_rec( kd_node<point_type>*& node, const point_type pos, int dir) {
        if (node == 0) {
            node = new kd_node<point_type>(pos,dir,0,0);
            if (root_==0) {
                root_=node;
            }
            return 0;
        } else {

            // else an existing node
            //node = *nptr;
            int new_dir = (node->dir + 1) % dim_;
            if( pos[node->dir] < node->pos[ node->dir] )  {
                //std::cout << " left "; print_node(node,0);
                return insert_rec( node->left, pos,  new_dir  );
            } else {
                //std::cout << " right "; print_node(node,0);
                return insert_rec( node->right, pos, new_dir );
            }
        }
    }
    /// square
    double sq(double x) {return x*x;}

    /// find nearest point
    void kd_nearest_i(kd_node<point_type> *node, const point_type pos,
                       kd_node<point_type>*& result, double& result_dist_sq , kd_hyperrect<point_type>& rect) {
        int dir = node->dir;
        num_nearest_i_calls++;
        //int i;
        //double dummy;
        kd_node<point_type> *nearer_subtree, *farther_subtree;
        double nearer_hyperrect_coord, farther_hyperrect_coord;

        /* Decide whether to go left or right in the tree */
        //dummy = pos[dir] - node->pos[dir];
        //if (dummy <= 0) {
            bool b;
        if (pos[dir] <= node->pos[dir]) {
            nearer_subtree = node->left;
            farther_subtree = node->right;
            nearer_hyperrect_coord  = rect.max[dir];
            farther_hyperrect_coord = rect.min[dir];
            b= true;
        } else {
            nearer_subtree = node->right;
            farther_subtree = node->left;
            nearer_hyperrect_coord  = rect.min[dir];
            farther_hyperrect_coord = rect.max[dir];
            b=false;
        }

        if (nearer_subtree) {
            //std::cout << " recurse into nearer subtree \n";
            /* Slice the hyperrect to get the hyperrect of the nearer subtree */
            double dummy = nearer_hyperrect_coord;
            //nearer_hyperrect_coord = node->pos[dir];
            if (b)
                rect.max[dir] = node->pos[dir];
            else
                rect.min[dir] = node->pos[dir];
            /* Recurse down into nearer subtree */
            kd_nearest_i(nearer_subtree, pos, result, result_dist_sq, rect);
            /* Undo the slice */
            if (b)
                rect.max[dir] = dummy; //node->pos[dir];
            else
                rect.min[dir] = dummy; //node->pos[dir];
            //rect->min[dir] = //nearer_hyperrect_coord = dummy;
        }

        /* Check the distance of the point at the current node, compare it
         * with our best so far */
        double dist_sq = node->pos.dist( pos );
        //for(int i=0; i < dim_; i++) {
        //    dist_sq += sq(node->pos[i] - pos[i]);
        //}
        if (dist_sq < result_dist_sq) {
            result = node;
            result_dist_sq = dist_sq;
        }

        if (farther_subtree) {
            //std::cout << " recurse into farther subtree \n";
            /* Get the hyperrect of the farther subtree */
            double dummy = farther_hyperrect_coord;
            if (b)
                rect.min[dir] = node->pos[dir];
            else
                rect.max[dir] = node->pos[dir];
            //farther_hyperrect_coord = node->pos[dir]; // this changes rect_ !!
            /* Check if we have to recurse down by calculating the closest
             * point of the hyperrect and see if it's closer than our
             * minimum distance in result_dist_sq. */
            if (hyperrect_dist_sq(rect, pos) < result_dist_sq)
            {
                /* Recurse down into farther subtree */
                kd_nearest_i(farther_subtree, pos, result, result_dist_sq, rect);
                      //double dist_sq = node->pos.dist( pos );
            //for(int i=0; i < dim_; i++) {
            //    dist_sq += sq(node->pos[i] - pos[i]);
            //}
            /*
            if (dist_sq < result_dist_sq) {
                result = node;
                result_dist_sq = dist_sq;
            }*/
            }
            /* Undo the slice on the hyperrect */
            if (b)
                rect.min[dir] = dummy;
            else
                rect.max[dir] = dummy;

            //*farther_hyperrect_coord = dummy;
        }
    }
    /// return distance squared from hyperrect to given point
    double hyperrect_dist_sq(kd_hyperrect<point_type>& rect, const point_type& pos){
        double result = 0;
        for (int i=0; i < dim_; i++) {
            if (pos[i] < rect.min[i]) {
                result += sq(rect.min[i] - pos[i]);
            } else if (pos[i] > rect.max[i]) {
                result += sq(rect.max[i] - pos[i]);
            }
        }
        return result;
    }

    /// text output
    void print_node(kd_node<point_type>* n, int d) {
        for(int i=0;i<d;++i)
            std::cout << " ";
        std::cout << "d=" << n->dir << " node at ";
        for (int i=0;i<dim_;++i)
            std::cout << n->pos[i] << " "; // << n->pos[1] << "  " << " " << n->pos[2] << "\n";
        std::cout << "\n";
        if (n->left)
            print_node(n->left,d+1);
        if (n->right)
            print_node(n->right,d+1);
    }

    int num_nearest_i_calls; ///< for debug, keep track of function calls
    int dim_; ///< number of dimensions
    kd_node<point_type>* root_; ///< root of the tree
    kd_hyperrect<point_type>* rect_; ///< hyperrectangle
};

} // kdtree namespace
<|endoftext|>


<commit_before>// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/basictypes.h"
#include "base/gfx/png_encoder.h"
#include "base/logging.h"
#include "third_party/skia/include/core/SkBitmap.h"

extern "C" {
#include "third_party/libpng/png.h"
}

namespace {

// Converts BGRA->RGBA and RGBA->BGRA.
void ConvertBetweenBGRAandRGBA(const unsigned char* input, int pixel_width,
                               unsigned char* output) {
  for (int x = 0; x < pixel_width; x++) {
    const unsigned char* pixel_in = &input[x * 4];
    unsigned char* pixel_out = &output[x * 4];
    pixel_out[0] = pixel_in[2];
    pixel_out[1] = pixel_in[1];
    pixel_out[2] = pixel_in[0];
    pixel_out[3] = pixel_in[3];
  }
}

void ConvertRGBAtoRGB(const unsigned char* rgba, int pixel_width,
                      unsigned char* rgb) {
  for (int x = 0; x < pixel_width; x++) {
    const unsigned char* pixel_in = &rgba[x * 4];
    unsigned char* pixel_out = &rgb[x * 3];
    pixel_out[0] = pixel_in[0];
    pixel_out[1] = pixel_in[1];
    pixel_out[2] = pixel_in[2];
  }
}

}  // namespace

// Encoder --------------------------------------------------------------------
//
// This section of the code is based on nsPNGEncoder.cpp in Mozilla
// (Copyright 2005 Google Inc.)

namespace {

// Passed around as the io_ptr in the png structs so our callbacks know where
// to write data.
struct PngEncoderState {
  PngEncoderState(std::vector<unsigned char>* o) : out(o) {}
  std::vector<unsigned char>* out;
};

// Called by libpng to flush its internal buffer to ours.
void EncoderWriteCallback(png_structp png, png_bytep data, png_size_t size) {
  PngEncoderState* state = static_cast<PngEncoderState*>(png_get_io_ptr(png));
  DCHECK(state->out);

  size_t old_size = state->out->size();
  state->out->resize(old_size + size);
  memcpy(&(*state->out)[old_size], data, size);
}

void ConvertBGRAtoRGB(const unsigned char* bgra, int pixel_width,
                      unsigned char* rgb) {
  for (int x = 0; x < pixel_width; x++) {
    const unsigned char* pixel_in = &bgra[x * 4];
    unsigned char* pixel_out = &rgb[x * 3];
    pixel_out[0] = pixel_in[2];
    pixel_out[1] = pixel_in[1];
    pixel_out[2] = pixel_in[0];
  }
}

// Automatically destroys the given write structs on destruction to make
// cleanup and error handling code cleaner.
class PngWriteStructDestroyer {
 public:
  PngWriteStructDestroyer(png_struct** ps, png_info** pi) : ps_(ps), pi_(pi) {
  }
  ~PngWriteStructDestroyer() {
    png_destroy_write_struct(ps_, pi_);
  }
 private:
  png_struct** ps_;
  png_info** pi_;

  DISALLOW_EVIL_CONSTRUCTORS(PngWriteStructDestroyer);
};

}  // namespace

// static
bool PNGEncoder::Encode(const unsigned char* input, ColorFormat format,
                      int w, int h, int row_byte_width,
                      bool discard_transparency,
                      std::vector<unsigned char>* output) {
  // Run to convert an input row into the output row format, NULL means no
  // conversion is necessary.
  void (*converter)(const unsigned char* in, int w, unsigned char* out) = NULL;

  int input_color_components, output_color_components;
  int png_output_color_type;
  switch (format) {
    case FORMAT_RGB:
      input_color_components = 3;
      output_color_components = 3;
      png_output_color_type = PNG_COLOR_TYPE_RGB;
      discard_transparency = false;
      break;

    case FORMAT_RGBA:
      input_color_components = 4;
      if (discard_transparency) {
        output_color_components = 3;
        png_output_color_type = PNG_COLOR_TYPE_RGB;
        converter = ConvertRGBAtoRGB;
      } else {
        output_color_components = 4;
        png_output_color_type = PNG_COLOR_TYPE_RGB_ALPHA;
        converter = NULL;
      }
      break;

    case FORMAT_BGRA:
      input_color_components = 4;
      if (discard_transparency) {
        output_color_components = 3;
        png_output_color_type = PNG_COLOR_TYPE_RGB;
        converter = ConvertBGRAtoRGB;
      } else {
        output_color_components = 4;
        png_output_color_type = PNG_COLOR_TYPE_RGB_ALPHA;
        converter = ConvertBetweenBGRAandRGBA;
      }
      break;

    default:
      NOTREACHED() << "Unknown pixel format";
      return false;
  }

  // Row stride should be at least as long as the length of the data.
  DCHECK(input_color_components * w <= row_byte_width);

  png_struct* png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING,
                                                png_voidp_NULL,
                                                png_error_ptr_NULL,
                                                png_error_ptr_NULL);
  if (!png_ptr)
    return false;
  png_info* info_ptr = png_create_info_struct(png_ptr);
  if (!info_ptr) {
    png_destroy_write_struct(&png_ptr, NULL);
    return false;
  }
  PngWriteStructDestroyer destroyer(&png_ptr, &info_ptr);

  if (setjmp(png_jmpbuf(png_ptr))) {
    // The destroyer will ensure that the structures are cleaned up in this
    // case, even though we may get here as a jump from random parts of the
    // PNG library called below.
    return false;
  }

  // Set our callback for libpng to give us the data.
  PngEncoderState state(output);
  png_set_write_fn(png_ptr, &state, EncoderWriteCallback, NULL);

  png_set_IHDR(png_ptr, info_ptr, w, h, 8, png_output_color_type,
               PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT,
               PNG_FILTER_TYPE_DEFAULT);
  png_write_info(png_ptr, info_ptr);

  if (!converter) {
    // No conversion needed, give the data directly to libpng.
    for (int y = 0; y < h; y ++)
      png_write_row(png_ptr,
                    const_cast<unsigned char*>(&input[y * row_byte_width]));
  } else {
    // Needs conversion using a separate buffer.
    unsigned char* row = new unsigned char[w * output_color_components];
    for (int y = 0; y < h; y ++) {
      converter(&input[y * row_byte_width], w, row);
      png_write_row(png_ptr, row);
    }
    delete[] row;
  }

  png_write_end(png_ptr, info_ptr);
  return true;
}

// static
bool PNGEncoder::EncodeBGRASkBitmap(const SkBitmap& input,
                                    bool discard_transparency,
                                    std::vector<unsigned char>* output) {
  SkAutoLockPixels input_lock(input);
  DCHECK(input.empty() || input.bytesPerPixel() == 4);
  return Encode(static_cast<unsigned char*>(input.getPixels()),
                PNGEncoder::FORMAT_BGRA, input.width(), input.height(),
                input.rowBytes(), discard_transparency, output);
}
<commit_msg>PNGEncoder wasn't accounting for SkBitmap's premultiplied alpha (PNGDecoder was, however).<commit_after>// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/basictypes.h"
#include "base/gfx/png_encoder.h"
#include "base/logging.h"
#include "base/scoped_ptr.h"
#include "third_party/skia/include/core/SkBitmap.h"

extern "C" {
#include "third_party/libpng/png.h"
}

namespace {

// Converts BGRA->RGBA and RGBA->BGRA.
void ConvertBetweenBGRAandRGBA(const unsigned char* input, int pixel_width,
                               unsigned char* output) {
  for (int x = 0; x < pixel_width; x++) {
    const unsigned char* pixel_in = &input[x * 4];
    unsigned char* pixel_out = &output[x * 4];
    pixel_out[0] = pixel_in[2];
    pixel_out[1] = pixel_in[1];
    pixel_out[2] = pixel_in[0];
    pixel_out[3] = pixel_in[3];
  }
}

void ConvertRGBAtoRGB(const unsigned char* rgba, int pixel_width,
                      unsigned char* rgb) {
  for (int x = 0; x < pixel_width; x++) {
    const unsigned char* pixel_in = &rgba[x * 4];
    unsigned char* pixel_out = &rgb[x * 3];
    pixel_out[0] = pixel_in[0];
    pixel_out[1] = pixel_in[1];
    pixel_out[2] = pixel_in[2];
  }
}

}  // namespace

// Encoder --------------------------------------------------------------------
//
// This section of the code is based on nsPNGEncoder.cpp in Mozilla
// (Copyright 2005 Google Inc.)

namespace {

// Passed around as the io_ptr in the png structs so our callbacks know where
// to write data.
struct PngEncoderState {
  PngEncoderState(std::vector<unsigned char>* o) : out(o) {}
  std::vector<unsigned char>* out;
};

// Called by libpng to flush its internal buffer to ours.
void EncoderWriteCallback(png_structp png, png_bytep data, png_size_t size) {
  PngEncoderState* state = static_cast<PngEncoderState*>(png_get_io_ptr(png));
  DCHECK(state->out);

  size_t old_size = state->out->size();
  state->out->resize(old_size + size);
  memcpy(&(*state->out)[old_size], data, size);
}

void ConvertBGRAtoRGB(const unsigned char* bgra, int pixel_width,
                      unsigned char* rgb) {
  for (int x = 0; x < pixel_width; x++) {
    const unsigned char* pixel_in = &bgra[x * 4];
    unsigned char* pixel_out = &rgb[x * 3];
    pixel_out[0] = pixel_in[2];
    pixel_out[1] = pixel_in[1];
    pixel_out[2] = pixel_in[0];
  }
}

// Automatically destroys the given write structs on destruction to make
// cleanup and error handling code cleaner.
class PngWriteStructDestroyer {
 public:
  PngWriteStructDestroyer(png_struct** ps, png_info** pi) : ps_(ps), pi_(pi) {
  }
  ~PngWriteStructDestroyer() {
    png_destroy_write_struct(ps_, pi_);
  }
 private:
  png_struct** ps_;
  png_info** pi_;

  DISALLOW_EVIL_CONSTRUCTORS(PngWriteStructDestroyer);
};

}  // namespace

// static
bool PNGEncoder::Encode(const unsigned char* input, ColorFormat format,
                      int w, int h, int row_byte_width,
                      bool discard_transparency,
                      std::vector<unsigned char>* output) {
  // Run to convert an input row into the output row format, NULL means no
  // conversion is necessary.
  void (*converter)(const unsigned char* in, int w, unsigned char* out) = NULL;

  int input_color_components, output_color_components;
  int png_output_color_type;
  switch (format) {
    case FORMAT_RGB:
      input_color_components = 3;
      output_color_components = 3;
      png_output_color_type = PNG_COLOR_TYPE_RGB;
      discard_transparency = false;
      break;

    case FORMAT_RGBA:
      input_color_components = 4;
      if (discard_transparency) {
        output_color_components = 3;
        png_output_color_type = PNG_COLOR_TYPE_RGB;
        converter = ConvertRGBAtoRGB;
      } else {
        output_color_components = 4;
        png_output_color_type = PNG_COLOR_TYPE_RGB_ALPHA;
        converter = NULL;
      }
      break;

    case FORMAT_BGRA:
      input_color_components = 4;
      if (discard_transparency) {
        output_color_components = 3;
        png_output_color_type = PNG_COLOR_TYPE_RGB;
        converter = ConvertBGRAtoRGB;
      } else {
        output_color_components = 4;
        png_output_color_type = PNG_COLOR_TYPE_RGB_ALPHA;
        converter = ConvertBetweenBGRAandRGBA;
      }
      break;

    default:
      NOTREACHED() << "Unknown pixel format";
      return false;
  }

  // Row stride should be at least as long as the length of the data.
  DCHECK(input_color_components * w <= row_byte_width);

  png_struct* png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING,
                                                png_voidp_NULL,
                                                png_error_ptr_NULL,
                                                png_error_ptr_NULL);
  if (!png_ptr)
    return false;
  png_info* info_ptr = png_create_info_struct(png_ptr);
  if (!info_ptr) {
    png_destroy_write_struct(&png_ptr, NULL);
    return false;
  }
  PngWriteStructDestroyer destroyer(&png_ptr, &info_ptr);

  if (setjmp(png_jmpbuf(png_ptr))) {
    // The destroyer will ensure that the structures are cleaned up in this
    // case, even though we may get here as a jump from random parts of the
    // PNG library called below.
    return false;
  }

  // Set our callback for libpng to give us the data.
  PngEncoderState state(output);
  png_set_write_fn(png_ptr, &state, EncoderWriteCallback, NULL);

  png_set_IHDR(png_ptr, info_ptr, w, h, 8, png_output_color_type,
               PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT,
               PNG_FILTER_TYPE_DEFAULT);
  png_write_info(png_ptr, info_ptr);

  if (!converter) {
    // No conversion needed, give the data directly to libpng.
    for (int y = 0; y < h; y ++)
      png_write_row(png_ptr,
                    const_cast<unsigned char*>(&input[y * row_byte_width]));
  } else {
    // Needs conversion using a separate buffer.
    unsigned char* row = new unsigned char[w * output_color_components];
    for (int y = 0; y < h; y ++) {
      converter(&input[y * row_byte_width], w, row);
      png_write_row(png_ptr, row);
    }
    delete[] row;
  }

  png_write_end(png_ptr, info_ptr);
  return true;
}

// static
bool PNGEncoder::EncodeBGRASkBitmap(const SkBitmap& input,
                                    bool discard_transparency,
                                    std::vector<unsigned char>* output) {
  // This only works with images with four bytes per pixel.
  static const int bbp = 4;

  DCHECK(input.empty() || input.bytesPerPixel() == bbp);

  // SkBitmaps are premultiplied, we need to unpremultiply them.
  scoped_ptr<unsigned char> divided;
  divided.reset(new unsigned char[input.width() * input.height() * bbp]);

  SkAutoLockPixels lock_input(input);
  int i = 0;
  for (int y = 0; y < input.height(); y++) {
    uint32* src_row = input.getAddr32(0, y);
    for (int x = 0; x < input.width(); x++) {
      int alpha = SkColorGetA(src_row[x]);
      if (alpha != 0 && alpha != 255) {
        divided.get()[i + 0] = (SkColorGetR(src_row[x]) << 8) / alpha;
        divided.get()[i + 1] = (SkColorGetG(src_row[x]) << 8) / alpha;
        divided.get()[i + 2] = (SkColorGetB(src_row[x]) << 8) / alpha;
        divided.get()[i + 3] = alpha;
      } else {
        divided.get()[i + 0] = SkColorGetR(src_row[x]);
        divided.get()[i + 1] = SkColorGetG(src_row[x]);
        divided.get()[i + 2] = SkColorGetB(src_row[x]);
        divided.get()[i + 3] = SkColorGetA(src_row[x]);
      }
      i += bbp;
    }
  }

  return Encode(divided.release(),
                PNGEncoder::FORMAT_RGBA, input.width(), input.height(),
                input.rowBytes(), discard_transparency, output);
}
<|endoftext|>


<commit_before>#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include "kernel.h"

#include <QDebug>

Kernel::Kernel(int argc, char** argv)
{
	map_was_loaded = false;
	/* default config */
	height = DEF_HEIGHT;
	width = DEF_WIDTH;
	fullscreen = false;
	mode = SINGLEPLAY;
	map_name = "default_map";
	load_config();
	/* parse command line arguments */
	static const char *optString = "m:h:w:f:c:s";
	int opt = 0;
	opt = getopt(argc, argv, optString);
	while(opt != -1)
	{
		switch(opt) {
			case 'm':
				map_name = (char*)malloc(sizeof(optarg));
				strcpy(map_name, optarg);
				break;
			case 'h':
				height = atof(optarg);
				break;
			case 'w':
				width = atof(optarg);
				break;
			case 'f':
				fullscreen = atoi(optarg);
				break;
			case 'c':
				if (mode == SERVER)
				{
					printf("Warning: options -c and -s should not be used at one time\n");
				}
				mode = CLIENT;
				server_address = (char*)malloc(sizeof(optarg));
				strcpy(server_address, optarg);
				break;
			case 's':
				if (mode == CLIENT)
				{
					printf("Warning: options -c and -s should not be used at one time\n");
				}
				mode = SERVER;
				break;
		}
		opt = getopt(argc, argv, optString);
	}
	save_config();
	printf("Resolution set to %fx%f\n", width, height);
	if (fullscreen)
	{
		printf("Mode fullscreen\n");
	}
	else
	{
		printf("Mode windowed\n");
	}
	switch (mode)
	{
		case SINGLEPLAY:
			printf("Mode singleplay\n");
			break;
		case CLIENT:
			printf("Mode client, server address is %s\n", server_address);
			break;
		case SERVER:
			printf("Mode server\n");
			break;
	}
    fpc_info.fpc = 0;
    fpc_info.fpc_max = 0;
    fpc_info.fpc_min = 0;
    fpc_info.fpc_min -=1;
}

void Kernel::load_config()
{
	/* open and read config file */
	char option[255];
	char value[255];
	FILE *config_file;
	config_file = fopen(CONFIG_PATH, "r");
	if (config_file != NULL)
	{
		while(fscanf(config_file, "%s %s", option, value) != EOF)
		{
			if (!strcmp(option, "height"))
			{
				height = atof(value);
			}
			if (!strcmp(option, "width"))
			{
				width = atof(value);
			}
			if (!strcmp(option, "fullscreen"))
			{
				fullscreen = atoi(value);
			}
		}
		fclose(config_file);
	}
	else
	{
		printf("Warning: no config file found\n");
	}
}

void Kernel::save_config()
{
	/* write config to config file */
	FILE *config_file;
	config_file = fopen(CONFIG_PATH, "w");
	if (config_file != NULL)
	{
		fprintf(config_file, "%s %f\n", "width", width);
		fprintf(config_file, "%s %f\n", "height", height);
		fprintf(config_file, "%s %i\n", "fullscreen", fullscreen);
		fclose(config_file);
		printf("Config saved\n");
	}
	else
	{
		printf("Warning: can not save config\n");
	}
}

/* was not tested yet */
void Kernel::do_command(char* input)
{
    printf("kernel \x1b[31mDEBUG\x1b[0m input comand '%s'\n", input);
	char command[255];
	sscanf(input, "%s", command);
	if (!strcmp(command, "connect"))
	{
		mode = CLIENT;
		sscanf(input, "%*s %s", server_address);
		/* ... */
	}
	if (!strcmp(command, "server"))
	{
		mode = SERVER;
		/* ... */
	}
	if (!strcmp(command, "fullscreen"))
	{
		fullscreen = false;
		save_config();
	}
	if (!strcmp(command, "windowed"))
	{
		fullscreen = true;
		save_config();
	}
    if (!strcmp(command, "fpc"))
    {
        print_fpc();
    }
}

void Kernel::load_map()
{
	if (map_was_loaded)
	{
		/* erase all models from vector */
	}
	else
	{
		models = new std::vector<SModel*>();
		map_was_loaded = true;
	}
	FILE *map_file;
	char map_path[255];
	map_path[0] = '\0';
	strcat(map_path, "res/maps/");
	strcat(map_path, map_name);
	strcat(map_path, ".map");
	printf("Loading map %s\n", map_path);
	map_file = fopen(map_path, "r");
	int id;
	Position* pos;
	SModel* model;
	if (map_file != NULL)
	{
		while(fscanf(map_file, "%i\n", &id) != EOF)
		{
			printf("Loading object %d\n", id);
			pos = new Position();
			model = (SModel*)malloc(sizeof(SModel));
			model->mesh_number = id;
			model->position = pos;
			model->position->_res_pos.angular_acceleration.v[2] = 0.01;
			double p0, p1, p2, v0, v1, v2, a0, a1, a2, ap0, ap1, ap2, av0, av1, av2, aa0, aa1, aa2;
			if (fscanf(map_file, "%lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf\n",
						&p0, &p1, &p2, &v0, &v1, &v2, &a0, &a1, &a2, &ap0, &ap1, &ap2, &av0, &av1, &av2, &aa0, &aa1, &aa2)
						== EOF)
			{
				printf("Unexpected end of map file %s\n", map_path);
			}
			else
			{
				model->position->_res_pos.position.init(p0, p1, p2);
				model->position->_res_pos.velocity.init(v0, v1, v2);
				model->position->_res_pos.acceleration.init(a0, a1, a2);
				model->position->_res_pos.angular_position.init(ap0, ap1, ap2);
				model->position->_res_pos.angular_velocity.init(av0, av1, av2);
				model->position->_res_pos.angular_acceleration.init(aa0, aa1, aa2);
				models->push_back(model);
				printf("Added object %d\n", id);
			}
		}
		fclose(map_file);
	}
	else
	{
		printf("Can not open map %s\n", map_path);
	}

}

void Kernel::print_fpc()
{
    qDebug() << "fpc now: " << fpc_info.fpc;
    qDebug() << "fpc max: " << fpc_info.fpc_max;
    qDebug() << "fpc min: " << fpc_info.fpc_min;
}

void Kernel::get_network(Network* _network)
{
	network = _network;
}
<commit_msg>erasing objects from models<commit_after>#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include "kernel.h"

#include <QDebug>

Kernel::Kernel(int argc, char** argv)
{
	map_was_loaded = false;
	/* default config */
	height = DEF_HEIGHT;
	width = DEF_WIDTH;
	fullscreen = false;
	mode = SINGLEPLAY;
	map_name = "default_map";
	load_config();
	models = new std::vector<SModel*>();
	/* parse command line arguments */
	static const char *optString = "m:h:w:f:c:s";
	int opt = 0;
	opt = getopt(argc, argv, optString);
	while(opt != -1)
	{
		switch(opt) {
			case 'm':
				map_name = (char*)malloc(sizeof(optarg));
				strcpy(map_name, optarg);
				break;
			case 'h':
				height = atof(optarg);
				break;
			case 'w':
				width = atof(optarg);
				break;
			case 'f':
				fullscreen = atoi(optarg);
				break;
			case 'c':
				if (mode == SERVER)
				{
					printf("Warning: options -c and -s should not be used at one time\n");
				}
				mode = CLIENT;
				server_address = (char*)malloc(sizeof(optarg));
				strcpy(server_address, optarg);
				break;
			case 's':
				if (mode == CLIENT)
				{
					printf("Warning: options -c and -s should not be used at one time\n");
				}
				mode = SERVER;
				break;
		}
		opt = getopt(argc, argv, optString);
	}
	save_config();
	printf("Resolution set to %fx%f\n", width, height);
	if (fullscreen)
	{
		printf("Mode fullscreen\n");
	}
	else
	{
		printf("Mode windowed\n");
	}
	switch (mode)
	{
		case SINGLEPLAY:
			printf("Mode singleplay\n");
			break;
		case CLIENT:
			printf("Mode client, server address is %s\n", server_address);
			break;
		case SERVER:
			printf("Mode server\n");
			break;
	}
    fpc_info.fpc = 0;
    fpc_info.fpc_max = 0;
    fpc_info.fpc_min = 0;
    fpc_info.fpc_min -=1;
}

void Kernel::load_config()
{
	/* open and read config file */
	char option[255];
	char value[255];
	FILE *config_file;
	config_file = fopen(CONFIG_PATH, "r");
	if (config_file != NULL)
	{
		while(fscanf(config_file, "%s %s", option, value) != EOF)
		{
			if (!strcmp(option, "height"))
			{
				height = atof(value);
			}
			if (!strcmp(option, "width"))
			{
				width = atof(value);
			}
			if (!strcmp(option, "fullscreen"))
			{
				fullscreen = atoi(value);
			}
		}
		fclose(config_file);
	}
	else
	{
		printf("Warning: no config file found\n");
	}
}

void Kernel::save_config()
{
	/* write config to config file */
	FILE *config_file;
	config_file = fopen(CONFIG_PATH, "w");
	if (config_file != NULL)
	{
		fprintf(config_file, "%s %f\n", "width", width);
		fprintf(config_file, "%s %f\n", "height", height);
		fprintf(config_file, "%s %i\n", "fullscreen", fullscreen);
		fclose(config_file);
		printf("Config saved\n");
	}
	else
	{
		printf("Warning: can not save config\n");
	}
}

/* was not tested yet */
void Kernel::do_command(char* input)
{
    printf("kernel \x1b[31mDEBUG\x1b[0m input comand '%s'\n", input);
	char command[255];
	sscanf(input, "%s", command);
	if (!strcmp(command, "connect"))
	{
		mode = CLIENT;
		sscanf(input, "%s %s", command, server_address);
		/* ... */
	}
	if (!strcmp(command, "server"))
	{
		mode = SERVER;
		/* ... */
	}
	if (!strcmp(command, "fullscreen"))
	{
		fullscreen = false;
		/* ... */
		save_config();
	}
	if (!strcmp(command, "windowed"))
	{
		fullscreen = true;
		/* ... */
		save_config();
	}
    if (!strcmp(command, "fpc"))
    {
        print_fpc();
    }
  if (!strcmp(command, "loadmap"))
  {
		sscanf(input, "%s %s", command, map_name);
		load_map();
	}
}

void Kernel::load_map()
{
	SModel* model;
	/* erase all models from vector */
	while(!models->empty())
	{
		model = models->back();
		delete model->position;
		free(model);
		models->pop_back();
	}
	FILE *map_file;
	char map_path[255];
	map_path[0] = '\0';
	strcat(map_path, "res/maps/");
	strcat(map_path, map_name);
	strcat(map_path, ".map");
	printf("Loading map %s\n", map_path);
	map_file = fopen(map_path, "r");
	int id;
	Position* pos;
	if (map_file != NULL)
	{
		while(fscanf(map_file, "%i\n", &id) != EOF)
		{
			printf("Loading object %d\n", id);
			pos = new Position();
			model = (SModel*)malloc(sizeof(SModel));
			model->mesh_number = id;
			model->position = pos;
			model->position->_res_pos.angular_acceleration.v[2] = 0.01;
			double p0, p1, p2, v0, v1, v2, a0, a1, a2, ap0, ap1, ap2, av0, av1, av2, aa0, aa1, aa2;
			if (fscanf(map_file, "%lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf\n",
						&p0, &p1, &p2, &v0, &v1, &v2, &a0, &a1, &a2, &ap0, &ap1, &ap2, &av0, &av1, &av2, &aa0, &aa1, &aa2)
						== EOF)
			{
				printf("Unexpected end of map file %s\n", map_path);
			}
			else
			{
				model->position->_res_pos.position.init(p0, p1, p2);
				model->position->_res_pos.velocity.init(v0, v1, v2);
				model->position->_res_pos.acceleration.init(a0, a1, a2);
				model->position->_res_pos.angular_position.init(ap0, ap1, ap2);
				model->position->_res_pos.angular_velocity.init(av0, av1, av2);
				model->position->_res_pos.angular_acceleration.init(aa0, aa1, aa2);
				models->push_back(model);
				printf("Added object %d\n", id);
			}
		}
		fclose(map_file);
	}
	else
	{
		printf("Can not open map %s\n", map_path);
	}

}

void Kernel::print_fpc()
{
    qDebug() << "fpc now: " << fpc_info.fpc;
    qDebug() << "fpc max: " << fpc_info.fpc_max;
    qDebug() << "fpc min: " << fpc_info.fpc_min;
}

void Kernel::get_network(Network* _network)
{
	network = _network;
}
<|endoftext|>