/************************************************************************** * Copyright(c) 1998-2008, ALICE Experiment at CERN, all rights reserved. * * See http://aliceinfo.cern.ch/Offline/AliRoot/License.html for * * full copyright notice. * **************************************************************************/ // Author: Mihai Niculescu 2013 /* * This script creates a collage containing all OpenGL views from a running AliEve * * Given Collage size (width, height), the size for all OpenGL * views are computed using the same aspect ratio (width/height) as the main 3D View */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include TString getEventInfo(); /***********Save all OpenGL views into one picture compositeImgFileName - save final image to this file showLiveBar - whether to show the LIVE bar, useful when not online (using offline) width - of the collage image height -of the collage image */ void saveViews(const char* compositeImgFileName="views.png", Bool_t showLiveBar=kTRUE, Int_t width = 1440, Int_t height= 900) { Info("saveViews.C", "saving views to [%s]", compositeImgFileName); Int_t heightInfoBar = 65; // hold height of the Information bar TASImage* compositeImg=0; // this holds the final image TASImage* tempImg=0; // temporary used for loading images TEveViewerList* viewers = gEve->GetViewers(); Int_t Nviewers = viewers->NumChildren()-2; // remark: 3D view is counted twice compositeImg = new TASImage(width, height); // 3D View size Int_t width3DView = TMath::FloorNint((float)Nviewers*width/(float)(Nviewers+1)); // the width of the 3D view Int_t height3DView= height-heightInfoBar; // the height of the 3D view Float_t aspectRatio = (float)width3DView/(float)height3DView; // 3D View aspect ratio // Children View Size Int_t heightChildView = TMath::FloorNint((float)height3DView/(float)Nviewers); Int_t widthChildView = TMath::FloorNint(aspectRatio*heightChildView); // has the same aspect ratio as the 3D view int index=0; // iteration counter int x = width3DView; // x position of the child view int y = 0;// y position of the child view TString viewFilename; // save view to this file for(TEveElement::List_i i = (++viewers->BeginChildren()); i != viewers->EndChildren(); i++) { // NB: this skips the first children (first 3D View) TEveViewer* view = ((TEveViewer*)*i); viewFilename = Form("view-%d.png", index); // Save OpenGL views in files if(index==0){ view->GetGLViewer()->SavePictureUsingBB(viewFilename);//, width3DView, height3DView); } else { view->GetGLViewer()->SavePictureUsingBB(viewFilename);//, widthChildView, heightChildView); } tempImg = new TASImage(viewFilename); // copy view image in the composite image if(index==0){ if(tempImg->GetWidth()>width3DView) { tempImg->Crop((tempImg->GetWidth()-width3DView)/2, 0,width3DView,height3DView); } if(tempImg->GetHeight()>height3DView) { tempImg->Crop(0,(tempImg->GetHeight()-height3DView)/2, width3DView,height3DView); } tempImg->CopyArea(compositeImg, 0,0, width3DView, height3DView); } else { tempImg->Crop((tempImg->GetWidth()-widthChildView)/2, (tempImg->GetHeight()-heightChildView)/2, widthChildView,heightChildView); tempImg->CopyArea(compositeImg, 0,0, widthChildView, heightChildView, x,y); // draw a border around child views compositeImg->DrawRectangle(x,y, widthChildView, heightChildView, "#C0C0C0"); } /* final touches inside loop */ delete tempImg; if(index>0) // skip 3D View y+=heightChildView; index++; } // Create a glow (bloom) effect tempImg = (TASImage*)compositeImg->Clone("tempImg"); tempImg->Blur(10.0,10.0); compositeImg->Merge(tempImg, "lighten"); delete tempImg; tempImg = 0; // show LIVE bar if(showLiveBar){ TTimeStamp ts; TString tNow = ts.AsString("s"); // display date & time compositeImg->Gradient( 90, "#EAEAEA #D2D2D2 #FFFFFF", 0, 75, 0, 239, 95); compositeImg->Gradient( 90, "#D6D6D6 #242424 #000000", 0, 155, 60, 152, 26); compositeImg->BeginPaint(); compositeImg->DrawRectangle(50,0, 264, 94); compositeImg->DrawText(162, 6, "LIVE", 70, "#FF2D00", "FreeSansBold.otf"); compositeImg->DrawText(162, 65, tNow, 16, "#FFFFFF", "arial.ttf"); compositeImg->EndPaint(); //include ALICE Logo tempImg = new TASImage( Form("%s/../src/picts/alice_logo_2009_blue_80x80.png", gSystem->Getenv("ALICE_ROOT")) ); tempImg->Scale(64,64); //tempImg->CopyArea(compositeImg, 0,0, 236, 319, 59, 4); compositeImg->Merge(tempImg, "alphablend", 82, 4); delete tempImg; tempImg = 0; } // show Information bar AliESDEvent* esd = AliEveEventManager::AssertESD(); ULong64_t triggerMask = esd->GetTriggerMask(); ULong64_t triggerMaskNext50 = esd->GetTriggerMaskNext50(); ULong64_t mask = 0b000001; TString triggerClasses1 = ""; TString triggerClasses2 = ""; TString triggerClasses3 = ""; int sw=0; for(int i=0;i<50;i++) { if(mask&triggerMask) { if(strcmp(esd->GetESDRun()->GetTriggerClass(i),"")){ if (sw==0) { triggerClasses1 += esd->GetESDRun()->GetTriggerClass(i); triggerClasses1 += " "; sw=1; } else if(sw==1) { triggerClasses2 += esd->GetESDRun()->GetTriggerClass(i); triggerClasses2 += " "; sw=2; } else if(sw==2) { triggerClasses3 += esd->GetESDRun()->GetTriggerClass(i); triggerClasses3 += " "; sw=0; } } } if(mask&triggerMaskNext50) { if(strcmp(esd->GetESDRun()->GetTriggerClass(i+50),"")) { if (sw==0) { triggerClasses1 += esd->GetESDRun()->GetTriggerClass(i+50); triggerClasses1 += " "; sw=1; } else if(sw==1) { triggerClasses2 += esd->GetESDRun()->GetTriggerClass(i+50); triggerClasses2 += " "; sw=2; } else if(sw==2) { triggerClasses3 += esd->GetESDRun()->GetTriggerClass(i+50); triggerClasses3 += " "; sw=0; } } } mask = mask<<1; } TString stringInfo; stringInfo = getEventInfo(); compositeImg->Gradient( 90, "#1B58BF #1D5CDF #0194FF", 0, 0, height-heightInfoBar, width, heightInfoBar); compositeImg->BeginPaint(); compositeImg->DrawText(10, height-heightInfoBar+15, stringInfo, 28, "#FFFFFF", "FreeSansBold.otf"); compositeImg->DrawText(750, height-heightInfoBar+4,triggerClasses1, 16, "#FFFFFF", "FreeSansBold.otf"); compositeImg->DrawText(750, height-heightInfoBar+24,triggerClasses2, 16, "#FFFFFF", "FreeSansBold.otf"); compositeImg->DrawText(750, height-heightInfoBar+44,triggerClasses3, 16, "#FFFFFF", "FreeSansBold.otf"); compositeImg->EndPaint(); // write composite image to disk compositeImg->CopyArea(compositeImg, 0,0, width, height); compositeImg->WriteImage(compositeImgFileName); delete compositeImg; return; } // This function retrieves a string containing some information regarding the current event TString getEventInfo() { // For general public please show as less or technical information as possible TString rawInfo, esdInfo; if (!AliEveEventManager::HasRawReader()) { rawInfo = ""; } else { AliRawReader* rawReader = AliEveEventManager::AssertRawReader(); if(!rawReader) return ""; rawInfo.Form("Run: %d Event#: %d (%s)", rawReader->GetRunNumber(), AliEveEventManager::CurrentEventId(), AliRawEventHeaderBase::GetTypeName(rawReader->GetType()) ); return rawInfo; } if (!AliEveEventManager::HasESD()) { esdInfo = ""; } else { AliESDEvent* esd = AliEveEventManager::AssertESD(); esdInfo.Form("Colliding: %s Run: %d Event: %d (%s)", esd->GetESDRun()->GetBeamType(), esd->GetRunNumber(), esd->GetEventNumberInFile(), AliRawEventHeaderBase::GetTypeName(esd->GetEventType()) ); } return esdInfo; }